[project @ 2002-11-19 15:57:10 by simonpj]
-----------------------------------------------
Fix a terrible and long-standing strictness bug
-----------------------------------------------
MERGE TO STABLE
Simplify.simplifyArg was floating out lets from a lazy argument.
Not only is this unprofitable, but it can actually be wrong it
the floated let has a strict-demand flag on it. (Simplify.simplLazyBind
goes to some trouble to check for this case.)
The situation is this
lazy_fn (let v = <expensive> in str_fn v v)
Here, the strictness analyser may put a 'demanded' flag on
v, and if is is *then* floated we'll get
let v* = <expensive>
in
lazy_fn (str_fn v v)
and then <expensive> will always be evaluated.
This bug has been in the compiler at least a year (since Sept 01), but
in fact it's quite hard to make a test case for it, because the same
bug meant that the let was floated out *before* strictness analysis
giving
let v = <expensive>
in
lazy_fn (str_fn v v)
and now v won't get a strict-demand flag. So it's only if the let
shows up (by inlining) after strictness analysis but not before.