summaryrefslogtreecommitdiff
path: root/compiler/coreSyn/CoreOpt.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/coreSyn/CoreOpt.hs')
-rw-r--r--compiler/coreSyn/CoreOpt.hs35
1 files changed, 8 insertions, 27 deletions
diff --git a/compiler/coreSyn/CoreOpt.hs b/compiler/coreSyn/CoreOpt.hs
index 80fb3a80cf..d0dba81e3e 100644
--- a/compiler/coreSyn/CoreOpt.hs
+++ b/compiler/coreSyn/CoreOpt.hs
@@ -42,7 +42,7 @@ import OptCoercion ( optCoercion )
import Type hiding ( substTy, extendTvSubst, extendCvSubst, extendTvSubstList
, isInScope, substTyVarBndr, cloneTyVarBndr )
import Coercion hiding ( substCo, substCoVarBndr )
-import TyCon ( tyConArity, isNewTyCon )
+import TyCon ( tyConArity )
import TysWiredIn
import PrelNames
import BasicTypes
@@ -793,7 +793,7 @@ Here's how exprIsConApp_maybe achieves this:
scrutinee = (\n. case n of n' -> MkT n') e
2. Beta-reduce the application, generating a floated 'let'.
- See Note [Special case for newtype wrappers] below. Now we have
+ See Note [beta-reduction in exprIsConApp_maybe] below. Now we have
scrutinee = case n of n' -> MkT n'
with floats {Let n = e}
@@ -806,8 +806,8 @@ And now we have a known-constructor MkT that we can return.
Notice that both (2) and (3) require exprIsConApp_maybe to gather and return
a bunch of floats, both let and case bindings.
-Note [Special case for newtype wrappers]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [beta-reduction in exprIsConApp_maybe]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The unfolding a definition (_e.g._ a let-bound variable or a datacon wrapper) is
typically a function. For instance, take the wrapper for MkT in Note
[exprIsConApp_maybe on data constructors with wrappers]:
@@ -838,7 +838,8 @@ Is transformed into
Which, effectively, means emitting a float `let x = arg` and recursively
analysing the body.
-This strategy requires a special case for newtypes. Suppose we have
+For newtypes, this strategy requires that their wrappers have compulsory unfoldings.
+Suppose we have
newtype T a b where
MkT :: a -> T b a -- Note args swapped
@@ -853,7 +854,8 @@ This defines a worker function MkT, a wrapper function $WMkT, and an axT:
Now we are optimising
case $WMkT (I# 3) |> sym axT of I# y -> ...
-we clearly want to simplify this. The danger is that we'll end up with
+we clearly want to simplify this. If $WMkT did not have a compulsory
+unfolding, we would end up with
let a = I#3 in case a of I# y -> ...
because in general, we do this on-the-fly beta-reduction
(\x. e) blah --> let x = blah in e
@@ -863,14 +865,6 @@ But if the case-of-known-constructor doesn't actually fire (i.e.
exprIsConApp_maybe does not return Just) then nothing happens, and nothing
will happen the next time either.
-For newtype wrappers we know for sure that the argument of the beta-redex
-is used exactly once, so we can substitute aggressively rather than use a let.
-Hence the special case, implemented in dealWithNewtypeWrapper.
-(It's sound for any beta-redex where the argument is used once, of course.)
-
-dealWithNewtypeWrapper is recursive since newtypes can have
-multiple type arguments.
-
See test T16254, which checks the behavior of newtypes.
-}
@@ -954,12 +948,6 @@ exprIsConApp_maybe (in_scope, id_unf) expr
= succeedWith in_scope floats $
pushCoDataCon con args co
- -- See Note [Special case for newtype wrappers]
- | Just a <- isDataConWrapId_maybe fun
- , isNewTyCon (dataConTyCon a)
- , let rhs = uf_tmpl (realIdUnfolding fun)
- = dealWithNewtypeWrapper (Left in_scope) floats rhs cont
-
-- Look through data constructor wrappers: they inline late (See Note
-- [Activation for data constructor wrappers]) but we want to do
-- case-of-known-constructor optimisation eagerly.
@@ -1005,13 +993,6 @@ exprIsConApp_maybe (in_scope, id_unf) expr
; return (in_scope, floats, con, tys, args) }
----------------------------
- -- Unconditionally substitute the argument of a newtype
- dealWithNewtypeWrapper scope floats (Lam v body) (CC (arg:args) co)
- = dealWithNewtypeWrapper (extend scope v arg) floats body (CC args co)
- dealWithNewtypeWrapper scope floats expr args
- = go scope floats expr args
-
- ----------------------------
-- Operations on the (Either InScopeSet CoreSubst)
-- The Left case is wildly dominant
subst_co (Left {}) co = co