[GHC] #7283: Specialise INLINE functions

GHC cvs-ghc at haskell.org
Mon Oct 1 01:13:21 CEST 2012


#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



More information about the Glasgow-haskell-bugs mailing list