add INLINEABLE to maybe, either, bool

Austin Seipp austin at well-typed.com
Tue Sep 17 01:03:59 CEST 2013


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 well-typed.com> 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 <danburton.email at gmail.com> 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 gmail.com> wrote:
>>>
>>> Contrary to appearances, I fully agree. =)
>>>
>>>
>>> On Mon, Sep 16, 2013 at 4:12 PM, Austin Seipp <austin at well-typed.com>
>>> 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 gmail.com> 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 haskell.org
>>>> > http://www.haskell.org/mailman/listinfo/libraries
>>>> >
>>>>
>>>>
>>>>
>>>> --
>>>> Austin Seipp, Haskell Consultant
>>>> Well-Typed LLP, http://www.well-typed.com/
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> Libraries at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/libraries
>>>
>>>
>>>
>>> _______________________________________________
>>> Libraries mailing list
>>> Libraries at haskell.org
>>> http://www.haskell.org/mailman/listinfo/libraries
>>>
>>
>
>
>
> --
> Austin Seipp, Haskell Consultant
> Well-Typed LLP, http://www.well-typed.com/



-- 
Austin Seipp, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/



More information about the Libraries mailing list