Demand signature of `lazy` is too conservative
When I write
module Lib where
import GHC.Exts
foo :: a -> a
foo a = lazy a
I expect to see a demand signature (with -O -ddump-dmd-signatures
) like <ML>
, i.e., used at most once (albeit lazily). Instead I see <L>
.
That is because the current wiring of lazy
does not specify any demand signature whatsoever, so it defaults to topSig
, which expands to <L>
.
This is easily fixed by specifying a demand signature in GHC.Types.Id.Make.
I'm a bit hesitant though, because CorePrep eliminates lazy x
entirely into x
. That might cause trouble, for example when we see
let x = expensive 42 in
let y = lazy x in
y + y
- Demand analysis concludes that
y
is used many times, butx
is only used at most once because of the apparent thunk. - Alas, CorePrep should eliminate
lazy x
tox
, at which point the trivial bindingy = x
is simply inlined! Nowx
is used many times. Yet the demand info onx
still says used once, so we will duplicate evaluation ofexpensive 42
.
So I'm wondering whether we should detect lazy x
as trivial iff x
is trivial (the same should be morally true of all the other CorePrep-inlined primops such as noinline
, runRW#
, dataToTag#
). Or simply not bother to fix this ticket.