Note [Worker/wrapper arity and join points]
Consider
(join j x = \y. error "urk")
(in case v of )
( A -> j 3 ) x
( B -> j 4 )
( C -> \y. blah )
The entire thing is in a C(1,L) context, so we will analyse j's body, namely
\y. error "urk"
with demand C(C(1,L)). See `rhs_sd` in `dmdAnalRhsSig`. That will produce
a demand signature of <A><A>b: and indeed `j` diverges when given two arguments.
BUT we do /not/ want to worker/wrapper `j` with two arguments. Suppose we have
join j2 :: Int -> Int -> blah
j2 x = rhs
in ...(j2 3)...(j2 4)...
where j2's join-arity is 1, so calls to `j` will all have /one/ argument.
Suppose the entire expression is in a called context (like `j` above) and `j2`
gets the demand signature <1!P(L)><1!P(L)>, that is, strict in both arguments.
we worker/wrapper'd `j2` with two args we'd get
join $wj2 x# y# = let x = I# x#; y = I# y# in rhs
j2 x = \y. case x of I# x# -> case y of I# y# -> $wj2 x# y#
in ...(j2 3)...(j2 4)...
But now `$wj2`is no longer a join point. Boo.
Instead if we w/w at all, we want to do so only with /one/ argument:
join $wj2 x# = let x = I# x# in rhs
j2 x = case x of I# x# -> $wj2 x#
in ...(j2 3)...(j2 4)...
Now all is fine. BUT in `finaliseArgBoxities` we should trim y's boxity,
to reflect the fact tta we aren't going to unbox `y` at all.
Conclusion:
(1) The "worker/wrapper arity" of an Id is
* For non-join-points: idArity
* The join points: the join arity (Id part only of course)
This is the number of args we will use in worker/wrapper.
See `ww_arity` in `dmdAnalRhsSig`, and the function `workWrapArity`.
(2) A join point's demand-signature arity may exceed the Id's worker/wrapper
arity. See the `arity_ok` assertion in `mkWwBodies`.
(3) In `finaliseArgBoxities`, do trimBoxity on any argument demands beyond
the worker/wrapper arity.
(4) In WorkWrap.splitFun, make sure we split based on the worker/wrapper
arity (re)-computed by workWrapArity. References 0
This Note does not link to any other.
Referenced by 5
- GHC.Core.Opt.DmdAnal call site ×2
- Demand analysis for join points GHC.Core.Opt.DmdAnal
- GHC.Core.Opt.WorkWrap call site
- GHC.Core.Opt.WorkWrap.Utils call site