diff options
Diffstat (limited to 'testsuite/tests/stranal/sigs/T19871.hs')
-rw-r--r-- | testsuite/tests/stranal/sigs/T19871.hs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/testsuite/tests/stranal/sigs/T19871.hs b/testsuite/tests/stranal/sigs/T19871.hs new file mode 100644 index 0000000000..564a055df4 --- /dev/null +++ b/testsuite/tests/stranal/sigs/T19871.hs @@ -0,0 +1,70 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +-- | From Note [Boxity Analysis] and related Notes +module T19871 where + +data Huge + = Huge + { f1 :: Bool + , f2 :: Bool + , f3 :: Bool + , f4 :: Bool + , f5 :: Bool + , f6 :: Bool + , f7 :: Bool + , f8 :: Bool + , f9 :: Bool + , f10 :: Bool + , f11 :: Bool + , f12 :: Bool } + +-- | Should not unbox Huge +ann :: Huge -> (Bool, Huge) +ann h@(Huge{f1=True}) = (False, h) +ann h = (True, h) +{-# NOINLINE ann #-} + +-- A few examples demonstrating the lubBoxity = unboxedWins tradeoff + +-- | Should unbox 'z'. +-- We won't with `lubBoxity = boxedWins`. +-- We will with `lubBoxity = unboxedWins`. +sumIO :: Int -> Int -> IO Int +sumIO 0 !z = return z +sumIO n !z = sumIO (n-1) (z+n) +{-# NOINLINE sumIO #-} + +-- | Should /not/ unbox 'h'. +-- We won't with `lubBoxity = boxedWins`. +-- We will with `lubBoxity = unboxedWins`. +update :: Huge -> (Bool, Huge) +update h@(Huge{f1=True}) = (False, h{f1=False}) +update h = (True, h) +{-# NOINLINE update #-} + +-- | Should /not/ unbox 'h'. +-- We won't with `lubBoxity = boxedWins`. +-- We will with `lubBoxity = unboxedWins`. +guarded :: (Huge -> Bool) -> Huge -> Bool +guarded g h | f1 h = True + | otherwise = g h +{-# NOINLINE guarded #-} + +-- | Should /not/ unbox 'h'. +-- We won't with `lubBoxity = boxedWins`. +-- We will with `lubBoxity = unboxedWins`. +-- +-- This example also demonstrates the usefulness of carrying a Boxity in Poly. +-- Most absent sub-demands here should be considered Boxed (and of course we +-- also need Unboxed absent Poly). See Note [Boxity in Poly]. +absent :: Huge -> Int +absent h = if f1 h || f2 h then g h else 2 + where + g :: a -> Int + g a = a `seq` f a True + {-# NOINLINE g #-} + f :: a -> Bool -> Int + f _ True = 1 + f a False = a `seq` 2 + {-# NOINLINE f #-} +{-# NOINLINE absent #-} |