Wrappers inlined too late
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
module Bar where import Foo blam x = f 3 [1..x]
If we simply inline
blam, we get
foldr/build fusion. And that is exactly what happens if you compile
But what actually happens is
- When compiling
Foo, strictness analysis does worker/wrapper for
- The wrapper currently gets an aciviation of "active only in phase 0"; see
Note [Wrapper activation]in
foois 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
fmay 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.