Given a function definition
data T = MkT Int Bool Char
f :: (a, b) -> Int -> T
f = \x y -> E
mkWwBodies _ f ['x::(a,b)','y::Int'] '(a,b)' ['1P(L,L)',
'1P(L)'] '1' returns
- The wrapper body context for the call to the worker function,
lacking only the Id for the worker function:
W[_] :: Id -> CoreExpr
W[work_fn] = \x y -> -- args of the wrapper (cloned_arg_vars)
case x of (a, b) -> -- unbox wrapper args (wrap_fn_str)
case y of I# n -> --
case <work_fn> a b n of -- call to the worker fun (call_work)
(# i, b, c #) -> MkT i b c -- rebox result (wrap_fn_cpr)
- The worker body context that wraps around its hole reboxing defns
for x and y, as well as returning CPR transit variables of the unboxed
MkT result in an unboxed tuple:
w[_] :: CoreExpr -> CoreExpr
w[fn_rhs] = \a b n -> -- args of the worker (work_lam_args)
let { y = I# n; x = (a, b) } in -- reboxing wrapper args (work_fn_str)
case <fn_rhs> x y of -- call to the original RHS (call_rhs)
MkT i b c -> (# i, b, c #) -- return CPR transit vars (work_fn_cpr)
NB: The wrap_rhs hole is to be filled with the original wrapper RHS
x y -> E. This is so that we can also use
w to
transform stable unfoldings, the lambda args of which may be different
than x and y.
- Id details for the worker function like demands on arguments and
its join arity.
All without looking at E (except for beta reduction, see Note [Join
points and beta-redexes]), which allows us to apply the same split to
function body and its unfolding(s) alike.