GHC: Ticket #7283: Specialise INLINE functions
http://ghc.haskell.org/trac/ghc/ticket/7283
<p>
Quick summary: At the moment, INLINE means inline a function if it is fully applied and <strong>don't use its unfolding</strong> otherwise. I think we might want to change this to INLINE a function if it is fully applied and <strong>treat it as to INLINABLE</strong> otherwise.
</p>
<p>
Here is a small example:
</p>
<pre class="wiki">module T where
f :: Num a => a -> a
{-# INLINE [1] f #-}
f = \x -> x+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
g :: Num a => a -> a
{-# INLINE [1] g #-}
g x = x+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2+2
h :: Num a => a -> a
{-# INLINABLE [1] h #-}
h x = x+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3+3
apply :: (a -> b) -> a -> b
{-# NOINLINE apply #-}
apply f x = f x
</pre><pre class="wiki">module U where
import T
ff :: Int -> Int -> Int
ff x y = apply f x + apply f y
gg :: Int -> Int -> Int
gg x y = apply g x + apply g y
hh :: Int -> Int -> Int
hh x y = apply h x + apply h y
</pre><p>
With -O2 -fno-cse (CSE does optimise this example but doesn't solve the problem of intermediate code bloat), GHC produces the following:
</p>
<ul><li>The RHS of <tt>f</tt> is duplicated since it is inlined twice - <strong>bad</strong>.
</li><li><tt>g</tt> is neither inlined nor specialised since it isn't fully applied - <strong>bad</strong>.
</li><li><tt>h</tt> is specialised but its RHS isn't duplicated - <strong>good</strong>.
</li></ul><p>
But of course, <tt>h</tt> isn't guaranteed to be inlined even if it is fully applied which, in the real-world examples I have in mind, is <strong>bad</strong>.
</p>
<p>
I think <tt>INLINE [n] f</tt> should mean that:
</p>
<ol><li><tt>f</tt> will always be inlined if it is fully applied,
</li><li><tt>f</tt> will be specialised when possible,
</li><li>specialisations of <tt>f</tt> will also be <tt>INLINE [n]</tt>.
</li></ol><p>
I don't think it's possible to achieve this effect at the moment. If we treated <tt>INLINE [n]</tt> as <tt>INLINABLE [n]</tt> until the function is fully applied, we would get exactly this, though, except for 3 which probably isn't too hard to implement.
</p>
<p>
Now, if I understand correctly, INLINABLE also means that GHC is free to inline the function if it wants but the function isn't treated as cheap. I think it would be fine if we did this for unsaturated <tt>INLINE</tt> functions rather than not inlining them under any circumstances. The original motivation for only inlining when fully applied was code bloat in DPH. But IIRC that only happened because INLINE functions were always cheap and so GHC was very keen to inline them even when they weren't saturated which wouldn't be the case with my proposal. We would have to check how this affects DPH and related libraries, though.
</p>
en-usGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/ticket/7283
Trac 1.0.1simonpjMon, 01 Oct 2012 21:58:33 GMTdifficulty set
http://ghc.haskell.org/trac/ghc/ticket/7283#comment:1
http://ghc.haskell.org/trac/ghc/ticket/7283#comment:1
<ul>
<li><strong>difficulty</strong>
set to <em>Unknown</em>
</li>
</ul>
<p>
Roman, your proposal sounds very plausible to me.
</p>
<p>
(I don't understand your last paragraph though.)
</p>
TicketrlTue, 02 Oct 2012 08:30:54 GMT
http://ghc.haskell.org/trac/ghc/ticket/7283#comment:2
http://ghc.haskell.org/trac/ghc/ticket/7283#comment:2
<p>
I'll try to rephrase the last paragraph. The problem is that this change will make GHC inline more since it will now be able (but not keen) to inline INLINE functions even if they aren't applied to enough arguments. The original reason for making INLINE respect arity was code bloat so we should be careful not to reintroduce this problem with this change. However, if INLINE functions that are not applied to enough arguments are treated exactly as INLINABLE then GHC won't try extra hard to inline them so perhaps we will be ok. This is different to what we had before the arity restriction on INLINE - back then, GHC would try extra hard to inline regardless of the number of arguments. So while we will inline more under my proposal, it will (hopefully) still be substantially less than in the bad old days.
</p>
TicketiglooFri, 12 Apr 2013 14:54:50 GMTmilestone set
http://ghc.haskell.org/trac/ghc/ticket/7283#comment:3
http://ghc.haskell.org/trac/ghc/ticket/7283#comment:3
<ul>
<li><strong>milestone</strong>
set to <em>7.8.1</em>
</li>
</ul>
Ticket