summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2016-12-21 12:01:32 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2016-12-21 12:26:24 +0000
commite07ad4db75885f6e3ff82aa3343999f2af39a16d (patch)
treecde9711f1916faa6dd87a71aa0da429f110d99f8 /compiler
parentd250d493d1dbe0bcfb19122ab3444c9450babdca (diff)
downloadhaskell-e07ad4db75885f6e3ff82aa3343999f2af39a16d.tar.gz
Don't eta-expand in stable unfoldings
See SimplUtils Note [No eta expansion in stable unfoldings], and Trac #9509 for an excellend diagnosis by Nick Frisby
Diffstat (limited to 'compiler')
-rw-r--r--compiler/simplCore/SimplUtils.hs43
-rw-r--r--compiler/simplCore/Simplify.hs6
2 files changed, 36 insertions, 13 deletions
diff --git a/compiler/simplCore/SimplUtils.hs b/compiler/simplCore/SimplUtils.hs
index 6c4737507a..03adfe00fa 100644
--- a/compiler/simplCore/SimplUtils.hs
+++ b/compiler/simplCore/SimplUtils.hs
@@ -688,11 +688,12 @@ simplEnvForGHCi dflags
updModeForStableUnfoldings :: Activation -> SimplifierMode -> SimplifierMode
-- See Note [Simplifying inside stable unfoldings]
updModeForStableUnfoldings inline_rule_act current_mode
- = current_mode { sm_phase = phaseFromActivation inline_rule_act
- , sm_inline = True
+ = current_mode { sm_phase = phaseFromActivation inline_rule_act
+ , sm_inline = True
, sm_eta_expand = False }
- -- For sm_rules, just inherit; sm_rules might be "off"
- -- because of -fno-enable-rewrite-rules
+ -- sm_eta_expand: see Note [No eta expansion in stable unfoldings]
+ -- For sm_rules, just inherit; sm_rules might be "off"
+ -- because of -fno-enable-rewrite-rules
where
phaseFromActivation (ActiveAfter _ n) = Phase n
phaseFromActivation _ = InitialPhase
@@ -717,6 +718,25 @@ Ticks into the LHS, which makes matching trickier. Trac #10665, #10745.
Doing this to either side confounds tools like HERMIT, which seek to reason
about and apply the RULES as originally written. See Trac #10829.
+Note [No eta expansion in stable unfoldings]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If we have a stable unfolding
+
+ f :: Ord a => a -> IO ()
+ -- Unfolding template
+ -- = /\a \(d:Ord a) (x:a). bla
+
+we do not want to eta-expand to
+
+ f :: Ord a => a -> IO ()
+ -- Unfolding template
+ -- = (/\a \(d:Ord a) (x:a) (eta:State#). bla eta) |> co
+
+because not specialisation of the overloading doesn't work properly
+(see Note [Specialisation shape] in Specialise), Trac #9509.
+
+So we disable eta-expansion in stable unfoldings.
+
Note [Inlining in gentle mode]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Something is inlined if
@@ -1256,16 +1276,16 @@ won't inline because 'e' is too big.
************************************************************************
-}
-mkLam :: [OutBndr] -> OutExpr -> SimplCont -> SimplM OutExpr
+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]
-mkLam [] body _cont
+mkLam _env [] body _cont
= return body
-mkLam bndrs body cont
- = do { dflags <- getDynFlags
- ; mkLam' dflags bndrs body }
+mkLam env bndrs body cont
+ = do { dflags <- getDynFlags
+ ; mkLam' dflags bndrs body }
where
mkLam' :: DynFlags -> [OutBndr] -> OutExpr -> SimplM OutExpr
mkLam' dflags bndrs (Cast body co)
@@ -1293,7 +1313,7 @@ mkLam bndrs body cont
; return etad_lam }
| not (contIsRhs cont) -- See Note [Eta-expanding lambdas]
- , gopt Opt_DoLambdaEtaExpansion dflags
+ , sm_eta_expand (getMode env)
, any isRuntimeVar bndrs
, let body_arity = exprEtaExpandArity dflags body
, body_arity > 0
@@ -1325,6 +1345,9 @@ better eta-expander (in the form of tryEtaExpandRhs), so we don't
bother to try expansion in mkLam in that case; hence the contIsRhs
guard.
+NB: We check the SimplEnv (sm_eta_expand), not DynFlags.
+ See Note [No eta expansion in stable unfoldings]
+
Note [Casts and lambdas]
~~~~~~~~~~~~~~~~~~~~~~~~
Consider
diff --git a/compiler/simplCore/Simplify.hs b/compiler/simplCore/Simplify.hs
index d52aacdde5..4f65b2b379 100644
--- a/compiler/simplCore/Simplify.hs
+++ b/compiler/simplCore/Simplify.hs
@@ -353,7 +353,7 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se
; (env', rhs')
<- if not (doFloatFromRhs top_lvl is_rec False body2 body_env2)
then -- No floating, revert to body1
- do { rhs' <- mkLam tvs' (wrapFloats body_env1 body1) rhs_cont
+ do { rhs' <- mkLam env tvs' (wrapFloats body_env1 body1) rhs_cont
; return (env, rhs') }
else if null tvs then -- Simple floating
@@ -363,7 +363,7 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se
else -- Do type-abstraction first
do { tick LetFloatFromLet
; (poly_binds, body3) <- abstractFloats tvs' body_env2 body2
- ; rhs' <- mkLam tvs' body3 rhs_cont
+ ; rhs' <- mkLam env tvs' body3 rhs_cont
; env' <- foldlM (addPolyBind top_lvl) env poly_binds
; return (env', rhs') }
@@ -1272,7 +1272,7 @@ simplLam env bndrs body (TickIt tickish cont)
simplLam env bndrs body cont
= do { (env', bndrs') <- simplLamBndrs env bndrs
; body' <- simplExpr env' body
- ; new_lam <- mkLam bndrs' body' cont
+ ; new_lam <- mkLam env bndrs' body' cont
; rebuild env' new_lam cont }
simplLamBndrs :: SimplEnv -> [InBndr] -> SimplM (SimplEnv, [OutBndr])