summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/GHC/Core/Coercion.hs11
-rw-r--r--compiler/GHC/Core/Opt/Arity.hs145
-rw-r--r--compiler/GHC/Core/Opt/Simplify.hs49
-rw-r--r--compiler/GHC/Core/Opt/Simplify/Utils.hs20
4 files changed, 152 insertions, 73 deletions
diff --git a/compiler/GHC/Core/Coercion.hs b/compiler/GHC/Core/Coercion.hs
index ba3da23d93..aa0cf29754 100644
--- a/compiler/GHC/Core/Coercion.hs
+++ b/compiler/GHC/Core/Coercion.hs
@@ -73,7 +73,7 @@ module GHC.Core.Coercion (
coToMCo, mkTransMCo, mkTransMCoL, mkTransMCoR, mkCastTyMCo, mkSymMCo,
mkHomoForAllMCo, mkFunResMCo, mkPiMCos,
- isReflMCo,
+ isReflMCo, checkReflexiveMCo,
-- ** Coercion variables
mkCoVar, isCoVar, coVarName, setCoVarName, setCoVarUnique,
@@ -311,6 +311,11 @@ coToMCo :: Coercion -> MCoercion
coToMCo co | isReflCo co = MRefl
| otherwise = MCo co
+checkReflexiveMCo :: MCoercion -> MCoercion
+checkReflexiveMCo MRefl = MRefl
+checkReflexiveMCo (MCo co) | isReflexiveCo co = MRefl
+ | otherwise = MCo co
+
-- | Tests if this MCoercion is obviously generalized reflexive
-- Guaranteed to work very quickly.
isGReflMCo :: MCoercion -> Bool
@@ -420,6 +425,10 @@ decomposeFunCo :: HasDebugCallStack
-- Expects co :: (s1 -> t1) ~ (s2 -> t2)
-- Returns (co1 :: s1~s2, co2 :: t1~t2)
-- See Note [Function coercions] for the "3" and "4"
+
+decomposeFunCo _ (FunCo _ w co1 co2) = (w, co1, co2)
+ -- Short-circuits the calls to mkNthCo
+
decomposeFunCo r co = assertPpr all_ok (ppr co)
(mkNthCo Nominal 0 co, mkNthCo r 3 co, mkNthCo r 4 co)
where
diff --git a/compiler/GHC/Core/Opt/Arity.hs b/compiler/GHC/Core/Opt/Arity.hs
index 53f2c28213..fcc35d76b5 100644
--- a/compiler/GHC/Core/Opt/Arity.hs
+++ b/compiler/GHC/Core/Opt/Arity.hs
@@ -592,7 +592,7 @@ arityTypeArity (AT oss _) = length oss
-- | True <=> eta-expansion will add at least one lambda
expandableArityType :: ArityType -> Bool
-expandableArityType at = arityTypeArity at /= 0
+expandableArityType at = arityTypeArity at > 0
-- | See Note [Dead ends] in "GHC.Types.Demand".
-- Bottom implies a dead end.
@@ -667,6 +667,7 @@ findRhsArity dflags bndr rhs old_arity
where
env = extendSigEnv (findRhsArityEnv dflags) bndr at
+
{-
Note [Arity analysis]
~~~~~~~~~~~~~~~~~~~~~
@@ -1293,12 +1294,22 @@ see Note [The one-shot state monad trick] in GHC.Utils.Monad.
-- We should have that:
--
-- > ty = exprType e = exprType e'
-etaExpand :: Arity -> CoreExpr -> CoreExpr
-etaExpandAT :: ArityType -> CoreExpr -> CoreExpr
-etaExpand n orig_expr = eta_expand (replicate n NoOneShotInfo) orig_expr
-etaExpandAT (AT oss _) orig_expr = eta_expand oss orig_expr
- -- See Note [Eta expansion with ArityType]
+etaExpand :: Arity -> CoreExpr -> CoreExpr
+etaExpand n orig_expr
+ = eta_expand in_scope (replicate n NoOneShotInfo) orig_expr
+ where
+ in_scope = {-#SCC "eta_expand:in-scopeX" #-}
+ mkInScopeSet (exprFreeVars orig_expr)
+
+etaExpandAT :: InScopeSet -> ArityType -> CoreExpr -> CoreExpr
+-- See Note [Eta expansion with ArityType]
+--
+-- We pass in the InScopeSet from the simplifier to avoid recomputing
+-- it here, which can be jolly expensive if the casts are big
+-- In #18223 it took 10% of compile time just to do the exprFreeVars!
+etaExpandAT in_scope (AT oss _) orig_expr
+ = eta_expand in_scope oss orig_expr
-- etaExpand arity e = res
-- Then 'res' has at least 'arity' lambdas at the top
@@ -1311,12 +1322,12 @@ etaExpandAT (AT oss _) orig_expr = eta_expand oss orig_e
-- would return
-- (/\b. \y::a -> E b y)
-eta_expand :: [OneShotInfo] -> CoreExpr -> CoreExpr
-eta_expand one_shots (Cast expr co)
- = mkCast (eta_expand one_shots expr) co
+eta_expand :: InScopeSet -> [OneShotInfo] -> CoreExpr -> CoreExpr
+eta_expand in_scope one_shots (Cast expr co)
+ = Cast (eta_expand in_scope one_shots expr) co
-eta_expand one_shots orig_expr
- = go one_shots [] orig_expr
+eta_expand in_scope one_shots orig_expr
+ = go in_scope one_shots [] orig_expr
where
-- Strip off existing lambdas and casts before handing off to mkEtaWW
-- This is mainly to avoid spending time cloning binders and substituting
@@ -1324,20 +1335,20 @@ eta_expand one_shots orig_expr
-- with casts here, apart from the topmost one, and they are rare, so
-- if we find one we just hand off to mkEtaWW anyway
-- Note [Eta expansion and SCCs]
- go [] _ _ = orig_expr -- Already has the specified arity; no-op
+ go _ [] _ _ = orig_expr -- Already has the specified arity; no-op
- go oss@(_:oss1) vs (Lam v body)
- | isTyVar v = go oss (v:vs) body
- | otherwise = go oss1 (v:vs) body
+ go in_scope oss@(_:oss1) vs (Lam v body)
+ | isTyVar v = go (in_scope `extendInScopeSet` v) oss (v:vs) body
+ | otherwise = go (in_scope `extendInScopeSet` v) oss1 (v:vs) body
- go oss rev_vs expr
- = -- pprTrace "ee" (vcat [ppr orig_expr, ppr expr, pprEtaInfos etas]) $
- retick $ etaInfoAbs top_eis $
- etaInfoApp in_scope' sexpr eis
+ go in_scope oss rev_vs expr
+ = -- pprTrace "ee" (vcat [ppr in_scope', ppr top_bndrs, ppr eis]) $
+ retick $
+ etaInfoAbs top_eis $
+ etaInfoApp in_scope' sexpr eis
where
- in_scope = mkInScopeSet (exprFreeVars expr)
(in_scope', eis@(EI eta_bndrs mco))
- = mkEtaWW oss (ppr orig_expr) in_scope (exprType expr)
+ = mkEtaWW oss (ppr orig_expr) in_scope (exprType expr)
top_bndrs = reverse rev_vs
top_eis = EI (top_bndrs ++ eta_bndrs) (mkPiMCos top_bndrs mco)
@@ -1380,23 +1391,29 @@ This what eta_expand does. We do it in two steps:
To a first approximation EtaInfo is just [Var]. But
casts complicate the question. If we have
newtype N a = MkN (S -> a)
+ axN :: N a ~ S -> a
and
- ty = N (N Int)
-then the eta-expansion must look like
- (\x (\y. ((e |> co1) x) |> co2) y)
- |> sym co2)
- |> sym co1
+ e :: N (N Int)
+then the eta-expansion should look like
+ (\(x::S) (y::S) -> e |> co x y) |> sym co
where
- co1 :: N (N Int) ~ S -> N Int
- co2 :: N Int ~ S -> Int
+ co :: N (N Int) ~ S -> S -> Int
+ co = axN @(N Int) ; (S -> axN @Int)
-Blimey! Look at all those casts. Moreover, if the type
-is very deeply nested (as happens in #18223), the repetition
+We want to get one cast, at the top, to account for all those
+nested newtypes. This is expressed by the EtaInfo type:
+
+ data EtaInfo = EI [Var] MCoercionR
+
+Note [Check for reflexive casts in eta expansion]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+It turns out that the casts created by teh above mechanism are often Refl.
+When casts are very deeply nested (as happens in #18223), the repetition
of types can make the overall term very large. So there is a big
payoff in cancelling out casts aggressively wherever possible.
(See also Note [No crap in eta-expanded code].)
-This matters a lot in etaEInfoApp, where we
+This matters particularly in etaInfoApp, where we
* Do beta-reduction on the fly
* Use getArg_maybe to get a cast out of the way,
so that we can do beta reduction
@@ -1413,23 +1430,56 @@ away.
#18223 was a dramatic example in which the intermediate term was
grotesquely huge, even though the next Simplifier iteration squashed
it. Better to kill it at birth.
+
+The crucial spots in etaInfoApp are:
+* `checkReflexiveMCo` in the (Cast e co) case of `go`
+* `checkReflexiveMCo` in `pushCoArg`
+* Less important: checkReflexiveMCo in the final case of `go`
+Collectively these make a factor-of-5 difference to the total
+allocation of T18223, so take care if you change this stuff!
+
+Example:
+ newtype N = MkN (Y->Z)
+ f :: X -> N
+ f = \(x::X). ((\(y::Y). blah) |> fco)
+
+where fco :: (Y->Z) ~ N
+
+mkEtaWW makes an EtaInfo of (EI [(eta1:X), (eta2:Y)] eta_co
+ where
+ eta_co :: (X->N) ~ (X->Y->Z)
+ eta_co = (<X> -> nco)
+ nco :: N ~ (Y->Z) -- Comes from topNormaliseNewType_maybe
+
+Now, when we push that eta_co inward in etaInfoApp:
+* In the (Cast e co) case, the 'fco' and 'nco' will meet, and
+ should cancel.
+* When we meet the (\y.e) we want no cast on the y.
+
-}
--------------
data EtaInfo = EI [Var] MCoercionR
--- EI bs co
--- Abstraction: (\b1 b2 .. bn. []) |> sym co
--- Application: ([] |> co) b1 b2 .. bn
+-- (EI bs co) describes a particular eta-expansion, as follows:
+-- Abstraction: (\b1 b2 .. bn. []) |> sym co
+-- Application: ([] |> co) b1 b2 .. bn
--
-- e :: T co :: T ~ (t1 -> t2 -> .. -> tn -> tr)
-- e = (\b1 b2 ... bn. (e |> co) b1 b2 .. bn) |> sym co
+instance Outputable EtaInfo where
+ ppr (EI vs mco) = text "EI" <+> ppr vs <+> parens (ppr mco)
+
etaInfoApp :: InScopeSet -> CoreExpr -> EtaInfo -> CoreExpr
--- (etaInfoApp s e eis) returns something equivalent to
--- (substExpr s e `appliedto` eis)
+-- (etaInfoApp s e (EI bs mco) returns something equivalent to
+-- ((substExpr s e) |> mco b1 .. bn)
-- See Note [The EtaInfo mechanism]
+--
+-- NB: With very deeply nested casts, this function can be expensive
+-- In T18223, this function alone costs 15% of allocation, all
+-- spent in the calls to substExprSC and substBindSC
etaInfoApp in_scope expr eis
= go (mkEmptySubst in_scope) expr eis
@@ -1442,7 +1492,10 @@ etaInfoApp in_scope expr eis
= Tick (substTickish subst t) (go subst e eis)
go subst (Cast e co) (EI bs mco)
- = go subst e (EI bs (Core.substCo subst co `mkTransMCoR` mco))
+ = go subst e (EI bs mco')
+ where
+ mco' = checkReflexiveMCo (Core.substCo subst co `mkTransMCoR` mco)
+ -- See Note [Check for reflexive casts in eta-expansion]
go subst (Case e b ty alts) eis
= Case (Core.substExprSC subst e) b1 ty' alts'
@@ -1467,8 +1520,9 @@ etaInfoApp in_scope expr eis
= go (Core.extendSubst subst v arg) e (EI bs mco')
-- Stop pushing down; just wrap the expression up
+ -- See Note [Check for reflexive casts in eta expansion]
go subst e (EI bs mco) = Core.substExprSC subst e
- `mkCastMCo` mco
+ `mkCastMCo` checkReflexiveMCo mco
`mkVarApps` bs
--------------
@@ -1617,10 +1671,17 @@ pushCoArg :: CoercionR -> CoreArg -> Maybe (CoreArg, MCoercion)
-- This may fail, e.g. if (fun :: N) where N is a newtype
-- C.f. simplCast in GHC.Core.Opt.Simplify
-- 'co' is always Representational
-pushCoArg co (Type ty) = do { (ty', m_co') <- pushCoTyArg co ty
- ; return (Type ty', m_co') }
-pushCoArg co val_arg = do { (arg_co, m_co') <- pushCoValArg co
- ; return (val_arg `mkCastMCo` arg_co, m_co') }
+pushCoArg co arg
+ | Type ty <- arg
+ = do { (ty', m_co') <- pushCoTyArg co ty
+ ; return (Type ty', m_co') }
+ | otherwise
+ = do { (arg_mco, m_co') <- pushCoValArg co
+ ; let arg_mco' = checkReflexiveMCo arg_mco
+ -- checkReflexiveMCo: see Note [Check for reflexive casts in eta expansion]
+ -- The coercion is very often (arg_co -> res_co), but without
+ -- the argument coercion actually being ReflCo
+ ; return (arg `mkCastMCo` arg_mco', m_co') }
pushCoTyArg :: CoercionR -> Type -> Maybe (Type, MCoercionR)
-- We have (fun |> co) @ty
diff --git a/compiler/GHC/Core/Opt/Simplify.hs b/compiler/GHC/Core/Opt/Simplify.hs
index 406c6ed1a0..ac55c68ded 100644
--- a/compiler/GHC/Core/Opt/Simplify.hs
+++ b/compiler/GHC/Core/Opt/Simplify.hs
@@ -362,7 +362,7 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se
-- ANF-ise a constructor or PAP rhs
-- We get at most one float per argument here
; (let_floats, body2) <- {-#SCC "prepareBinding" #-}
- prepareBinding env top_lvl bndr1 body1
+ prepareBinding body_env top_lvl bndr1 body1
; let body_floats2 = body_floats1 `addLetFloats` let_floats
; (rhs_floats, rhs')
@@ -608,7 +608,7 @@ tryCastWorkerWrapper env top_lvl old_bndr occ_info bndr (Cast rhs co)
, not (hasInlineUnfolding info) -- Not INLINE things: Wrinkle 4
, not (isUnliftedType rhs_ty) -- Not if rhs has an unlifted type;
-- see Note [Cast w/w: unlifted]
- = do { (rhs_floats, work_rhs) <- prepareRhs mode top_lvl occ_fs rhs
+ = do { (rhs_floats, work_rhs) <- prepareRhs env top_lvl occ_fs rhs
; uniq <- getUniqueM
; let work_name = mkSystemVarName uniq occ_fs
work_id = mkLocalIdWithInfo work_name Many rhs_ty worker_info
@@ -691,7 +691,7 @@ prepareBinding :: SimplEnv -> TopLevelFlag
-> OutId -> OutExpr
-> SimplM (LetFloats, OutExpr)
prepareBinding env top_lvl bndr rhs
- = prepareRhs (getMode env) top_lvl (getOccFS bndr) rhs
+ = prepareRhs env top_lvl (getOccFS bndr) rhs
{- Note [prepareRhs]
~~~~~~~~~~~~~~~~~~~~
@@ -711,7 +711,7 @@ Here we want to make e1,e2 trivial and get
That's what the 'go' loop in prepareRhs does
-}
-prepareRhs :: SimplMode -> TopLevelFlag
+prepareRhs :: SimplEnv -> TopLevelFlag
-> FastString -- Base for any new variables
-> OutExpr
-> SimplM (LetFloats, OutExpr)
@@ -721,7 +721,7 @@ prepareRhs :: SimplMode -> TopLevelFlag
-- becomes a = e
-- x = Just a
-- See Note [prepareRhs]
-prepareRhs mode top_lvl occ rhs0
+prepareRhs env top_lvl occ rhs0
= do { (_is_exp, floats, rhs1) <- go 0 rhs0
; return (floats, rhs1) }
where
@@ -736,7 +736,7 @@ prepareRhs mode top_lvl occ rhs0
= do { (is_exp, floats1, fun') <- go (n_val_args+1) fun
; case is_exp of
False -> return (False, emptyLetFloats, App fun arg)
- True -> do { (floats2, arg') <- makeTrivial mode top_lvl topDmd occ arg
+ True -> do { (floats2, arg') <- makeTrivial env top_lvl topDmd occ arg
; return (True, floats1 `addLetFlts` floats2, App fun' arg') } }
go n_val_args (Var fun)
= return (is_exp, emptyLetFloats, Var fun)
@@ -765,58 +765,60 @@ prepareRhs mode top_lvl occ rhs0
go _ other
= return (False, emptyLetFloats, other)
-makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec)
-makeTrivialArg mode arg@(ValArg { as_arg = e, as_dmd = dmd })
- = do { (floats, e') <- makeTrivial mode NotTopLevel dmd (fsLit "arg") e
+makeTrivialArg :: SimplEnv -> ArgSpec -> SimplM (LetFloats, ArgSpec)
+makeTrivialArg env arg@(ValArg { as_arg = e, as_dmd = dmd })
+ = do { (floats, e') <- makeTrivial env NotTopLevel dmd (fsLit "arg") e
; return (floats, arg { as_arg = e' }) }
makeTrivialArg _ arg
= return (emptyLetFloats, arg) -- CastBy, TyArg
-makeTrivial :: SimplMode -> TopLevelFlag -> Demand
+makeTrivial :: SimplEnv -> TopLevelFlag -> Demand
-> FastString -- ^ A "friendly name" to build the new binder from
-> OutExpr -- ^ This expression satisfies the let/app invariant
-> SimplM (LetFloats, OutExpr)
-- Binds the expression to a variable, if it's not trivial, returning the variable
-- For the Demand argument, see Note [Keeping demand info in StrictArg Plan A]
-makeTrivial mode top_lvl dmd occ_fs expr
+makeTrivial env top_lvl dmd occ_fs expr
| exprIsTrivial expr -- Already trivial
|| not (bindingOk top_lvl expr expr_ty) -- Cannot trivialise
-- See Note [Cannot trivialise]
= return (emptyLetFloats, expr)
| Cast expr' co <- expr
- = do { (floats, triv_expr) <- makeTrivial mode top_lvl dmd occ_fs expr'
+ = do { (floats, triv_expr) <- makeTrivial env top_lvl dmd occ_fs expr'
; return (floats, Cast triv_expr co) }
| otherwise
- = do { (floats, new_id) <- makeTrivialBinding mode top_lvl occ_fs
+ = do { (floats, new_id) <- makeTrivialBinding env top_lvl occ_fs
id_info expr expr_ty
; return (floats, Var new_id) }
where
id_info = vanillaIdInfo `setDemandInfo` dmd
expr_ty = exprType expr
-makeTrivialBinding :: SimplMode -> TopLevelFlag
+makeTrivialBinding :: SimplEnv -> TopLevelFlag
-> FastString -- ^ a "friendly name" to build the new binder from
-> IdInfo
-> OutExpr -- ^ This expression satisfies the let/app invariant
-> OutType -- Type of the expression
-> SimplM (LetFloats, OutId)
-makeTrivialBinding mode top_lvl occ_fs info expr expr_ty
- = do { (floats, expr1) <- prepareRhs mode top_lvl occ_fs expr
+makeTrivialBinding env top_lvl occ_fs info expr expr_ty
+ = do { (floats, expr1) <- prepareRhs env top_lvl occ_fs expr
; uniq <- getUniqueM
; let name = mkSystemVarName uniq occ_fs
var = mkLocalIdWithInfo name Many expr_ty info
-- Now something very like completeBind,
-- but without the postInlineUnconditionally part
- ; (arity_type, expr2) <- tryEtaExpandRhs mode var expr1
+ ; (arity_type, expr2) <- tryEtaExpandRhs env var expr1
; unf <- mkLetUnfolding (sm_uf_opts mode) top_lvl InlineRhs var expr2
; let final_id = addLetBndrInfo var arity_type unf
bind = NonRec final_id expr2
; return ( floats `addLetFlts` unitLetFloat bind, final_id ) }
+ where
+ mode = getMode env
bindingOk :: TopLevelFlag -> CoreExpr -> Type -> Bool
-- True iff we can have a binding of this expression at this level
@@ -900,11 +902,10 @@ completeBind env top_lvl mb_cont old_bndr new_bndr new_rhs
do { let old_info = idInfo old_bndr
old_unf = realUnfoldingInfo old_info
occ_info = occInfo old_info
- mode = getMode env
-- Do eta-expansion on the RHS of the binding
-- See Note [Eta-expanding at let bindings] in GHC.Core.Opt.Simplify.Utils
- ; (new_arity, eta_rhs) <- tryEtaExpandRhs mode new_bndr new_rhs
+ ; (new_arity, eta_rhs) <- tryEtaExpandRhs env new_bndr new_rhs
-- Simplify the unfolding
; new_unfolding <- simplLetUnfolding env top_lvl mb_cont old_bndr
@@ -1651,8 +1652,8 @@ simplLam env bndrs body (TickIt tickish cont)
-- Not enough args, so there are real lambdas left to put in the result
simplLam env bndrs body cont
= do { (env', bndrs') <- simplLamBndrs env bndrs
- ; body' <- simplExpr env' body
- ; new_lam <- mkLam env bndrs' body' cont
+ ; body' <- simplExpr env' body
+ ; new_lam <- mkLam env' bndrs' body' cont
; rebuild env' new_lam cont }
-------------
@@ -3478,7 +3479,7 @@ mkDupableContWithDmds env _
; (floats1, cont') <- mkDupableContWithDmds env dmds cont
-- Use the demands from the function to add the right
-- demand info on any bindings we make for further args
- ; (floats_s, args') <- mapAndUnzipM (makeTrivialArg (getMode env))
+ ; (floats_s, args') <- mapAndUnzipM (makeTrivialArg env)
(ai_args fun)
; return ( foldl' addLetFloats floats1 floats_s
, StrictArg { sc_fun = fun { ai_args = args' }
@@ -3524,7 +3525,7 @@ mkDupableContWithDmds env dmds
; (floats1, cont') <- mkDupableContWithDmds env dmds cont
; let env' = env `setInScopeFromF` floats1
; (_, se', arg') <- simplArg env' dup se arg
- ; (let_floats2, arg'') <- makeTrivial (getMode env) NotTopLevel dmd (fsLit "karg") arg'
+ ; (let_floats2, arg'') <- makeTrivial env NotTopLevel dmd (fsLit "karg") arg'
; let all_floats = floats1 `addLetFloats` let_floats2
; return ( all_floats
, ApplyToVal { sc_arg = arg''
@@ -4109,7 +4110,7 @@ simplStableUnfolding env top_lvl mb_cont id rhs_ty id_arity unf
eta_expand expr
| not eta_on = expr
| exprIsTrivial expr = expr
- | otherwise = etaExpandAT id_arity expr
+ | otherwise = etaExpandAT (getInScope env) id_arity expr
eta_on = sm_eta_expand (getMode env)
{- Note [Eta-expand stable unfoldings]
diff --git a/compiler/GHC/Core/Opt/Simplify/Utils.hs b/compiler/GHC/Core/Opt/Simplify/Utils.hs
index 39f62d8744..5c3114e76b 100644
--- a/compiler/GHC/Core/Opt/Simplify/Utils.hs
+++ b/compiler/GHC/Core/Opt/Simplify/Utils.hs
@@ -409,6 +409,7 @@ contIsRhsOrArg _ = False
contIsRhs :: SimplCont -> Bool
contIsRhs (Stop _ RhsCtxt) = True
+contIsRhs (CastIt _ k) = contIsRhs k -- For f = e |> co, treat e as Rhs context
contIsRhs _ = False
-------------------
@@ -1557,11 +1558,13 @@ mkLam :: SimplEnv -> [OutBndr] -> OutExpr -> SimplCont -> SimplM OutExpr
-- mkLam tries three things
-- a) eta reduction, if that gives a trivial expression
-- b) eta expansion [only if there are some value lambdas]
-
+--
+-- NB: the SimplEnv already includes the [OutBndr] in its in-scope set
mkLam _env [] body _cont
= return body
mkLam env bndrs body cont
- = do { dflags <- getDynFlags
+ = {-#SCC "mkLam" #-}
+ do { dflags <- getDynFlags
; mkLam' dflags bndrs body }
where
mkLam' :: DynFlags -> [OutBndr] -> OutExpr -> SimplM OutExpr
@@ -1595,13 +1598,16 @@ mkLam env bndrs body cont
, let body_arity = exprEtaExpandArity dflags body
, expandableArityType body_arity
= do { tick (EtaExpansion (head bndrs))
- ; let res = mkLams bndrs (etaExpandAT body_arity body)
+ ; let res = mkLams bndrs $
+ etaExpandAT in_scope body_arity body
; traceSmpl "eta expand" (vcat [text "before" <+> ppr (mkLams bndrs body)
, text "after" <+> ppr res])
; return res }
| otherwise
= return (mkLams bndrs body)
+ where
+ in_scope = getInScope env -- Includes 'bndrs'
{-
Note [Eta expanding lambdas]
@@ -1664,13 +1670,13 @@ because the latter is not well-kinded.
************************************************************************
-}
-tryEtaExpandRhs :: SimplMode -> OutId -> OutExpr
+tryEtaExpandRhs :: SimplEnv -> OutId -> OutExpr
-> SimplM (ArityType, OutExpr)
-- See Note [Eta-expanding at let bindings]
-- If tryEtaExpandRhs rhs = (n, is_bot, rhs') then
-- (a) rhs' has manifest arity n
-- (b) if is_bot is True then rhs' applied to n args is guaranteed bottom
-tryEtaExpandRhs mode bndr rhs
+tryEtaExpandRhs env bndr rhs
| Just join_arity <- isJoinId_maybe bndr
= do { let (join_bndrs, join_body) = collectNBinders join_arity rhs
oss = [idOneShotInfo id | id <- join_bndrs, isId id]
@@ -1686,12 +1692,14 @@ tryEtaExpandRhs mode bndr rhs
, new_arity > old_arity -- And the current manifest arity isn't enough
, want_eta rhs
= do { tick (EtaExpansion bndr)
- ; return (arity_type, etaExpandAT arity_type rhs) }
+ ; return (arity_type, etaExpandAT in_scope arity_type rhs) }
| otherwise
= return (arity_type, rhs)
where
+ mode = getMode env
+ in_scope = getInScope env
dflags = sm_dflags mode
old_arity = exprArity rhs