Note [No lazy, Unboxed demands in demand signature]
Consider T19407:
data Huge = Huge Bool () ... () -- think: DynFlags
data T = T { h :: Huge, n :: Int }
f t@(T h _) = g h t
g (H b _ ... _) t = if b then 1 else n t
The body of `g` puts (approx.) demand `L!P(A,1)` on `t`. But we better
not put that demand in `g`'s demand signature, because worker/wrapper will not
in general unbox a lazy-and-unboxed demand like `L!P(..)`.
(The exception are known-to-be-evaluated arguments like strict fields,
see Note [Unboxing evaluated arguments].)
The program above is an example where spreading misinformed boxity through the
signature is particularly egregious. If we give `g` that signature, then `f`
puts demand `S!P(1!P(1L,A,..),ML)` on `t`. Now we will unbox `t` in `f` it and
we get
f (T (H b _ ... _) n) = $wf b n
$wf b n = $wg b (T (H b x ... x) n)
$wg = ...
Massive reboxing in `$wf`! Solution: Trim boxity on lazy demands in
'trimBoxity', modulo Note [Unboxing evaluated arguments]. References 1
- Unboxing evaluated arguments GHC.Core.Opt.DmdAnal
Referenced by 4
- Boxity for bottoming functions GHC.Core.Opt.DmdAnal
- Finalising boxity for demand signatures GHC.Core.Opt.DmdAnal
- GHC.Core.Opt.DmdAnal call site
- GHC.Types.Demand call site