diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2020-11-23 11:42:04 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-12-12 04:45:09 -0500 |
commit | 5bd71bfd3a410ff2edcd29306a9824d60857f9fd (patch) | |
tree | 978d1366447bc4c97d2df573c548f533aa99775d /testsuite/tests/stranal | |
parent | 4af6126d1758d5e365cadf032e34c99489f13dee (diff) | |
download | haskell-5bd71bfd3a410ff2edcd29306a9824d60857f9fd.tar.gz |
DmdAnal: Annotate top-level function bindings with demands (#18894)
It's useful to annotate a non-exported top-level function like `g` in
```hs
module Lib (h) where
g :: Int -> Int -> (Int,Int)
g m 1 = (m, 0)
g m n = (2 * m, 2 `div` n)
{-# NOINLINE g #-}
h :: Int -> Int
h 1 = 0
h m
| odd m = snd (g m 2)
| otherwise = uncurry (+) (g 2 m)
```
with its demand `UCU(CS(P(1P(U),SP(U))`, which tells us that whenever `g` was
called, the second component of the returned pair was evaluated strictly.
Since #18903 we do so for local functions, where we can see all calls.
For top-level functions, we can assume that all *exported* functions are
demanded according to `topDmd` and thus get sound demands for
non-exported top-level functions.
The demand on `g` is crucial information for Nested CPR, which may the
go on and unbox `g` for the second pair component. That is true even if
that pair component may diverge, as is the case for the call site `g 13
0`, which throws a div-by-zero exception.
In `T18894b`, you can even see the new demand annotation enabling us to
eta-expand a function that we wouldn't be able to eta-expand without
Call Arity.
We only track bindings of function type in order not to risk huge compile-time
regressions, see `isInterestingTopLevelFn`.
There was a CoreLint check that rejected strict demand annotations on
recursive or top-level bindings, which seems completely unjustified.
All the cases I investigated were fine, so I removed it.
Fixes #18894.
Diffstat (limited to 'testsuite/tests/stranal')
-rw-r--r-- | testsuite/tests/stranal/should_compile/T18894.hs | 28 | ||||
-rw-r--r-- | testsuite/tests/stranal/should_compile/T18894.stderr | 404 | ||||
-rw-r--r-- | testsuite/tests/stranal/should_compile/T18894b.hs | 20 | ||||
-rw-r--r-- | testsuite/tests/stranal/should_compile/T18894b.stderr | 187 | ||||
-rw-r--r-- | testsuite/tests/stranal/should_compile/all.T | 4 |
5 files changed, 643 insertions, 0 deletions
diff --git a/testsuite/tests/stranal/should_compile/T18894.hs b/testsuite/tests/stranal/should_compile/T18894.hs new file mode 100644 index 0000000000..6b91d0e3b5 --- /dev/null +++ b/testsuite/tests/stranal/should_compile/T18894.hs @@ -0,0 +1,28 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} + +-- | The point of this test is that @g*@ get's a demand that says +-- "whenever @g*@ is called, the second component of the pair is evaluated strictly". +module T18894 (h1, h2) where + +g1 :: Int -> (Int,Int) +g1 1 = (15, 0) +g1 n = (2 * n, 2 `div` n) +{-# NOINLINE g1 #-} + +h1 :: Int -> Int +h1 1 = 0 +-- Sadly, the @g1 2@ subexpression will be floated to top-level, where we +-- don't see the specific demand placed on it by @snd@. Tracked in #19001. +h1 2 = snd (g1 2) +h1 m = uncurry (+) (g1 m) + +g2 :: Int -> Int -> (Int,Int) +g2 m 1 = (m, 0) +g2 m n = (2 * m, 2 `div` n) +{-# NOINLINE g2 #-} + +h2 :: Int -> Int +h2 1 = 0 +h2 m + | odd m = snd (g2 m 2) + | otherwise = uncurry (+) (g2 2 m) diff --git a/testsuite/tests/stranal/should_compile/T18894.stderr b/testsuite/tests/stranal/should_compile/T18894.stderr new file mode 100644 index 0000000000..e0efbe9272 --- /dev/null +++ b/testsuite/tests/stranal/should_compile/T18894.stderr @@ -0,0 +1,404 @@ + +==================== Demand analysis ==================== +Result size of Demand analysis + = {terms: 177, types: 97, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +$trModule = "T18894"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18894.$trModule :: GHC.Types.Module +[LclIdX, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T18894.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 36, types: 16, coercions: 0, joins: 0/0} +g2 [InlPrag=NOINLINE, Dmd=UCU(CS(P(1P(U),SP(U))))] + :: Int -> Int -> (Int, Int) +[LclId, + Arity=2, + Str=<UP(U)><SP(SU)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 20] 161 20}] +g2 + = \ (m [Dmd=UP(U)] :: Int) (ds [Dmd=SP(SU)] :: Int) -> + case ds of { GHC.Types.I# ds [Dmd=SU] -> + case ds of ds [Dmd=1U] { + __DEFAULT -> + (case m of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.*# 2# y) }, + case ds of wild { + __DEFAULT -> + case GHC.Classes.divInt# 2# wild of ww4 { __DEFAULT -> + GHC.Types.I# ww4 + }; + -1# -> GHC.Types.I# -2#; + 0# -> case GHC.Real.divZeroError of wild [Dmd=B] { } + }); + 1# -> (m, lvl) + } + } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 2# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 2# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 36, types: 19, coercions: 0, joins: 0/0} +h2 :: Int -> Int +[LclIdX, + Arity=1, + Str=<SP(MU)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 162 10}] +h2 + = \ (ds [Dmd=SP(MU)] :: Int) -> + case ds of wild [Dmd=UP(U)] { GHC.Types.I# ds [Dmd=MU] -> + case ds of ds { + __DEFAULT -> + case GHC.Prim.remInt# ds 2# of { + __DEFAULT -> + case g2 wild lvl of { (ds1 [Dmd=A], y [Dmd=SU]) -> y }; + 0# -> + case g2 lvl wild of { (x [Dmd=SP(U)], ds [Dmd=SP(U)]) -> + case x of { GHC.Types.I# x -> + case ds of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.+# x y) } + } + } + }; + 1# -> lvl + } + } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 15# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0} +lvl :: (Int, Int) +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = (lvl, lvl) + +-- RHS size: {terms: 30, types: 11, coercions: 0, joins: 0/0} +g1 [InlPrag=NOINLINE, Dmd=UCU(P(UP(U),UP(U)))] :: Int -> (Int, Int) +[LclId, + Arity=1, + Str=<SP(SU)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 141 10}] +g1 + = \ (ds [Dmd=SP(SU)] :: Int) -> + case ds of { GHC.Types.I# ds [Dmd=SU] -> + case ds of ds { + __DEFAULT -> + (GHC.Types.I# (GHC.Prim.*# 2# ds), + case ds of wild { + __DEFAULT -> + case GHC.Classes.divInt# 2# wild of ww4 { __DEFAULT -> + GHC.Types.I# ww4 + }; + -1# -> GHC.Types.I# -2#; + 0# -> case GHC.Real.divZeroError of wild [Dmd=B] { } + }); + 1# -> lvl + } + } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +lvl :: (Int, Int) +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}] +lvl = g1 (GHC.Types.I# 2#) + +-- RHS size: {terms: 28, types: 18, coercions: 0, joins: 0/0} +h1 :: Int -> Int +[LclIdX, + Arity=1, + Str=<SP(MU)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 10}] +h1 + = \ (ds [Dmd=SP(MU)] :: Int) -> + case ds of wild [Dmd=1P(1U)] { GHC.Types.I# ds [Dmd=MU] -> + case ds of { + __DEFAULT -> + case g1 wild of { (x [Dmd=SP(U)], ds [Dmd=SP(U)]) -> + case x of { GHC.Types.I# x -> + case ds of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.+# x y) } + } + }; + 1# -> lvl; + 2# -> case lvl of { (ds1 [Dmd=A], y [Dmd=SU]) -> y } + } + } + + + + +==================== Demand analysis ==================== +Result size of Demand analysis + = {terms: 171, types: 120, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +$trModule = "T18894"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18894.$trModule :: GHC.Types.Module +[LclIdX, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T18894.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# -2# + +-- RHS size: {terms: 32, types: 18, coercions: 0, joins: 0/0} +$wg2 [InlPrag=NOINLINE, Dmd=UCU(CS(P(1P(U),SP(U))))] + :: Int -> GHC.Prim.Int# -> (# Int, Int #) +[LclId, + Arity=2, + Str=<UP(U)><SU>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [20 30] 121 20}] +$wg2 + = \ (w [Dmd=UP(U)] :: Int) (ww [Dmd=SU] :: GHC.Prim.Int#) -> + case ww of ds { + __DEFAULT -> + (# case w of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.*# 2# y) }, + case ds of { + __DEFAULT -> + case GHC.Classes.divInt# 2# ds of ww4 { __DEFAULT -> + GHC.Types.I# ww4 + }; + -1# -> lvl; + 0# -> case GHC.Real.divZeroError of wild [Dmd=B] { } + } #); + 1# -> (# w, lvl #) + } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 2# + +-- RHS size: {terms: 34, types: 21, coercions: 0, joins: 0/0} +$wh2 [InlPrag=[2], Dmd=UCU(U)] :: GHC.Prim.Int# -> Int +[LclId, + Arity=1, + Str=<SU>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 162 10}] +$wh2 + = \ (ww [Dmd=SU] :: GHC.Prim.Int#) -> + case ww of ds { + __DEFAULT -> + case GHC.Prim.remInt# ds 2# of { + __DEFAULT -> + case $wg2 (GHC.Types.I# ds) 2# of + { (# ww [Dmd=A], ww [Dmd=SU] #) -> + ww + }; + 0# -> + case $wg2 lvl ds of { (# ww [Dmd=SP(U)], ww [Dmd=SP(U)] #) -> + case ww of { GHC.Types.I# x -> + case ww of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.+# x y) } + } + } + }; + 1# -> lvl + } + +-- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} +h2 [InlPrag=[2]] :: Int -> Int +[LclIdX, + Arity=1, + Str=<SP(SU)>, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) + Tmpl= \ (w [Occ=Once1!] :: Int) -> + case w of { GHC.Types.I# ww [Occ=Once1, Dmd=MU] -> $wh2 ww }}] +h2 + = \ (w [Dmd=SP(SU)] :: Int) -> + case w of { GHC.Types.I# ww [Dmd=SU] -> $wh2 ww } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 15# + +-- RHS size: {terms: 28, types: 15, coercions: 0, joins: 0/0} +$wg1 [InlPrag=NOINLINE, Dmd=UCU(P(UP(U),UP(U)))] + :: GHC.Prim.Int# -> (# Int, Int #) +[LclId, + Arity=1, + Str=<SU>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 111 20}] +$wg1 + = \ (ww [Dmd=SU] :: GHC.Prim.Int#) -> + case ww of ds { + __DEFAULT -> + (# GHC.Types.I# (GHC.Prim.*# 2# ds), + case ds of { + __DEFAULT -> + case GHC.Classes.divInt# 2# ds of ww4 { __DEFAULT -> + GHC.Types.I# ww4 + }; + -1# -> lvl; + 0# -> case GHC.Real.divZeroError of wild [Dmd=B] { } + } #); + 1# -> (# lvl, lvl #) + } + +-- RHS size: {terms: 7, types: 9, coercions: 0, joins: 0/0} +lvl :: (Int, Int) +[LclId, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 40 10}] +lvl = case $wg1 2# of { (# ww, ww #) -> (ww, ww) } + +-- RHS size: {terms: 25, types: 18, coercions: 0, joins: 0/0} +$wh1 [InlPrag=[2], Dmd=UCU(U)] :: GHC.Prim.Int# -> Int +[LclId, + Arity=1, + Str=<SU>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [50] 101 10}] +$wh1 + = \ (ww [Dmd=SU] :: GHC.Prim.Int#) -> + case ww of ds [Dmd=1U] { + __DEFAULT -> + case $wg1 ds of { (# ww [Dmd=SP(U)], ww [Dmd=SP(U)] #) -> + case ww of { GHC.Types.I# x -> + case ww of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.+# x y) } + } + }; + 1# -> lvl; + 2# -> case lvl of { (ds1 [Dmd=A], y [Dmd=SU]) -> y } + } + +-- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} +h1 [InlPrag=[2]] :: Int -> Int +[LclIdX, + Arity=1, + Str=<SP(SU)>, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) + Tmpl= \ (w [Occ=Once1!] :: Int) -> + case w of { GHC.Types.I# ww [Occ=Once1, Dmd=MU] -> $wh1 ww }}] +h1 + = \ (w [Dmd=SP(SU)] :: Int) -> + case w of { GHC.Types.I# ww [Dmd=SU] -> $wh1 ww } + + + diff --git a/testsuite/tests/stranal/should_compile/T18894b.hs b/testsuite/tests/stranal/should_compile/T18894b.hs new file mode 100644 index 0000000000..e90f34e3fd --- /dev/null +++ b/testsuite/tests/stranal/should_compile/T18894b.hs @@ -0,0 +1,20 @@ +{-# OPTIONS_GHC -O -fno-call-arity -fforce-recomp #-} + +module T18894 (f) where + +expensive :: Int -> (Int, Int) +expensive n = (n+1, n+2) +{-# NOINLINE expensive #-} + +-- arity 1 by itself, but not exported, thus can be eta-expanded based on usage +eta :: Int -> Int -> Int +eta x = if fst (expensive x) == 13 + then \y -> x + y + else \y -> x * y +{-# NOINLINE eta #-} + +f :: Int -> Int +f 1 = 0 +f m + | odd m = eta m 2 + | otherwise = eta 2 m diff --git a/testsuite/tests/stranal/should_compile/T18894b.stderr b/testsuite/tests/stranal/should_compile/T18894b.stderr new file mode 100644 index 0000000000..d9d950769b --- /dev/null +++ b/testsuite/tests/stranal/should_compile/T18894b.stderr @@ -0,0 +1,187 @@ + +==================== Demand analysis ==================== +Result size of Demand analysis = {terms: 83, types: 40, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +$trModule = "T18894"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18894.$trModule :: GHC.Types.Module +[LclIdX, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T18894.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 16, types: 7, coercions: 0, joins: 0/0} +expensive [InlPrag=NOINLINE, Dmd=UCU(P(SP(SU),A))] :: Int -> (Int, Int) +[LclId, + Arity=1, + Str=<UP(U)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [40] 52 10}] +expensive + = \ (n [Dmd=UP(U)] :: Int) -> + (case n of { GHC.Types.I# x -> GHC.Types.I# (GHC.Prim.+# x 1#) }, case n of { GHC.Types.I# x -> GHC.Types.I# (GHC.Prim.+# x 2#) }) + +-- RHS size: {terms: 20, types: 11, coercions: 0, joins: 0/0} +eta [InlPrag=NOINLINE, Dmd=UCU(CS(U))] :: Int -> Int -> Int +[LclId, + Arity=1, + Str=<UP(U)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 140 120}] +eta + = \ (x [Dmd=UP(U)] :: Int) -> + case expensive x of { (x [Dmd=SP(SU)], ds1 [Dmd=A]) -> + case x of { GHC.Types.I# x [Dmd=SU] -> + case x of { + __DEFAULT -> \ (y [Dmd=SP(U)] :: Int) -> GHC.Num.$fNumInt_$c* x y; + 13# -> \ (y [Dmd=SP(U)] :: Int) -> GHC.Num.$fNumInt_$c+ x y + } + } + } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 2# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 2# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 21, types: 5, coercions: 0, joins: 0/0} +f :: Int -> Int +[LclIdX, + Arity=1, + Str=<SP(MU)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 111 0}] +f = \ (ds [Dmd=SP(MU)] :: Int) -> + case ds of wild [Dmd=UP(U)] { GHC.Types.I# ds [Dmd=MU] -> + case ds of ds { + __DEFAULT -> + case GHC.Prim.remInt# ds 2# of { + __DEFAULT -> eta wild lvl; + 0# -> eta lvl wild + }; + 1# -> lvl + } + } + + + + +==================== Demand analysis ==================== +Result size of Demand analysis = {terms: 85, types: 47, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +$trModule = "T18894"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18894.$trModule :: GHC.Types.Module +[LclIdX, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +T18894.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 16, types: 9, coercions: 0, joins: 0/0} +$wexpensive [InlPrag=NOINLINE, Dmd=UCU(P(SP(SU),A))] :: Int -> (# Int, Int #) +[LclId, + Arity=1, + Str=<UP(U)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [40] 42 10}] +$wexpensive + = \ (w [Dmd=UP(U)] :: Int) -> + (# case w of { GHC.Types.I# x -> GHC.Types.I# (GHC.Prim.+# x 1#) }, + case w of { GHC.Types.I# x -> GHC.Types.I# (GHC.Prim.+# x 2#) } #) + +-- RHS size: {terms: 19, types: 12, coercions: 0, joins: 0/0} +eta [InlPrag=NOINLINE, Dmd=UCU(CS(U))] :: Int -> Int -> Int +[LclId, + Arity=2, + Str=<MP(U)><SP(U)>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 0] 120 0}] +eta + = \ (x [Dmd=MP(U)] :: Int) (eta [Dmd=SP(U), OS=OneShot] :: Int) -> + case $wexpensive x of { (# ww [Dmd=SP(SU)], ww [Dmd=A] #) -> + case ww of { GHC.Types.I# x [Dmd=SU] -> + case x of { + __DEFAULT -> GHC.Num.$fNumInt_$c* x eta; + 13# -> GHC.Num.$fNumInt_$c+ x eta + } + } + } + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 2# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[LclId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}] +lvl = GHC.Types.I# 0# + +-- RHS size: {terms: 20, types: 3, coercions: 0, joins: 0/0} +$wf [InlPrag=[2]] :: GHC.Prim.Int# -> Int +[LclId, + Arity=1, + Str=<SU>, + Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [30] 121 0}] +$wf + = \ (ww [Dmd=SU] :: GHC.Prim.Int#) -> + case ww of ds { + __DEFAULT -> + case GHC.Prim.remInt# ds 2# of { + __DEFAULT -> eta (GHC.Types.I# ds) lvl; + 0# -> eta lvl (GHC.Types.I# ds) + }; + 1# -> lvl + } + +-- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} +f [InlPrag=[2]] :: Int -> Int +[LclIdX, + Arity=1, + Str=<SP(SU)>, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) + Tmpl= \ (w [Occ=Once1!] :: Int) -> case w of { GHC.Types.I# ww [Occ=Once1, Dmd=MU] -> $wf ww }}] +f = \ (w [Dmd=SP(SU)] :: Int) -> case w of { GHC.Types.I# ww [Dmd=SU] -> $wf ww } + + + diff --git a/testsuite/tests/stranal/should_compile/all.T b/testsuite/tests/stranal/should_compile/all.T index 1262ad426e..c00d61b8c2 100644 --- a/testsuite/tests/stranal/should_compile/all.T +++ b/testsuite/tests/stranal/should_compile/all.T @@ -58,3 +58,7 @@ test('T18122', [ grep_errmsg(r'wfoo =') ], compile, ['-ddump-simpl']) # We care about the call demand on $wg test('T18903', [ grep_errmsg(r'Dmd=\S+C\S+') ], compile, ['-ddump-simpl -dsuppress-uniques']) +# We care about the call demand on $wg1 and $wg2 +test('T18894', [ grep_errmsg(r'Dmd=\S+C\S+') ], compile, ['-ddump-stranal -dsuppress-uniques']) +# We care about the Arity 2 on eta, as a result of the annotated Dmd +test('T18894b', [ grep_errmsg(r'Arity=2') ], compile, ['-ddump-stranal -dsuppress-uniques -fno-call-arity -dppr-cols=200']) |