Hi Max. Thanks much for passing on this info. Very encouraging news! - Conal
On Wed, Mar 10, 2010 at 8:41 AM, Max Bolingbroke <batterseapo...@hotmail.com > wrote: > This is my understanding: > > Old story (GHC 6.12.1 (?) and below): > 1) Function bodies are only optimised if they are not marked INLINE. > The assumption is that INLINE bodies will be inlined and then > optimised at the point where they are inlined. > 2) Unfoldings are exported in .hi files for functions if they are > nonrecursive and "small enough" or marked INLINE > > New story (GHC HEAD): > 1) Function bodies are optimised regardless of whether they are marked > INLINE or not. > 2) Unfoldings are exported in .hi files for functions if they are > nonrecursive and "small enough" or marked INLINE, but the unfolding > that is exported is the _unoptimised_ version! > - It is important to export the unoptimised version because the > optimisation may destroy information we would have relied upon in rule > matching. E.g. the optimised version of a list producer will not use > "build", but we need to be able to spot the "build" in rules to do > foldr/build fusion. > > The new story is much more robust - adding INLINE pragmas should be a > much safer thing to do now, because even if the function is not > inlined you will still get an optimised definition for that function. > > Other relevant points: > a) There is a new flag, -fexpose-all-unfoldings, in GHC HEAD. This > does what you want - compile vector-space with this flag on and > unfoldings for everything will show up in the .hi file, with no INLINE > annotations necessary. This was intended for supercompilers (such as > the one I'm working on :-) but you can probably use for this as well. > b) GHC already treats RULES differently for the purposes of inlining. > It is very eager to inline into the arguments of a function you have > RULES for, because doing so may let it spot extra chances for the rule > to fire. > > Hope that helps, > Max > > On 10 March 2010 16:23, Jake McArthur <jake.mcart...@gmail.com> wrote: > > Here's a transcript from a conversation I had with Conal on IRC. > > > > tl;dr: <conal> cross-module inlining is only possible because ghc > > stashes a definition in a .hi, iuuc. i'm suggesting that the stashed > > definition either (a) never include further inlinings, or (b) be > > augmented by such a definition. > > > > Full transcript: > > > > 11:23:10 <conal> jmcarthur: i'm wondering what to do about INLINE > > pragmas for vector-space and other libraries. i love optimizability > > and clean/elegant/terse code. and i don't know how to resolve that > > tension. > > 11:23:21 <jmcarthur> conal: yeah, me either. it's annoying > > 11:23:41 <jmcarthur> conal: a compiler feature to do it more > > succinctly would be nice, if we can come up with one > > 11:23:52 <conal> jmcarthur: i'm thinking exactly the same > > 11:24:04 <conal> jmcarthur: a ghc flag that does what you did manually > > 11:24:41 <jmcarthur> conal: yeah, but we still need to do better than > > inlining *all* functions. we need to be able to tell it we want it to > > inline all functions satisfying some predicate or something > > 11:25:07 <jmcarthur> like, there's no point in forcing to inline > > functions having absolutely nothing to do with vector, for example > > 11:25:18 <conal> jmcarthur: i wonder. ghc already has some > > heuristics. do we really want anything different/unusual? > > 11:25:26 <jmcarthur> then again, combinators that don't inline and get > > used in a vector function later might still be annoying > > 11:26:08 <conal> jmcarthur: maybe some kind of demand-driven mechanism > > 11:26:21 <jmcarthur> conal: that's what i was thinking would be best > > 11:26:28 <conal> jmcarthur: ie pull inlining rather than push them. > > or some combo. > > 11:27:21 <conal> jmcarthur: i don't think this issue is specific to > > either vector fusion or to the vector-space package. > > 11:27:28 <jmcarthur> conal: actually, this is about rewrite rules more > > than inlining > > 11:27:40 <jmcarthur> conal: maybe if we focus on the rewrite rules we > > can think of something nicer > > 11:27:46 <conal> jmcarthur: ah, yeah. > > 11:28:32 <conal> jmcarthur: have you talked with they ghc guys about > > this issue? i wonder what practice they'd advise for use with the > > current ghc > > 11:28:54 <jmcarthur> i have not > > 11:29:47 <conal> jmcarthur: how did the inlining/rewriting concern > > arise for vector fusion and the vector-space package? > > 11:30:16 <jmcarthur> conal: i assume you read the email i linked to? > > 11:30:27 <jmcarthur> this one: > > http://www.haskell.org/pipermail/haskell-cafe/2010-March/074153.html > > 11:30:34 <conal> jmcarthur: yes. i'l reread now. > > 11:31:03 <jmcarthur> conal: "in general, you have to add INLINE > > pragmas in such cases if you want to be sure your code fuses. A > > general-purpose mechanism for handling situations like this > > automatically would be great but we haven't found a good one so far." > > 11:31:14 <jmcarthur> i think the most relevant line > > 11:31:49 <conal> jmcarthur: thx. and the difficulty (with current > > ghc) is specifically cross-module, right? > > 11:32:00 <jmcarthur> conal: that is my understanding > > 11:32:10 <jmcarthur> but perhaps it is more complex > > 11:32:49 <conal> jmcarthur: if so, i wonder if ghc could be fixed to > > inline between modules according to the same heuristics as within a > > module. > > 11:34:36 <jmcarthur> conal: maybe. > > 11:35:34 <conal> jmcarthur: part of my discomfort is that i don't know > > whether the INLINE directives are more helpful or more harmful under > > all uses. if they were generally helpful, i imagine ghc would do it. > > 11:56:56 <jmcarthur> me too > > 11:57:46 <conal> jmcarthur: i just found that haskell-cafe thread and > > added a reply. > > 11:58:31 <conal> jmcarthur: hoping that don, roman, etc will have some > > ideas in addressing that discomfort. > > 12:09:58 <jmcarthur> conal: apparently the real trick is that GHC will > > not inline functions in a function that is annotated INLINE, meaning > > that rewrite rules can fire on the outermost rule before firing on > > inner ones > > 12:10:30 <jmcarthur> conal: i think it would be nice if we could come > > up with a way for rewrite rules to affect GHC's inliner > > 12:10:44 <conal> jmcarthur: yeah. maybe INLINE ought to be decomposed > > into two sub-meanings. > > 12:10:45 <jmcarthur> then it would only happen when necessary > > 12:11:17 <jmcarthur> well, the fact that it forces that function to be > > inlined is also good though > > 12:11:33 <jmcarthur> which is apparently important across module > boundaries > > 12:11:45 <conal> jmcarthur: maybe ghc could *never* inline functions > > into an inline body. and then do some caching to avoid redundant > > work. > > 12:12:00 <jmcarthur> perhaps. still leaves the cross-module inlining > > issue though > > 12:12:32 <jmcarthur> i suspect this is also architectural > > 12:12:44 <jmcarthur> ghc doesn't know if it will inline a function > > across a module boundary in advance > > 12:12:52 <jmcarthur> therefore it goes ahead and inlines into it > > 12:13:04 <jmcarthur> *inlines other functions into it > > 12:13:31 <conal> jmcarthur: i don't understand how module boundaries > > come into play > > 12:14:40 <jmcarthur> conal: my suspicion is that because ghc builds > > modules separately it can't know whether a function will be inlined in > > another module, so if it's not marked INLINE it feels free to inline > > other functions into it as it pleases > > 12:15:17 <jmcarthur> conal: but a function marked INLINE is clearly > > going to be inlined everywhere it's used, so ghc can go ahead and > > avoid inlining into it > > 12:17:07 <jmcarthur> conal: perhaps a way around it would be to avoid > > making inlining decisions about exported functions at all until link > > time > > 12:17:20 <jmcarthur> but that would stink a little > > 12:17:24 <conal> jmcarthur: maybe so. sounds like a place for > > improving ghc. it makes an invalid assumption: that a def not marked > > INLINE won't be inlined. > > 12:17:25 <conal> jmcarthur: instead, it could be prepared to inline > elsewhere. > > 12:17:25 <conal> jmcarthur: i'm confused though. ghc *is* prepared to > > inline elsewhere. > > 12:18:23 <jmcarthur> conal: well, it's not that ghc makes an invalid > > assumption, i think. it just doesn't take certain steps unless you > > tell it to explicitly > > 12:18:58 <conal> jmcarthur: the invalid assumption i mean is that it's > > not worth saving an inline-and-optimze-friendly def. > > 12:19:43 <conal> jmcarthur: cross-module inlining is only possible > > because ghc stashes a definition in a .hi, iuuc. i'm suggesting that > > the stashed definition either (a) never include further inlinings, or > > (b) be augmented by such a definition. > > 12:20:07 <jmcarthur> conal: i agree with that suggestion, if our > > understanding of how it works is correct > > 12:20:54 <conal> jmcarthur: okay. let's take this understanding into > > the haskell-cafe discussion and see what evolves. okay? > > > > - Jake > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe@haskell.org > > http://www.haskell.org/mailman/listinfo/haskell-cafe > > > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe