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
yis used many times, butxis only used at most once because of the apparent thunk. - Alas, CorePrep should eliminate
lazy xtox, at which point the trivial bindingy = xis simply inlined! Nowxis used many times. Yet the demand info onxstill 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.
Edited by Sebastian Graf