
#15056: Wrappers inlined too late -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.2 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Consider these two modules {{{ module Foo where test :: Int -> Bool test 0 = True test n = test (n-1) foo :: Foldable t => Int -> t Int -> Int foo n xs | test n = foldr (+) n xs | otherwise = n+7 }}} and {{{ module Bar where import Foo blam x = f 3 [1..x] }}} If we simply inline `foo` into `blam`, we get `foldr/build` fusion. And that is exactly what happens if you compile `Foo` with `-fno-strictness`. But what actually happens is * When compiling `Foo`, strictness analysis does worker/wrapper for `foo`. * The wrapper currently gets an aciviation of "active only in phase 0"; see `Note [Wrapper activation]` in `WorkWrap`. * So `foo` is ultimately inlined (actually its worker is inlined too) but too late for fusion to take place. This is bad: optimising `Foo` makes the overall runtime increase. I have seen other examples of this. The general pattern is: * Without worker/wrapper, a function `f` may inline, which exposes opportunities for functions in its body to participate in rule rewrites * With worker/wrapper, no inlining happens until phase 0; and that is too late for the rules to fire. Obvious thought: allow wrappers from strictness analysis to inline earlier. I'll try that. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15056 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler