• simonpj's avatar
    [project @ 2003-09-23 15:29:02 by simonpj] · 6d493299
    simonpj 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
    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.
FloatOut.lhs 14.4 KB