add INLINEABLE to maybe, either, bool

Simon Marlow marlowsd at
Thu Sep 26 17:45:55 CEST 2013

I read this discussion and thought that one small thing we could do is 
to clarify the documentation for INLINE a bit.  Here's what I came up 
with; comments welcome.  I'll commit this if there are no objections.

           GHC (with <option>-O</option>, as always) tries to inline
           (or &ldquo;unfold&rdquo;) functions/values that are
           &ldquo;small enough,&rdquo; thus avoiding the call overhead
           and possibly exposing other more-wonderful optimisations.
           GHC has a set of heuristics, tuned over a long period of
           time using many benchmarks, that decide when it is
           beneficial to inline a function at its call site.  The
           heuristics are designed to inline functions when it appears
           to be beneficial to do so, but without incurring excessive
           code bloat.  If a function looks too big, it won't be
           inlined, and functions larger than a certain size will not
           even have their definition exported in the interface file.
           Some of the thresholds that govern these heuristic decisions
           can be changed using flags, see <xref linkend="options-f"

           Normally GHC will do a reasonable job of deciding by itself
           when it is a good idea to inline a function.  However,
           sometimes you might want to override the default behaviour.
           For exmaple, if you have a key function that is important to
           inline because it leads to further optimisations, but GHC
           judges it to be too big to inline.


On 16/09/2013 19:03, Austin Seipp wrote:
> In light of some recent conversations with others and self-review, I
> realize my prior messages may have been too strong, come off as
> hostile, or outright combative.
> I'd like to publicly apologize for that: I'm sorry to ruffle feathers.
> (As a GHC developer, what seems 'obvious' to me is much different than
> most people, I realize.)
> Now, in light of some discussions I had on IRC, there *are* things we
> can do here, and I'd like to lightly recap my position and some other
> points. To wit:
>   * I think it is bad to overuse things like INLINE, and I believe it
> encourages people to not understand the implications of what the
> compiler is doing (all programmers generally must have some intuition
> and control over their programs, and how they run.)
>   * Using the INLINE hammer everywhere makes it *incredibly* difficult
> to see where GHC deficiencies are, and that's not what we want - it
> hurts our ability to have informed decisions and examples. I also find
> it slightly disheartening that many people don't think GHC can handle
> cases like this.
>   * But Haskell is a language where inlining may not make a
> constant-factor difference, but *orders of magnitude difference*.
> vector-algorithms is a good example of this, and I'm not sure anyone
> knows how to 'fix it' so it doesn't have to INLINE literally
> everything. We're talking 10 orders of magnitude difference, if I
> remember my conversations with Dan/Edward correctly. lens is a lesser
> example: there are cases where GHC won't inline due to fear of work
> duplication or other unusual cases, but we can tackle these in GHC in
> some cases (and have.)
>   * We tend to be quite sensitive to performance matters as a community, I feel.
>   * And sometimes, things are hard. Even for people like Simon,
> 'fixing' bad inliner behavior can be a monstrous task, and INLINE is
> certainly a way to help the compiler when its hands are tied.
> Ultimately, nobody is wrong here. But we have options, and two of them
> people brought up are good ones I think.
>   1.) Perhaps GHC should have a flag to warn you if you use
> INLINE/INLINEABLE on a definition that the inliner would have dealt
> with anyway. This should not be on by default with -Wall. But it would
> give us a useful tool to examine our assumptions more easily in a lot
> of cases.
>   2.) GHC does have a testsuite with many performance-related tests,
> and tests that check the Core. We could easily add a test that checked
> the core output of bool, maybe, and either (and other functions, as
> time may go on.) This is much easier and probably more robust than
> trying to contrive an example of what the performance difference might
> be.
> Personally, I am way more interested in #1, as opposed to #2 (a
> failure to inline something so small would quickly be noticed -
> because lots of things probably won't inline at that point and our
> tests will fail!) However, I believe both of these are relatively
> easy, and quite feasible to implement.
> Unfortunately, I have about 10,000,000 things on my plate with the
> upcoming release. So I'm afraid I don't have time to do these myself.
> So, patches welcome! However, I am more than willing to help people
> get their feet wet in doing the work. You can email me (same email I'm
> using now,) or contact me on IRC (freenode, nick 'thoughtpolice') if
> you prefer more real time communication. I'll help you to the best of
> my abilities if you'd like to give it a go.
> On Mon, Sep 16, 2013 at 4:56 PM, Austin Seipp <austin at> wrote:
>> A serious question: if you don't even trust GHC to inline 'bool',
>> 'maybe' or 'either', given their triviality, do you trust it to ever
>> inline anything at all? I'm being completely honest here.
>> It still ignores the question of *why* the inliner is failing to do
>> what you want. If the type inferencer fails to infer the type of an
>> utterly trivial function - let's again say 'bool :: a -> a -> Bool ->
>> a', as it's type is about as trivial as it's definition - it is almost
>> certainly broken. By the same token, GHC not inlining 'bool' under -O
>> would almost certainly be a bug too, in my eyes. The definition is
>> trivial to the point where we should not ask "what if it doesn't
>> inline" - we should figure out WHY it does not do so. Maybe INLINE
>> would be a justified way of fixing it, but in this case it's just
>> unnecessary and has been verified as such.
>> By the same token, we also don't encourage people to wildly put `seq`
>> everywhere, or make everything on earth strict just because it makes
>> them feel good.
>> A compiler must work on a broad range of programs for a broad range of
>> use cases. There are certainly some cases that the compiler is *not*
>> tuned for. In some of these cases, we work to make them more
>> efficient. We patch the compiler to make it better where-ever
>> possible. But this case? This is nothing but a premature optimization
>> in my eyes - and one that even people like Edward or myself are guilty
>> of, for sure.* And I am repenting by rejecting the "INLINE school of
>> thought" (or INLINE school of hammers, as it were.)
>> If you want to make the argument that 'bool' - or something else even
>> - should be INLINE, by all means do so. But if you're going to do so
>> without any empirical cases, or examples of why it should be so
>> (especially when we have already checked the interface files,) and
>> just say it lets you sleep better at night? I simply do not buy it.
>> On Mon, Sep 16, 2013 at 3:59 PM, Dan Burton < at> wrote:
>>> I'm wary of "let's not mark it as INLINE because we want the compiler to
>>> automagically inline it for us." This seems like saying we should not have
>>> type signatures, because we want the type inferencer to figure it out for
>>> us. (If you want to test the auto-inliner's wisdom, then just add a setting
>>> that ignores INLINE pragmas and see if it inlines the same thing that humans
>>> do?)
>>> I don't really care how it's accomplished, but I do think that we should
>>> make sure that maybe, either, and bool are inlined, and the most obvious way
>>> to accomplish this is to directly mark them INLINE, is it not?
>>> -- Dan Burton
>>> On Mon, Sep 16, 2013 at 1:33 PM, Edward Kmett <ekmett at> wrote:
>>>> Contrary to appearances, I fully agree. =)
>>>> On Mon, Sep 16, 2013 at 4:12 PM, Austin Seipp <austin at>
>>>> wrote:
>>>>> I'm strongly opposed to this.
>>>>> Being INLINE happy is not a good thing, it is a bad thing. More often
>>>>> than not, I see people stuffing INLINE all over the place for things
>>>>> that would trivially be unfolded and put in the interface file anyway.
>>>>> This is bad, and it teaches people to just use the INLINE hammer
>>>>> everywhere instead of understanding the actual implications of what
>>>>> the inliner does. It also makes it impossible to actually observe how
>>>>> the inliner behaves and see where it needs tuning: if we just mark
>>>>> everything INLINE, we might as well not have it and make it
>>>>> unconditional.
>>>>> There are some particular cases where GHC is hesitant to inline small
>>>>> things if it would lead to work duplication, or where the inliner
>>>>> behavior is tweaked and you may want to force it across multiple
>>>>> versions to be sure (lens is a good example of this.) But this is far
>>>>> more rare, and this case is not that. In particular, Joachim checked
>>>>> the 'bool' commit. As expected, the unfolding for bool was put into
>>>>> the interface file for Data.Bool, meaning if you use -O (or just -O0
>>>>> -fno-ignore-interface-pragmas,) it should be inlined at call sites
>>>>> appropriately when it is used.
>>>>> If we're going to INLINE things, we need to make sure it actually has
>>>>> an empirical benefit, by looking at the core, and seeing where the
>>>>> inliner is failing. Not just attach it to things because it seems like
>>>>> a good idea. This also helps drive feedback into the inliner so we can
>>>>> see where it fails.
>>>>> On Mon, Sep 16, 2013 at 2:59 PM, Carter Schonwald
>>>>> <carter.schonwald at> wrote:
>>>>>> Its come to my attention that maybe, either, and its new sibling bool,
>>>>>> all
>>>>>> lack the
>>>>>> INLINEABLE attribute, or its more aggressive sibling INLINE
>>>>>> this seems like one of those operations where inlining in client use
>>>>>> sites
>>>>>> is a good option to have, and currently not possible!
>>>>>> theres probably other stuff that would benefit from an INLINEABLE
>>>>>> pragma in
>>>>>> base,
>>>>>> but this is an obvious, simple, "easy win" that I noticed when Oliver's
>>>>>> patch got merged into base.
>>>>>> Thoughts?
>>>>>> Time scale: sometime this week? (ghc 7.8 merge window is landing!)
>>>>>> cheers
>>>>>> _______________________________________________
>>>>>> Libraries mailing list
>>>>>> Libraries at
>>>>> --
>>>>> Austin Seipp, Haskell Consultant
>>>>> Well-Typed LLP,
>>>>> _______________________________________________
>>>>> Libraries mailing list
>>>>> Libraries at
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> Libraries at
>> --
>> Austin Seipp, Haskell Consultant
>> Well-Typed LLP,

More information about the Libraries mailing list