The role of INLINE and INLINABLE on recursive functions
Simon Peyton-Jones
simonpj at microsoft.com
Thu Jun 9 13:43:31 CEST 2011
INLINE:
- no effect for a recursive function
- for a non-recursive function, always inline a call that
(a) is applied to as many args as the LHS of the defn
(b) has some interesting context. Ie (\y x-> f x y) doesn't
inline f
INLINEABLE
a) For type-class overloaded functions (including recursive ones)
- makes them auto-specialise at call sites in other modules
- allows SPECIALISE pragmas for them in other modules
b) For non-recursive functions, makes GHC willing, but not super-eager,
to inline at call sites. Ie just use GHC's usual inlining rules.
The difference from not having the pragma is that the *original*
RHS is inlined (if GHC decides to) rather than the optimised RHS.
Does that help? The dual role of INLINEABLE is a bit confusing. And the utility of (b) isn't clear to me.
Simon
| -----Original Message-----
| From: Johan Tibell [mailto:johan.tibell at gmail.com]
| Sent: 09 June 2011 12:06
| To: Simon Peyton-Jones
| Subject: The role of INLINE and INLINABLE on recursive functions
|
| Hi,
|
| This comment on Trac got me curious:
|
| "Ok, we looked at this, and it turns out that 6.12.3 desugars `forever`
| differently: in 6.12, a local recursive `let` was introduced, which meant
| that `forever` could be inlined (and hence specialised) at every call
| site, whereas in 7.0 the desugarer leaves the function as a top-level
| recursive function which cannot be inlined.
|
| The solution is to add an `INLINABLE` pragma for `forever`, which will
| allow it to be specialised at a call site."
|
| What's the meaning of INLINE or INLINABLE on a recursive function?
| Normally we don't inline recursive functions (when would we stop
| inlining?) so it's unclear to me what the meaning of the pragmas would
| be in this cases. I know that INLINABLE on a recursive function that
| takes a type class dictionary leads to call site specialization of
| that function (but not "inlining").
|
| People often use this transformation to get recursive functions inlined:
|
| f = ... f ...
|
| f_transformed = go
| where go = ... go ...
| {-# INLINE f_transformed #-}
|
| Could we get the same result by just adding an INLINE pragma to the original f?
|
| Cheers,
| Johan
More information about the Glasgow-haskell-users
mailing list