The role of INLINE and INLINABLE on recursive functions
Simon PeytonJones
simonpj at microsoft.com
Thu Jun 9 13:43:31 CEST 2011
INLINE:
 no effect for a recursive function
 for a nonrecursive 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 typeclass overloaded functions (including recursive ones)
 makes them autospecialise at call sites in other modules
 allows SPECIALISE pragmas for them in other modules
b) For nonrecursive functions, makes GHC willing, but not supereager,
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 PeytonJones
 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 toplevel
 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 Glasgowhaskellusers
mailing list