
On 09/06/2011 12:43, Simon Peyton-Jones wrote:
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.
So there are a couple of reasons to want (b). First, it shifts the decision about whether to inline to the call site, where the user has more control (e.g. with -funfolding-use-threshold300). This came up during the work on the containers package, where there was a concern that overuse of INLINE was causing code bloat in clients. Second, (b) is useful in cases like this: g x = ... large ... f x = ... g x ... and you want f to be inlined (but not necessarily everywhere, only if it's useful). If you don't say INLINABLE, then g gets inlined into f's rhs (let's assume g is only used once), and f never gets inlined because it's too big. If you say INLINE, then f gets inlined everywhere, which might be overkill. INLINABLE is just right. Cheers, Simon
Simon
| -----Original Message----- | From: Johan Tibell [mailto:johan.tibell@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
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users