Note [Worker/wrapper arity and join points]

GHC/Core/Opt/DmdAnal.hs:1276 compiler

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