Skip to content

CPR analysis worker returns values the wrapper could trivially construct itself

Consider GHC.Num.Natural.naturalNegate:

naturalNegate :: Natural -> Natural
{-# NOINLINE naturalNegate #-}
naturalNegate (NS 0##) = NS 0##
naturalNegate _        = raiseUnderflow

This will create the following WW split:

naturalNegate n = case $wnaturalNegate n of b -> NS b

$wnaturalNegate :: Natural -> Word#
{-# NOINLINE $wnaturalNegate #-}
$wnaturalNegate (NS 0##) = 0##
$wnaturalNegate _        = case raiseUnderflow of {}

but that 0## is an expression that is both cheap to evaluate and not free in any of the parameters of the function. We could just as well construct it in the wrapper:

naturalNegate n = case $wnaturalNegate n of () -> NS 0##

$wnaturalNegate :: Natural -> ()
{-# NOINLINE $wnaturalNegate #-}
$wnaturalNegate (NS 0##) = ()
$wnaturalNegate _        = case raiseUnderflow of {}

This transformation would be completely within reach for Nested CPR; the only question is whether we want it. Maybe we should only do this for literal expressions for code size concerns.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information