Looks great to me, thanks. I imagine you are proposing this as a preamble to 7.18.5.1? http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html#inline-... Simon | -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Simon Marlow | Sent: 26 September 2013 16:46 | To: Austin Seipp | Cc: Haskell Libraries | Subject: Re: add INLINEABLE to maybe, either, bool | | 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. | | <para> | GHC (with <option>-O</option>, as always) tries to inline | (or “unfold”) functions/values that are | “small enough,” 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" | />. | </para> | | <para> | 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. | </para> | | Cheers, | Simon | | | | 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@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@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@gmail.com> | wrote: | >>>> | >>>> Contrary to appearances, I fully agree. =) | >>>> | >>>> | >>>> On Mon, Sep 16, 2013 at 4:12 PM, Austin Seipp <austin@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@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@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@haskell.org | >>>>> http://www.haskell.org/mailman/listinfo/libraries | >>>> | >>>> | >>>> | >>>> _______________________________________________ | >>>> Libraries mailing list | >>>> Libraries@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@haskell.org | http://www.haskell.org/mailman/listinfo/libraries