Fix a long-standing bug the float-out pass
authorsimonpj@microsoft.com <unknown>
Tue, 26 Oct 2010 11:15:47 +0000 (11:15 +0000)
committersimonpj@microsoft.com <unknown>
Tue, 26 Oct 2010 11:15:47 +0000 (11:15 +0000)
commitb284d3709e846c2dcdceb48901fe42ec75efb090
treeded0d213b3aeffa19941e669df59949e8382d1d8
parentd196d84a6a6fbd128da207c03b1c5f29fb24e6a4
Fix a long-standing bug the float-out pass

We were failing to float out a binding that could be floated,
because of a confusion in the Lam case of floatExpr.

In investigating this I also discoverd that there is really
no point at all in giving a different level to variables in
a binding group, so I've now given them all the same (in
SetLevels.lvlLamBndrs

The overall difference is quite minor in a nofib run:

        Program           Size    Allocs   Runtime   Elapsed
-------------------------------------------------------------
            Min          +0.0%     -8.5%    -28.4%    -28.7%
            Max          +0.0%     +0.7%     -0.7%     -1.1%
 Geometric Mean          +0.0%     -0.0%    -11.6%    -11.8%

I don't trust those runtimes, but smaller is good!  The 8.5%
improvement in allocation in fulsom, and seems real.  The
0.7% allocation increase only happens in programs with
very small allocation.  I tracked one down to a call of this form

  GHC.IO.Handle.Internals.mkDuplexHandle5
    = \ args -> GHC.IO.Handle.Internals.openTextEncoding1
                  mb_codec ha_type
                  (\mb_encoder mb_decoder -> blah)

With the new floater the argument of openTextEncoding1 becomes

     (let lvl = .. in \mb_encoder mb_decoder -> blah)

And rightly so.  However in fact this argument is a continuation
and hence is called once, so the floating is fruitless.

Roll on one-shot-function analysis (which I know how to do
but fail to get to!).
compiler/simplCore/FloatOut.lhs
compiler/simplCore/SetLevels.lhs