Massive blowup of code size on trivial program
The test simplCore/should_compile/simpl015
was leading to massive compile times. This is weird: it looks like:
main = do { return ()
; return ()
... hundreds more times ...
; return () }
It turns out that the cause was over-eager eta-expansion. Each return ()
gives a top-level PAP thus
lvl17 :: IO ()
lvl17 = returnIO ()
But these definitions are then eta-expanded, thus:
lvl17 = ((\eta. returnIO () |> sym g) eta) |> g
where g :: State# RealWorld -> (# State# RealWorld, () #)
~
IO ()
Now in general it makes sense to eta-expand through newtypes (as is done here), because it exposes more lambadas. But it really doesn't make sense to eta-expand a PAP like this.
Fortunately the fix is easy: use exprArity
rather than manifestArity
in SimplUtils.tryEtaExpandRhs
.
The effect on simpl015
is dramatic: compiler allocation drops from 6.6G to 812M; and residency drops from 1.8G to 45M.
Trac metadata
Trac field | Value |
---|---|
Version | 7.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |