summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Opt/Simplify.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2021-02-19 11:03:15 +0000
committerBen Gamari <ben@well-typed.com>2021-02-28 22:53:23 -0500
commitebe0bd83603c582341bc1466b0ba9dfb060b5880 (patch)
treec214e052aa69c2c65f0ec911ef7bd28a2e938e41 /compiler/GHC/Core/Opt/Simplify.hs
parent915daf51357175fcc31a37c0aaf2347875560269 (diff)
downloadhaskell-wip/T19360.tar.gz
Fix terrible occurrence-analysis bugwip/T19360
Ticket #19360 showed up a terrible bug in the occurrence analyser, in a situation like this Rec { f = g ; g = ..f... {-# RULE g .. = ...f... #-} } Then f was postInlineUnconditionally, but not in the RULE (which is simplified first), so we had a RULE mentioning a variable that was not in scope. This led me to review (again) the subtle loop-breaker stuff in the occurrence analyser. The actual changes are few, and are largely simplifications. I did a /lot/ of comment re-organising though. There was an unexpected amount of fallout. * Validation failed when compiling the stage2 compiler with profiling on. That turned to tickle a second latent bug in the same OccAnal code (at least I think it was always there), which led me to simplify still further; see Note [inl_fvs] in GHC.Core.Opt.OccurAnal. * But that in turn let me to some strange behaviour in CSE when ticks are in the picture, which I duly fixed. See Note [Dealing with ticks] in GHC.Core.Opt.CSE. * Then I got an ASSERT failure in CoreToStg, which again seems to be a latent bug. See Note [Ticks in applications] in GHC.CoreToStg * I also made one unforced change: I now simplify the RHS of a RULE in the same way as the RHS of a stable unfolding. This can allow a trivial binding to disappear sooner than otherwise, and I don't think it has any downsides. The change is in GHC.Core.Opt.Simplify.simplRules.
Diffstat (limited to 'compiler/GHC/Core/Opt/Simplify.hs')
-rw-r--r--compiler/GHC/Core/Opt/Simplify.hs20
1 files changed, 16 insertions, 4 deletions
diff --git a/compiler/GHC/Core/Opt/Simplify.hs b/compiler/GHC/Core/Opt/Simplify.hs
index da039a8e83..13f0fdc46c 100644
--- a/compiler/GHC/Core/Opt/Simplify.hs
+++ b/compiler/GHC/Core/Opt/Simplify.hs
@@ -3996,14 +3996,17 @@ simplRules env mb_new_id rules mb_cont
= return rule
simpl_rule rule@(Rule { ru_bndrs = bndrs, ru_args = args
- , ru_fn = fn_name, ru_rhs = rhs })
+ , ru_fn = fn_name, ru_rhs = rhs
+ , ru_act = act })
= do { (env', bndrs') <- simplBinders env bndrs
; let rhs_ty = substTy env' (exprType rhs)
rhs_cont = case mb_cont of -- See Note [Rules and unfolding for join points]
Nothing -> mkBoringStop rhs_ty
Just cont -> ASSERT2( join_ok, bad_join_msg )
cont
- rule_env = updMode updModeForRules env'
+ lhs_env = updMode updModeForRules env'
+ rhs_env = updMode (updModeForStableUnfoldings act) env'
+ -- See Note [Simplifying the RHS of a RULE]
fn_name' = case mb_new_id of
Just id -> idName id
Nothing -> fn_name
@@ -4018,9 +4021,18 @@ simplRules env mb_new_id rules mb_cont
bad_join_msg = vcat [ ppr mb_new_id, ppr rule
, ppr (fmap isJoinId_maybe mb_new_id) ]
- ; args' <- mapM (simplExpr rule_env) args
- ; rhs' <- simplExprC rule_env rhs rhs_cont
+ ; args' <- mapM (simplExpr lhs_env) args
+ ; rhs' <- simplExprC rhs_env rhs rhs_cont
; return (rule { ru_bndrs = bndrs'
, ru_fn = fn_name'
, ru_args = args'
, ru_rhs = rhs' }) }
+
+{- Note [Simplifying the RHS of a RULE]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We can simplify the RHS of a RULE much as we do the RHS of a stable
+unfolding. We used to use the much more conservative updModeForRules
+for the RHS as well as the LHS, but that seems more conservative
+than necesary. Allowing some inlining might, for example, eliminate
+a binding.
+-} \ No newline at end of file