WW for constructed products should not wrap an unboxed 1-tuple around evaluated binders/stuff that terminates rapidly
Consider
data T = T (Int, Int)
f :: T -> T
f t@(T p) = p `seq` t
{-# NOINLINE f #-}
For the better or the worse, we give f
the CPR property (which is not up for discussion in this ticket) and WW to
$wf :: (Int, Int) -> (# (Int, Int) #)
$wf t = case t of t' { (x, y) -> (# t' #) }
f (T p) = case $wf p of { (# p' #) -> T p' }
The (# #)
wrapping is unnecessary, since t'
is already evaluated ("unlifted"). There alraedy is a special case in WorkWrap.Utils.mkWWcpr_help
for the singleton, unlifted result type case, but it doesn't detect t'
as unlifted, as operates purely by type. It appears that the function doesn't even have access to the expression it will wrap, and even if it had it's not easy to see how it could do the necessary analysis pre-simplication.
But with Nested CPR, we have the necessary termination info available! In particular, we would see that evaluation of t'
terminates rapidly (it's a case binder) and would see so in the Cpr
*c1(#)
(note the #
) for f
. This enables mkWWcpr_help
to safely drop the (# #)
wrapping.