-
Simon Peyton Jones authored
-------------------------- 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.
6d493299