The role of INLINE and INLINABLE on recursive functions

Simon Peyton-Jones simonpj at
Thu Jun 9 13:43:31 CEST 2011

- 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

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.


| -----Original Message-----
| From: Johan Tibell [mailto:johan.tibell at]
| 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