#7283: Specialise INLINE functions
-+--
Reporter: rl | Owner:
Type: feature request | Status: new
Priority: normal | Component: Compiler
Version: 7.7 | Keywords:
Os: Unknown/Multiple | Architecture: Unknown/Multiple
Failure: Runtime performance bug | Testcase:
Blockedby: | Blocking:
Related: |
-+--
Quick summary: At the moment, INLINE means inline a function if it is
fully applied and '''don't use its unfolding''' otherwise. I think we
might want to change this to INLINE a function if it is fully applied and
'''treat it as to INLINABLE''' otherwise.
Here is a small example:
{{{
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
}}}
{{{
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
}}}
With -O2 -fno-cse (CSE does optimise this example but doesn't solve the
problem of intermediate code bloat), GHC produces the following:
* The RHS of `f` is duplicated since it is inlined twice - '''bad'''.
* `g` is neither inlined nor specialised since it isn't fully applied -
'''bad'''.
* `h` is specialised but its RHS isn't duplicated - '''good'''.
But of course, `h` isn't guaranteed to be inlined even if it is fully
applied which, in the real-world examples I have in mind, is '''bad'''.
I think `INLINE [n] f` should mean that:
1. `f` will always be inlined if it is fully applied,
2. `f` will be specialised when possible,
3. specialisations of `f` will also be `INLINE [n]`.
I don't think it's possible to achieve this effect at the moment. If we
treated `INLINE [n]` as `INLINABLE [n]` until the function is fully
applied, we would get exactly this, though, except for 3 which probably
isn't too hard to implement.
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 `INLINE` 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.
--
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/7283
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler
___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs