
#9349: excessive inlining with -fpre-inlining -------------------------------------+------------------------------------- Reporter: rwbarton | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: Runtime | Blocked By: performance bug | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): First, I believe that `-fno-state-hack` would be better than `-fno-pre- inlining`, because it's less drastic. You might want to check that it does indeed cure the problem. I understand why NOINLINE is not working. The work is being duplicated by float-in, not by inlining! Consider {{{ let {-# NOINLINE rangeMap #-} rangeMap = expensive in replicateM_ n (\s -> ...rangeMap...) }}} The float-in pass picks up let-bindings and floats them inward as far as possible, but not inside a lambda (unless it's a one-shot lambda). So float-in does this: {{{ replicateM n (\s -> ....(let rangeMap = expensive in rangeMap)...) ... }}} The real culprit is, of course that the `\s` isn't one-shot. But that's why NOINLINE doesn't help. I suppose we could say that float-in should not move a NOINLINE binding; or at least should not move it in past a lambda, whether one-shot or not. I suppose that might be a finer-grained way of allowing you to fix the thing, a little less brutal than `-fno-state-hack`. The other thing that occurs to me is that for this `\s` we can ''see'' (via cardinality analysis) that it is called more than once. So maybe that can override the state-hack nonsense. Needs more looking at. Anyway I thought I'd write down what is going on. Is this a show-stopper for anyone? Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9349#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler