[GHC] #9020: Massive blowup of code size on trivial program

#9020: Massive blowup of code size on trivial program ------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- 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. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------ Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Changes (by nomeata): * cc: mail@… (added) Comment: Did you also measure -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program
-------------------------------------+------------------------------------
Reporter: simonpj | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.8.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture: Unknown/Multiple
Type of failure: None/Unknown | Difficulty: Unknown
Test Case: | Blocked By:
Blocking: | Related Tickets:
-------------------------------------+------------------------------------
Comment (by Simon Peyton Jones

#9020: Massive blowup of code size on trivial program ----------------------------------------+---------------------------------- Reporter: simonpj | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Test Case: perf/compiler/T9020 | Difficulty: Unknown Blocking: | Blocked By: | Related Tickets: ----------------------------------------+---------------------------------- Changes (by simonpj): * status: new => closed * testcase: => perf/compiler/T9020 * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | perf/compiler/T9020 | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nomeata): I might have a different fix for this, that would also avoid implementing the strange heuristics in #10319: In T9020, the problem is not really that `return ()` is eta-expanded, but that it is eta-expaned in a phase where no inlining happens, namely in the gentle phase. If we do not eta-expand in this phase (by changing `simpl_gently` in `SimplCore`), we can revert to `old_arity = manifestArity` and this program still compiles quickly. Doesn’t that look like the cleaner solution? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | perf/compiler/T9020 | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by simonpj):
In T9020, the problem is not really that `return ()` is eta-expanded, but that it is eta-expanded in a phase where no inlining happens, namely in the gentle phase. If we do not eta-expand in this phase (by changing `simpl_gently` in `SimplCore`), we can revert to `old_arity = manifestArity` and this program still compiles quickly.
Aha. That sounds cool. I buy. * NB that I am (separately) wanting to make some inlining happen in the gentle phase too...So the no-eta thing should depend on sm_inline rather than on the phase. That makes the reasoning clearer too. * Rather than muttering about PAPs, perhaps e can simply switch off eta- expansion ''altogether'' under these conditions? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | perf/compiler/T9020 | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nomeata):
Rather than muttering about PAPs, perhaps we can simply switch off eta- expansion altogether under these conditions?
With "these conditions", do you mean "gentle phase" a.k.a. "sm_inline = False"? If so, then that is precisely what I am proposing: {{{ -- initial simplify: mk specialiser happy: minimum effort please simpl_gently = CoreDoSimplify max_iter (base_mode { sm_phase = InitialPhase , sm_names = ["Gentle"] , sm_rules = rules_on -- Note [RULEs enabled in SimplGently] , sm_inline = False , sm_case_case = False , sm_eta_expand = False}) -- This line was added -- Don't do case-of-case transformations. -- This makes full laziness work better }}} We still need to distinguish between `sm_inline` and `sm_eta_expand`, as the former is always on in the `base_mode`, while the second one depends on `Opt_DoLambdaEtaExpansion`. (Which means that this flag isn’t correctly named, as it affects all eta- expansion, not just lambda-eta-expansion.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | perf/compiler/T9020 | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nomeata): Here is some concrete code to talk about: Phab:D851 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | perf/compiler/T9020 | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by simonpj): * status: closed => new * resolution: fixed => Comment: Re-opening. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | perf/compiler/T9020 | Blocking: | Differential Revisions: Phab:D851 -------------------------------------+------------------------------------- Changes (by simonpj): * owner: => nomeata * differential: => Phab:D851 * milestone: => 7.12.1 Comment: Thanks for working on this, Joachim. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: 7.12.1 Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Compile-time | Test Case: performance bug | perf/compiler/T9020 Blocked By: | Blocking: Related Tickets: | Differential Revisions: Phab:D851 -------------------------------------+------------------------------------- Changes (by thomie): * failure: None/Unknown => Compile-time performance bug -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Inlining Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Compile-time | Test Case: performance bug | perf/compiler/T9020 Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D851 Wiki Page: | -------------------------------------+------------------------------------- Changes (by mpickering): * keywords: => Inlining -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:13 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Inlining Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Compile-time | Test Case: performance bug | perf/compiler/T9020 Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D851 Wiki Page: | -------------------------------------+------------------------------------- Comment (by dfeuer): What's it going to take to put this to bed? It sounds like comment:6 suggests there may still be something to be done despite the early inline patch? It's not clear to me just what. For the record, this test case no longer seems to be in the test suite, but compiling something similar dropped from 5.5s in 7.8 to 1s in 7.10 and 8.0 to 0.8s in HEAD. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:14 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9020: Massive blowup of code size on trivial program -------------------------------------+------------------------------------- Reporter: simonpj | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.2 Resolution: | Keywords: Inlining Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Compile-time | Test Case: performance bug | perf/compiler/T9020 Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D851 Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): If it's good in HEAD, let's add a regression test and declare victory. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9020#comment:15 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC