diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2020-08-24 14:36:57 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-09-22 05:37:24 -0400 |
commit | 6de40f83c53c3b1899f7b4912badbe98e4fbde88 (patch) | |
tree | 9a311c2630a5ecd66abcee3a02ce8efef7364262 /testsuite/tests/stranal | |
parent | aaa51dcfdb729f130aeefeaeac15029b62096a74 (diff) | |
download | haskell-6de40f83c53c3b1899f7b4912badbe98e4fbde88.tar.gz |
Better eta-expansion (again) and don't specilise DFuns
This patch fixes #18223, which made GHC generate an exponential
amount of code. There are three quite separate changes in here
1. Re-engineer eta-expansion (again). The eta-expander was
generating lots of intermediate stuff, which could be optimised
away, but which choked the simplifier meanwhile. Relatively
easy to kill it off at source.
See Note [The EtaInfo mechanism] in GHC.Core.Opt.Arity.
The main new thing is the use of pushCoArg in getArg_maybe.
2. Stop Specialise specalising DFuns. This is the cause of a huge
(and utterly unnecessary) blowup in program size in #18223.
See Note [Do not specialise DFuns] in GHC.Core.Opt.Specialise.
I also refactored the Specialise monad a bit... it was silly,
because it passed on unchanging values as if they were mutable
state.
3. Do an extra Simplifer run, after SpecConstra and before
late-Specialise. I found (investigating perf/compiler/T16473)
that failing to do this was crippling *both* SpecConstr *and*
Specialise. See Note [Simplify after SpecConstr] in
GHC.Core.Opt.Pipeline.
This change does mean an extra run of the Simplifier, but only
with -O2, and I think that's acceptable.
T16473 allocates *three* times less with this change. (I changed
it to check runtime rather than compile time.)
Some smaller consequences
* I moved pushCoercion, pushCoArg and friends from SimpleOpt
to Arity, because it was needed by the new etaInfoApp.
And pushCoValArg now returns a MCoercion rather than Coercion for
the argument Coercion.
* A minor, incidental improvement to Core pretty-printing
This does fix #18223, (which was otherwise uncompilable. Hooray. But
there is still a big intermediate because there are some very deeply
nested types in that program.
Modest reductions in compile-time allocation on a couple of benchmarks
T12425 -2.0%
T13253 -10.3%
Metric increase with -O2, due to extra simplifier run
T9233 +5.8%
T12227 +1.8%
T15630 +5.0%
There is a spurious apparent increase on heap residency on T9630,
on some architectures at least. I tried it with -G1 and the residency
is essentially unchanged.
Metric Increase
T9233
T12227
T9630
Metric Decrease
T12425
T13253
Diffstat (limited to 'testsuite/tests/stranal')
-rw-r--r-- | testsuite/tests/stranal/should_compile/T18122.stderr | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/testsuite/tests/stranal/should_compile/T18122.stderr b/testsuite/tests/stranal/should_compile/T18122.stderr index ff18350279..f94751fb55 100644 --- a/testsuite/tests/stranal/should_compile/T18122.stderr +++ b/testsuite/tests/stranal/should_compile/T18122.stderr @@ -13,9 +13,8 @@ Lib.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Lib.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] Lib.$trModule3 = GHC.Types.TrNameS Lib.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -28,27 +27,25 @@ Lib.$trModule2 = "Lib"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Lib.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] Lib.$trModule1 = GHC.Types.TrNameS Lib.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Lib.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] Lib.$trModule = GHC.Types.Module Lib.$trModule3 Lib.$trModule1 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} Lib.$wfoo [InlPrag=NOINLINE] :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# [GblId, Arity=2, Str=<L,U><L,U>, Unf=OtherCon []] -Lib.$wfoo = (GHC.Prim.+#) +Lib.$wfoo = GHC.Prim.+# -- RHS size: {terms: 18, types: 14, coercions: 0, joins: 0/0} -foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int +foo [InlPrag=NOUSERINLINE[final]] :: (Int, Int) -> Int -> Int [GblId, Arity=2, Str=<S(SL),1*U(1*U(U),A)><S,1*U(U)>, @@ -56,24 +53,25 @@ foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (w_sHs [Occ=Once!] :: (Int, Int)) - (w1_sHt [Occ=Once!] :: Int) -> - case w_sHs of { (ww1_sHw [Occ=Once!], _ [Occ=Dead]) -> - case ww1_sHw of { GHC.Types.I# ww4_sHz [Occ=Once] -> - case w1_sHt of { GHC.Types.I# ww6_sHF [Occ=Once] -> - case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ [Occ=Once] { __DEFAULT -> - GHC.Types.I# ww7_sHJ + Tmpl= \ (w_sEf [Occ=Once1!] :: (Int, Int)) + (w1_sEg [Occ=Once1!] :: Int) -> + case w_sEf of { (ww1_sEj [Occ=Once1!], _ [Occ=Dead]) -> + case ww1_sEj of { GHC.Types.I# ww4_sEm [Occ=Once1] -> + case w1_sEg of { GHC.Types.I# ww6_sEs [Occ=Once1] -> + case Lib.$wfoo ww4_sEm ww6_sEs of ww7_sEw [Occ=Once1] + { __DEFAULT -> + GHC.Types.I# ww7_sEw } } } }}] foo - = \ (w_sHs :: (Int, Int)) (w1_sHt :: Int) -> - case w_sHs of { (ww1_sHw, ww2_sHB) -> - case ww1_sHw of { GHC.Types.I# ww4_sHz -> - case w1_sHt of { GHC.Types.I# ww6_sHF -> - case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ { __DEFAULT -> - GHC.Types.I# ww7_sHJ + = \ (w_sEf :: (Int, Int)) (w1_sEg :: Int) -> + case w_sEf of { (ww1_sEj, ww2_sEo) -> + case ww1_sEj of { GHC.Types.I# ww4_sEm -> + case w1_sEg of { GHC.Types.I# ww6_sEs -> + case Lib.$wfoo ww4_sEm ww6_sEs of ww7_sEw { __DEFAULT -> + GHC.Types.I# ww7_sEw } } } |