[project @ 2002-11-19 15:57:10 by simonpj]
authorsimonpj <unknown>
Tue, 19 Nov 2002 15:57:10 +0000 (15:57 +0000)
committersimonpj <unknown>
Tue, 19 Nov 2002 15:57:10 +0000 (15:57 +0000)
commit0316a9e603115e6d3f04bd03824a1ca9430b0f0f
treeb9e6ab281e572b47d4b694bb7610bca7358d850f
parent821d799485702aa76b393cecf3e2eb32381eb5df
[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.
ghc/compiler/simplCore/Simplify.lhs