too much let-floating
simonpj at microsoft.com
Tue Jun 5 04:14:06 EDT 2007
| No, I don't want to duplicate. But in my example the let var was only
| used once, so there was no sharing problem.
Not so in general -- floating outside a lambda that is called many times can dramatically increase sharing.
You're right that all you want is to *forgo* an optimisation; but I want to avoid people complaining about lost optimisations!
| In my original example, once we get to a later phase of compilation, the
| let bound thing does get inlined again. Once the bind and write
| functions get inlined, lots of case expressions appear and then it
| becomes obvious that it'd be beneficial to inline, and ghc does so. And
Hmm. Indeed, looking at it:
lvl_s198 = write 1 (pokeWord8 0)
I believe that there are no redexes there, correct? So we are gaining no sharing of work. GHC is simply avoiding an allocation, by floating to the top level, rather than actually avoiding work.
Is that always so in the cases you are bothered about? That is, the annoying floating is saving allocation but not work? And GHC can see that? If so, perhaps we can make the first run of FloatOut not do allocation-saving. There's a second run later I think.
You could have a go at this if you like. Look at SetLevels.lhs line 400. I think you might try something like replacing 'True' with:
floatConsts env || not (exprIsCheap expr)
The 'floatConsts' flag is False for the first run of FloatOut but True for the second.
| So how about the idea of taking the rule pattern into account when
| deciding to let-float
That could be the next thing to try. I used to look at LHSs etc, but decided that it was not robust enough.
More information about the Glasgow-haskell-users