diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2020-02-06 15:11:21 +0100 |
---|---|---|
committer | Andreas Klebinger <klebinger.andreas@gmx.at> | 2020-02-06 17:04:27 +0100 |
commit | c2886bf608b283ce9034a1cf5ad854b8b9286b5e (patch) | |
tree | e85ac268370530d7018f992d3bd3fb5ddf767ecc /compiler | |
parent | 5e63d9c07c0585b85c8fa340d30aeff0130af3f4 (diff) | |
download | haskell-wip/andreask/T17724.tar.gz |
Fix #17724 by running the simplifier before late CSEwip/andreask/T17724
CSE seems to depend on bindings being in dependency order.
The simplifier put's bindings into dependency order.
So do a simplifier run first.
We used to do in order
* ...
* optional: late spec + simplifier "post-late-spec" run
* optional: late cse
* simplifier "final" run
* ...
We now do:
* ...
* optional: late spec
* optional: simplifier "pre-late-cse" run + cse
* simplifier "final" run.
* ...
The result is that:
* At -O we now potentially do fewer runs of the simplifier.
"post-late-spec" is gone if late-spec is on
* At -O2 we do an additional simplifier run : "pre-late-cse"
* At -O2 with -fspec-late we do what we already did.
Only that the intermediate simplifier run is called "pre-late-cse"
instead of "post-late-spec".
We also removed a case where occAnal dropped code it assumed to be dead.
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/simplCore/CSE.hs | 1 | ||||
-rw-r--r-- | compiler/simplCore/OccurAnal.hs | 7 | ||||
-rw-r--r-- | compiler/simplCore/SimplCore.hs | 8 |
3 files changed, 12 insertions, 4 deletions
diff --git a/compiler/simplCore/CSE.hs b/compiler/simplCore/CSE.hs index 9a0945e290..0835f87bb0 100644 --- a/compiler/simplCore/CSE.hs +++ b/compiler/simplCore/CSE.hs @@ -327,6 +327,7 @@ the program; it's a kind of synthetic key for recursive bindings. ************************************************************************ -} +-- | Requires bindings to be in dependency order. cseProgram :: CoreProgram -> CoreProgram cseProgram binds = snd (mapAccumL (cseBind TopLevel) emptyCSEnv binds) diff --git a/compiler/simplCore/OccurAnal.hs b/compiler/simplCore/OccurAnal.hs index 96ee9623c3..47460178f1 100644 --- a/compiler/simplCore/OccurAnal.hs +++ b/compiler/simplCore/OccurAnal.hs @@ -81,11 +81,16 @@ occurAnalysePgm this_mod active_unf active_rule imp_rules binds (final_usage, occ_anald_binds) = go init_env binds (_, occ_anald_glommed_binds) = occAnalRecBind init_env TopLevel imp_rule_edges - (flattenBinds occ_anald_binds) + (flattenBinds binds) initial_uds -- It's crucial to re-analyse the glommed-together bindings -- so that we establish the right loop breakers. Otherwise -- we can easily create an infinite loop (#9583 is an example) + -- + -- Also crucial to re-analyse the /original/ bindings + -- in case the first pass accidentally discarded as dead code + -- a binding that was actually needed (albeit before its + -- definition site). #17724 threw this up. initial_uds = addManyOccsSet emptyDetails (rulesFreeVars imp_rules) diff --git a/compiler/simplCore/SimplCore.hs b/compiler/simplCore/SimplCore.hs index b8fb162432..799dfa93fe 100644 --- a/compiler/simplCore/SimplCore.hs +++ b/compiler/simplCore/SimplCore.hs @@ -318,15 +318,17 @@ getCoreToDo dflags maybe_rule_check (Phase 0), - runWhen late_specialise - (CoreDoPasses [ CoreDoSpecialising - , simpl_phase 0 ["post-late-spec"] max_iter]), + runWhen late_specialise CoreDoSpecialising, -- LiberateCase can yield new CSE opportunities because it peels -- off one layer of a recursive function (concretely, I saw this -- in wheel-sieve1), and I'm guessing that SpecConstr can too -- And CSE is a very cheap pass. So it seems worth doing here. + -- This helps shake out any effect of liberate_case/spec_constr. + -- It also puts bindings in dependency order, which helps with CSE. runWhen ((liberate_case || spec_constr) && cse) CoreCSE, + ( CoreDoPasses [ simpl_phase 0 ["pre-late-cse"] max_iter + , CoreCSE ]), -- Final clean-up simplification: simpl_phase 0 ["final"] max_iter, |