diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2021-02-19 11:03:15 +0000 |
---|---|---|
committer | Ben Gamari <ben@well-typed.com> | 2021-02-28 22:53:23 -0500 |
commit | ebe0bd83603c582341bc1466b0ba9dfb060b5880 (patch) | |
tree | c214e052aa69c2c65f0ec911ef7bd28a2e938e41 /compiler/GHC/Core/Opt/Simplify.hs | |
parent | 915daf51357175fcc31a37c0aaf2347875560269 (diff) | |
download | haskell-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.hs | 20 |
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 |