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!).