[project @ 2003-09-23 15:29:02 by simonpj]
authorsimonpj <unknown>
Tue, 23 Sep 2003 15:29:02 +0000 (15:29 +0000)
committersimonpj <unknown>
Tue, 23 Sep 2003 15:29:02 +0000 (15:29 +0000)
commit6d4932994d5a99d0ec7ea707e213b68328fa68a6
tree5cd174f71767ee4987e9008cac445d5aefaf1913
parent6c4a98d3df5a8183ac7bfb71c8eeeaf2972b50e5
[project @ 2003-09-23 15:29:02 by simonpj]
--------------------------
         Much grunting about let-floating
   --------------------------

We want to avoid putting bindings between the '=' of a defn and a '\':
let { f = let ... in \y-> ... } in ...

Reason: float-in often follows float-out, and it may then add yte
more bindings there, some of which may be strict.  But f may by
not be marked as not-demanded (for other reasons: see the call to
zapDemandInfo in Simplify.completeLazyBind); and now the strict binding
may not be able to float out again.  (Well, it triggers the ASSERT in
simplLazyBind.)

So this commit adds FloatOut.floatNonRecRhs (to complement floatRhs) which
is a big more vigorous about floating out.

But that in turn showed up a pile of gore to do with unlifted bindings.
We can't have them showing up at top level.  After thrashing in the swamp
for a while, I eventually arranged that
let x# = e in b
(where x# has an unlifted type) is treated exactly like
case e of x# -> b
That is, it is never floated.  Yes, we lose opportunities to float some
(very cheap!  unlifted let-bindings are always cheap) out of a lambda,
but we're missing much bigger opportunities already.  For example:
\x -> f (h y)

where h :: Int -> Int# is expensive. We'd like to float the (h y) outside
the \x, but we don't because it's unboxed.  Possible solution: box it.
Anyway, that's for the future.
ghc/compiler/simplCore/FloatOut.lhs
ghc/compiler/simplCore/SetLevels.lhs