diff options
author | Luke Maurer <maurerl@cs.uoregon.edu> | 2017-02-01 11:56:01 -0500 |
---|---|---|
committer | David Feuer <David.Feuer@gmail.com> | 2017-02-01 13:44:52 -0500 |
commit | 8d5cf8bf584fd4849917c29d82dcf46ee75dd035 (patch) | |
tree | 9d1b012562fd7ec1d1089b7d87e061884ba71f1c /testsuite/tests | |
parent | 4fa439e3ee2822f893bd364a6cbfe410a0c1e29f (diff) | |
download | haskell-8d5cf8bf584fd4849917c29d82dcf46ee75dd035.tar.gz |
Join points
This major patch implements Join Points, as described in
https://ghc.haskell.org/trac/ghc/wiki/SequentCore. You have
to read that page, and especially the paper it links to, to
understand what's going on; but it is very cool.
It's Luke Maurer's work, but done in close collaboration with Simon PJ.
This Phab is a squash-merge of wip/join-points branch of
http://github.com/lukemaurer/ghc. There are many, many interdependent
changes.
Reviewers: goldfire, mpickering, bgamari, simonmar, dfeuer, austin
Subscribers: simonpj, dfeuer, mpickering, Mikolaj, thomie
Differential Revision: https://phabricator.haskell.org/D2853
Diffstat (limited to 'testsuite/tests')
33 files changed, 480 insertions, 169 deletions
diff --git a/testsuite/tests/deSugar/should_compile/T2431.stderr b/testsuite/tests/deSugar/should_compile/T2431.stderr index a8da44b73f..83826408cf 100644 --- a/testsuite/tests/deSugar/should_compile/T2431.stderr +++ b/testsuite/tests/deSugar/should_compile/T2431.stderr @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 44, types: 34, coercions: 1} +Result size of Tidy Core + = {terms: 44, types: 34, coercions: 1, joins: 0/0} --- RHS size: {terms: 2, types: 4, coercions: 1} +-- RHS size: {terms: 2, types: 4, coercions: 1, joins: 0/0} T2431.$WRefl [InlPrag=INLINE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, @@ -16,47 +17,47 @@ T2431.$WRefl = \ (@ a) -> T2431.Refl @ a @ a @~ (<a>_N :: (a :: *) GHC.Prim.~# (a :: *)) --- RHS size: {terms: 4, types: 8, coercions: 0} +-- RHS size: {terms: 4, types: 8, coercions: 0, joins: 0/0} absurd :: forall a. (Int :~: Bool) -> a [GblId, Arity=1, Caf=NoCafRefs, Str=<L,U>x] absurd = \ (@ a) (x :: Int :~: Bool) -> case x of { } --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $trModule1 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $trModule2 = GHC.Types.TrNameS $trModule1 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule3 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $trModule3 = "T2431"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule4 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $trModule4 = GHC.Types.TrNameS $trModule3 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T2431.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs] T2431.$trModule = GHC.Types.Module $trModule2 $trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $tc'Refl1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $tc'Refl1 = "'Refl"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $tc'Refl2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $tc'Refl2 = GHC.Types.TrNameS $tc'Refl1 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} T2431.$tc'Refl :: GHC.Types.TyCon [GblId, Caf=NoCafRefs] T2431.$tc'Refl = @@ -66,17 +67,17 @@ T2431.$tc'Refl = T2431.$trModule $tc'Refl2 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $tc:~:1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $tc:~:1 = ":~:"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $tc:~:2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $tc:~:2 = GHC.Types.TrNameS $tc:~:1 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} T2431.$tc:~: :: GHC.Types.TyCon [GblId, Caf=NoCafRefs] T2431.$tc:~: = diff --git a/testsuite/tests/deriving/perf/all.T b/testsuite/tests/deriving/perf/all.T index 0c3e9a4d3e..4c4bb97101 100644 --- a/testsuite/tests/deriving/perf/all.T +++ b/testsuite/tests/deriving/perf/all.T @@ -1,6 +1,8 @@ test('T10858', [compiler_stats_num_field('bytes allocated', - [ (wordsize(64), 222312440, 8) ]), + [ (wordsize(64), 247768192, 8) ]), + # Initial: 222312440 + # 2016-12-19 247768192 Join points (#19288) only_ways(['normal'])], compile, ['-O']) diff --git a/testsuite/tests/numeric/should_compile/T7116.stdout b/testsuite/tests/numeric/should_compile/T7116.stdout index 7fe4d93d87..bc2f85b85f 100644 --- a/testsuite/tests/numeric/should_compile/T7116.stdout +++ b/testsuite/tests/numeric/should_compile/T7116.stdout @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 50, types: 25, coercions: 0} +Result size of Tidy Core + = {terms: 50, types: 25, coercions: 0, joins: 0/0} --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7116.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -10,7 +11,7 @@ T7116.$trModule4 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T7116.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -19,7 +20,7 @@ T7116.$trModule3 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule3 = GHC.Types.TrNameS T7116.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7116.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -27,7 +28,7 @@ T7116.$trModule2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T7116.$trModule2 = "T7116"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -36,7 +37,7 @@ T7116.$trModule1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7116.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, @@ -46,7 +47,7 @@ T7116.$trModule :: GHC.Types.Module T7116.$trModule = GHC.Types.Module T7116.$trModule3 T7116.$trModule1 --- RHS size: {terms: 8, types: 3, coercions: 0} +-- RHS size: {terms: 8, types: 3, coercions: 0, joins: 0/0} dr :: Double -> Double [GblId, Arity=1, @@ -63,7 +64,7 @@ dr = \ (x :: Double) -> case x of { GHC.Types.D# x1 -> GHC.Types.D# (GHC.Prim.+## x1 x1) } --- RHS size: {terms: 8, types: 3, coercions: 0} +-- RHS size: {terms: 8, types: 3, coercions: 0, joins: 0/0} dl :: Double -> Double [GblId, Arity=1, @@ -78,7 +79,7 @@ dl = \ (x :: Double) -> case x of { GHC.Types.D# y -> GHC.Types.D# (GHC.Prim.+## y y) } --- RHS size: {terms: 8, types: 3, coercions: 0} +-- RHS size: {terms: 8, types: 3, coercions: 0, joins: 0/0} fr :: Float -> Float [GblId, Arity=1, @@ -97,7 +98,7 @@ fr = GHC.Types.F# (GHC.Prim.plusFloat# x1 x1) } --- RHS size: {terms: 8, types: 3, coercions: 0} +-- RHS size: {terms: 8, types: 3, coercions: 0, joins: 0/0} fl :: Float -> Float [GblId, Arity=1, diff --git a/testsuite/tests/perf/compiler/all.T b/testsuite/tests/perf/compiler/all.T index d9b0be509a..822ccb0026 100644 --- a/testsuite/tests/perf/compiler/all.T +++ b/testsuite/tests/perf/compiler/all.T @@ -67,7 +67,7 @@ test('T1969', # 2014-06-29 5949188 (x86/Linux) # 2015-07-11 6241108 (x86/Linux, 64bit machine) use +RTS -G1 # 2016-04-06 9093608 (x86/Linux, 64bit machine) - (wordsize(64), 17285216, 15)]), + (wordsize(64), 19924328, 15)]), # 2014-09-10 10463640, 10 # post-AMP-update (somewhat stabelish) # looks like the peak is around ~10M, but we're # unlikely to GC exactly on the peak. @@ -79,6 +79,7 @@ test('T1969', # 2015-07-11 11670120 (amd64/Linux) # 2015-10-28 15017528 (amd64/Linux) emit typeable at definition site # 2016-10-12 17285216 (amd64/Linux) it's not entirely clear why + # 2017-02-01 19924328 (amd64/Linux) Join points (#12988) compiler_stats_num_field('bytes allocated', [(platform('i386-unknown-mingw32'), 301784492, 5), # 215582916 (x86/Windows) @@ -439,9 +440,10 @@ test('T5631', test('parsing001', [compiler_stats_num_field('bytes allocated', [(wordsize(32), 274000576, 10), - (wordsize(64), 581551384, 5)]), + (wordsize(64), 493730288, 5)]), # expected value: 587079016 (amd64/Linux) # 2016-09-01: 581551384 (amd64/Linux) Restore w/w limit (#11565) + # 2016-12-19: 493730288 (amd64/Linux) Join points (#12988) only_ways(['normal']), ], compile_fail, ['']) @@ -503,7 +505,7 @@ test('T5321Fun', # 2014-09-03: 299656164 (specialisation and inlining) # 10/12/2014: 206406188 # Improvements in constraint solver # 2016-04-06: 279922360 x86/Linux - (wordsize(64), 525895608, 5)]) + (wordsize(64), 498135752, 5)]) # prev: 585521080 # 29/08/2012: 713385808 # (increase due to new codegen) # 15/05/2013: 628341952 # (reason for decrease unknown) @@ -526,6 +528,7 @@ test('T5321Fun', # change, however. Namely I am # quite skeptical of the downward # "drift" reported above + # 31/01/2017: 498135752 # Join points (#12988) ], compile,['']) @@ -802,7 +805,7 @@ test('T9872d', test('T9961', [ only_ways(['normal']), compiler_stats_num_field('bytes allocated', - [(wordsize(64), 537297968, 5), + [(wordsize(64), 571246936, 5), # 2015-01-12 807117816 Initally created # 2015-spring 772510192 Got better # 2015-05-22 663978160 Fix for #10370 improves it more @@ -811,6 +814,7 @@ test('T9961', # 2016-03-20 519436672 x64_64/Linux Don't use build desugaring for large lists (#11707) # 2016-03-24 568526784 x64_64/Linux Add eqInt* variants (#11688) # 2016-09-01 537297968 x64_64/Linux Restore w/w limit (#11565) + # 2016-12-19 571246936 x64_64/Linux Join points (#12988) (wordsize(32), 275264188, 5) # was 375647160 # 2016-04-06 275264188 x86/Linux @@ -934,8 +938,9 @@ test('T13035', test('T13056', [ only_ways(['optasm']), compiler_stats_num_field('bytes allocated', - [(wordsize(64), 520166912, 5), + [(wordsize(64), 546800240, 5), # 2017-01-06 520166912 initial + # 2017-01-31 546800240 Join points (#12988) ]), ], compile, @@ -943,9 +948,10 @@ test('T13056', test('T12707', [ compiler_stats_num_field('bytes allocated', - [(wordsize(64), 1348865648, 5), + [(wordsize(64), 1280336112, 5), # initial: 1271577192 # 2017-01-22: 1348865648 Allow top-level strings in Core + # 2017-01-31: 1280336112 Join points (#12988) ]), ], compile, diff --git a/testsuite/tests/perf/haddock/all.T b/testsuite/tests/perf/haddock/all.T index 8ec02cefcc..f037954263 100644 --- a/testsuite/tests/perf/haddock/all.T +++ b/testsuite/tests/perf/haddock/all.T @@ -5,7 +5,7 @@ test('haddock.base', [unless(in_tree_compiler(), skip), req_haddock ,stats_num_field('bytes allocated', - [(wordsize(64), 32855223200, 5) + [(wordsize(64), 31115778088 , 5) # 2012-08-14: 5920822352 (amd64/Linux) # 2012-09-20: 5829972376 (amd64/Linux) # 2012-10-08: 5902601224 (amd64/Linux) @@ -30,6 +30,7 @@ test('haddock.base', # 2015-12-17: 27812188000 (x86_64/Linux) - Move Data.Functor.* into base # 2016-02-25: 30987348040 (x86_64/Linux) - RuntimeRep # 2016-05-12: 32855223200 (x86_64/Linux) - Make Generic1 poly-kinded + # 2017-01-11: 31115778088 (x86_64/Linux) - Join points (#12988) ,(platform('i386-unknown-mingw32'), 4434804940, 5) # 2013-02-10: 3358693084 (x86/Windows) @@ -52,7 +53,7 @@ test('haddock.base', test('haddock.Cabal', [unless(in_tree_compiler(), skip), req_haddock ,stats_num_field('bytes allocated', - [(wordsize(64), 25478853176 , 5) + [(wordsize(64), 23272708864, 5) # 2012-08-14: 3255435248 (amd64/Linux) # 2012-08-29: 3324606664 (amd64/Linux, new codegen) # 2012-10-08: 3373401360 (amd64/Linux) @@ -92,6 +93,7 @@ test('haddock.Cabal', # 2016-10-03: 21554874976 (amd64/Linux) - Cabal update # 2016-10-06: 23706190072 (amd64/Linux) - Cabal update # 2016-12-20: 25478853176 (amd64/Linux) - Cabal update + # 2017-01-14: 23272708864 (amd64/Linux) - Join points (#12988) ,(platform('i386-unknown-mingw32'), 3293415576, 5) # 2012-10-30: 1733638168 (x86/Windows) diff --git a/testsuite/tests/perf/join_points/Makefile b/testsuite/tests/perf/join_points/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/perf/join_points/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/perf/join_points/all.T b/testsuite/tests/perf/join_points/all.T new file mode 100644 index 0000000000..b6f6e40699 --- /dev/null +++ b/testsuite/tests/perf/join_points/all.T @@ -0,0 +1,28 @@ +# Only compile with optimisation +def f( name, opts ): + opts.only_ways = ['optasm'] + +setTestOpts(f) + +test('join001', normal, compile, ['']) + +test('join002', + [stats_num_field('bytes allocated', [(wordsize(64), 2000290792, 5)])], + compile_and_run, + ['']) +test('join003', + [stats_num_field('bytes allocated', [(wordsize(64), 2000290792, 5)])], + compile_and_run, + ['']) +test('join004', + [stats_num_field('bytes allocated', [(wordsize(64), 48146720, 5)])], + compile_and_run, + ['']) + +test('join005', normal, compile, ['']) +test('join006', normal, compile, ['']) + +test('join007', + [stats_num_field('bytes allocated', [(wordsize(64), 50944, 5)])], + compile_and_run, + ['']) diff --git a/testsuite/tests/perf/join_points/join001.hs b/testsuite/tests/perf/join_points/join001.hs new file mode 100644 index 0000000000..04dce36dc9 --- /dev/null +++ b/testsuite/tests/perf/join_points/join001.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE BangPatterns #-} + +module Main where + +findDivBy :: Int -> [Int] -> Maybe Int +findDivBy p ns + -- go should be a join point and should get worker/wrappered; the worker + -- must also be a join point (since it's mutually recursive with one). + = let go !p ns = case ns of n:ns' -> case n `mod` p of 0 -> Just n + _ -> go p ns' + [] -> Nothing + in case p of + 0 -> error "div by zero" + _ -> go p ns + +main = print $ findDivBy 7 [1..10] diff --git a/testsuite/tests/perf/join_points/join002.hs b/testsuite/tests/perf/join_points/join002.hs new file mode 100644 index 0000000000..49aecdcc7f --- /dev/null +++ b/testsuite/tests/perf/join_points/join002.hs @@ -0,0 +1,51 @@ +module Main where + +import Data.List + +-- These four functions should all wind up the same; they represent successive +-- simplifications that should happen. (Actual details may vary, since find +-- isn't quite defined this way, but the differences disappear by the end.) + +firstEvenIsPositive1 :: [Int] -> Bool +firstEvenIsPositive1 = maybe False (> 0) . find even + +-- After inlining: + +firstEvenIsPositive2 :: [Int] -> Bool +firstEvenIsPositive2 xs = + let go xs = case xs of x:xs' -> if even x then Just x else go xs' + [] -> Nothing + in case go xs of Just n -> n > 0 + Nothing -> False + +-- Note that go *could* be a join point if it were declared inside the scrutinee +-- instead of outside. So it's now Float In's job to move the binding inward a +-- smidge. *But* if it goes too far inward (as it would until recently), it will +-- wrap only "go" instead of "go xs", which won't let us mark go as a join point +-- since join points can't be partially invoked. +-- +-- After Float In: + +firstEvenIsPositive3 :: [Int] -> Bool +firstEvenIsPositive3 xs = + case let {-join-} go xs = case xs of x:xs' -> if even x then Just x + else go xs' + [] -> Nothing + in go xs of + Just n -> n > 0 + Nothing -> False + +-- After the simplifier: + +firstEvenIsPositive4 :: [Int] -> Bool +firstEvenIsPositive4 xs = + let {-join-} go xs = case xs of x:xs' -> if even x then x > 0 else go xs' + [] -> False + in go xs + +-- This only worked because go was a join point so that the case gets moved +-- inside. + +{-# NOINLINE firstEvenIsPositive1 #-} + +main = print $ or $ [firstEvenIsPositive1 [1,3..n] | n <- [1..10000]] diff --git a/testsuite/tests/perf/join_points/join002.stdout b/testsuite/tests/perf/join_points/join002.stdout new file mode 100644 index 0000000000..bc59c12aa1 --- /dev/null +++ b/testsuite/tests/perf/join_points/join002.stdout @@ -0,0 +1 @@ +False diff --git a/testsuite/tests/perf/join_points/join003.hs b/testsuite/tests/perf/join_points/join003.hs new file mode 100644 index 0000000000..051c2d8bfe --- /dev/null +++ b/testsuite/tests/perf/join_points/join003.hs @@ -0,0 +1,69 @@ +{- + - A variation on join002.hs that avoids Float Out issues. The join points in + - join002.hs may get floated to top level, which is necessary to allow in + - general, but which makes them into functions rather than join points, thus + - messing up the test. + -} + +module Main ( + firstMultIsPositive1, firstMultIsPositive2, firstMultIsPositive3, + firstMultIsPositive4, + + main +) where + +import Data.List + +divides :: Int -> Int -> Bool +p `divides` n = n `mod` p == 0 + +infix 4 `divides` + +-- These four functions should all wind up the same; they represent successive +-- simplifications that should happen. (Actual details may vary, since find +-- isn't quite defined this way, but the differences disappear by the end.) + +firstMultIsPositive1 :: Int -> [Int] -> Bool +firstMultIsPositive1 p = maybe False (> 0) . find (p `divides`) + +-- After inlining: + +firstMultIsPositive2 :: Int -> [Int] -> Bool +firstMultIsPositive2 p xs = + let go xs = case xs of x:xs' -> if p `divides` x then Just x else go xs' + [] -> Nothing + in case go xs of Just n -> n > 0 + Nothing -> False + +-- Note that go *could* be a join point if it were declared inside the scrutinee +-- instead of outside. So it's now Float In's job to move the binding inward a +-- smidge. *But* if it goes too far inward (as it would until recently), it will +-- wrap only "go" instead of "go xs", which won't let us mark go as a join point +-- since join points can't be partially invoked. +-- +-- After Float In: + +firstMultIsPositive3 :: Int -> [Int] -> Bool +firstMultIsPositive3 p xs = + case let {-join-} go xs = case xs of x:xs' -> if p `divides` x then Just x + else go xs' + [] -> Nothing + in go xs of + Just n -> n > 0 + Nothing -> False + +-- After the simplifier: + +firstMultIsPositive4 :: Int -> [Int] -> Bool +firstMultIsPositive4 p xs = + let {-join-} go xs = case xs of x:xs' -> if p `divides` x then x > 0 + else go xs' + [] -> False + in go xs + +-- This only worked because go was a join point so that the case gets moved +-- inside. + +{-# NOINLINE firstMultIsPositive1 #-} + +main = print $ or $ [firstMultIsPositive1 2 [1,3..n] | n <- [1..10000]] diff --git a/testsuite/tests/perf/join_points/join003.stdout b/testsuite/tests/perf/join_points/join003.stdout new file mode 100644 index 0000000000..bc59c12aa1 --- /dev/null +++ b/testsuite/tests/perf/join_points/join003.stdout @@ -0,0 +1 @@ +False diff --git a/testsuite/tests/perf/join_points/join004.hs b/testsuite/tests/perf/join_points/join004.hs new file mode 100644 index 0000000000..1962cc266e --- /dev/null +++ b/testsuite/tests/perf/join_points/join004.hs @@ -0,0 +1,30 @@ +{- + - A rather contrived example demonstrating the virtues of not floating join + - points outward. + -} + +module Main (main) where + +-- Calculate n `div` d `div` d by looping. + +{-# NOINLINE slowDivDiv #-} +slowDivDiv :: Int -> Int -> Int +slowDivDiv n d + = let {-# NOINLINE divPos #-} + divPos :: Int -> Int + divPos n0 + = -- This function is a join point (all calls are tail calls), so it + -- never causes a closure allocation, so it doesn't help to float it + -- out. Thus -fno-join-points causes a ~25% jump in allocations. + let go n' i + = case n' >= d of True -> go (n' - d) (i + 1) + False -> i + in go n0 0 + in case n >= 0 of True -> divPos (divPos n) + False -> divPos (-(divPos (-n))) + -- It's important that divPos be called twice + -- because otherwise it'd be a one-shot lambda + -- and so the join point would be floated + -- back in again. + +main = print $ sum [slowDivDiv n d | n <- [1..1000], d <- [1..1000]] diff --git a/testsuite/tests/perf/join_points/join004.stdout b/testsuite/tests/perf/join_points/join004.stdout new file mode 100644 index 0000000000..a3abc727e8 --- /dev/null +++ b/testsuite/tests/perf/join_points/join004.stdout @@ -0,0 +1 @@ +793515 diff --git a/testsuite/tests/perf/join_points/join005.hs b/testsuite/tests/perf/join_points/join005.hs new file mode 100644 index 0000000000..7feec98c28 --- /dev/null +++ b/testsuite/tests/perf/join_points/join005.hs @@ -0,0 +1,23 @@ +{- Test of Worker/Wrapper operating on join points -} + +module Main where + +sumOfMultiplesOf :: Int -> [Int] -> Int +sumOfMultiplesOf p ns + = {- This is a join point (and it will stay that way---it won't get floated to + top level because p occurs free). It should get worker/wrappered. -} + let go ns acc + = case ns of [] -> acc + n:ns' -> case n `mod` p of 0 -> go ns' (acc + n) + _ -> go ns' acc + in go ns 0 + +{- +It's hard to test for this, but what should happen is that go gets W/W'd and the +worker is a join point (else Core Lint will complain). Interestingly, go is +*not* CPR'd, because then the worker couldn't be a join point, but once the +simplifier runs, the worker ends up returning Int# anyway. See Note [Don't CPR +join points] in WorkWrap.hs. +-} + +main = print $ sumOfMultiplesOf 2 [1..10] diff --git a/testsuite/tests/perf/join_points/join006.hs b/testsuite/tests/perf/join_points/join006.hs new file mode 100644 index 0000000000..3c0b2ceecd --- /dev/null +++ b/testsuite/tests/perf/join_points/join006.hs @@ -0,0 +1,22 @@ +module Main where + +{-# NOINLINE foo #-} +foo :: Int -> Int +foo x = x + +{-# RULES "foo/5" forall (f :: Int -> Int). foo (f 5) = foo (f 42) #-} +-- highly suspect, of course! + +main = print $ foo (let {-# NOINLINE j #-} + j :: Int -> Int + j n = n + 1 in j 5) + +{- +If we're not careful, this will get rewritten to + + main = print $ let <join> j n = n + 1 in foo (j 42) + +which violates the join point invariant (can't invoke a join point from +non-tail context). Solution is to refuse to float join points when matching +RULES. +-} diff --git a/testsuite/tests/perf/join_points/join007.hs b/testsuite/tests/perf/join_points/join007.hs new file mode 100644 index 0000000000..aa2f68c0bc --- /dev/null +++ b/testsuite/tests/perf/join_points/join007.hs @@ -0,0 +1,42 @@ +-- Test of fusion in unfold/destroy style. Originally, unfold/destroy supported +-- filter, but the constructors (here Done and Yield) couldn't be compiled away. +-- Join points let us do this by pulling the case from sumS into the loop in +-- filterS. + +{-# LANGUAGE GADTs #-} + +module Main (main) where + +data Stream a where Stream :: (s -> Step a s) -> s -> Stream a +data Step a s = Done | Yield a s + +{-# INLINE sumS #-} +sumS :: Stream Int -> Int +sumS (Stream next s0) = go s0 0 + where + go s acc = case next s of Done -> acc + Yield a s' -> go s' (acc + a) + +{-# INLINE filterS #-} +filterS :: (a -> Bool) -> Stream a -> Stream a +filterS p (Stream next s0) = Stream fnext s0 + where + fnext s = seek s + where + -- should be a join point! + seek s = case next s of Done -> Done + Yield a s' | p a -> Yield a s' + | otherwise -> seek s' + +{-# INLINE enumFromToS #-} +enumFromToS :: Int -> Int -> Stream Int +enumFromToS lo hi = Stream next lo + where + next n | n > hi = Done + | otherwise = Yield n (n+1) + +{-# NOINLINE test #-} -- for -ddump-simpl +test :: Int -> Int -> Int +test lo hi = sumS (filterS even (enumFromToS lo hi)) + +main = print $ test 1 10000000 diff --git a/testsuite/tests/perf/join_points/join007.stdout b/testsuite/tests/perf/join_points/join007.stdout new file mode 100644 index 0000000000..0a7ad1072c --- /dev/null +++ b/testsuite/tests/perf/join_points/join007.stdout @@ -0,0 +1 @@ +25000005000000 diff --git a/testsuite/tests/perf/should_run/all.T b/testsuite/tests/perf/should_run/all.T index 382c317a9b..592e63c274 100644 --- a/testsuite/tests/perf/should_run/all.T +++ b/testsuite/tests/perf/should_run/all.T @@ -436,10 +436,11 @@ test('T9203', [ (wordsize(32), 84345136 , 5) # was # 2016-04-06 84345136 (i386/Debian) not sure - , (wordsize(64), 95451192, 5) ]), + , (wordsize(64), 84620888, 5) ]), # was 95747304 # 2019-09-10 94547280 post-AMP cleanup # 2015-10-28 95451192 emit Typeable at definition site + # 2016-12-19 84620888 Join points only_ways(['normal'])], compile_and_run, ['-O2']) @@ -447,9 +448,10 @@ test('T9203', test('T9339', [stats_num_field('bytes allocated', [ (wordsize(32), 40046844, 5) - , (wordsize(64), 80050760, 5) ]), + , (wordsize(64), 50728, 5) ]), # w/o fusing last: 320005080 # 2014-07-22: 80050760 + # 2016-08-17: 50728 Join points (#12988) only_ways(['normal'])], compile_and_run, ['-O2']) diff --git a/testsuite/tests/roles/should_compile/Roles13.stderr b/testsuite/tests/roles/should_compile/Roles13.stderr index 20206e28df..7e510d442e 100644 --- a/testsuite/tests/roles/should_compile/Roles13.stderr +++ b/testsuite/tests/roles/should_compile/Roles13.stderr @@ -1,13 +1,14 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 63, types: 26, coercions: 5} +Result size of Tidy Core + = {terms: 63, types: 26, coercions: 5, joins: 0/0} --- RHS size: {terms: 2, types: 2, coercions: 0} +-- RHS size: {terms: 2, types: 2, coercions: 0, joins: 0/0} convert1 :: Wrap Age -> Wrap Age [GblId, Arity=1, Caf=NoCafRefs] convert1 = \ (ds :: Wrap Age) -> ds --- RHS size: {terms: 1, types: 0, coercions: 5} +-- RHS size: {terms: 1, types: 0, coercions: 5, joins: 0/0} convert :: Wrap Age -> Int [GblId, Arity=1, Caf=NoCafRefs] convert = @@ -15,42 +16,42 @@ convert = `cast` (<Wrap Age>_R -> Roles13.N:Wrap[0] Roles13.N:Age[0] :: ((Wrap Age -> Wrap Age) :: *) ~R# ((Wrap Age -> Int) :: *)) --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $trModule1 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $trModule2 = GHC.Types.TrNameS $trModule1 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule3 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $trModule3 = "Roles13"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule4 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $trModule4 = GHC.Types.TrNameS $trModule3 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roles13.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs] Roles13.$trModule = GHC.Types.Module $trModule2 $trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $tc'MkAge1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $tc'MkAge1 = "'MkAge"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $tc'MkAge2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $tc'MkAge2 = GHC.Types.TrNameS $tc'MkAge1 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} Roles13.$tc'MkAge :: GHC.Types.TyCon [GblId, Caf=NoCafRefs] Roles13.$tc'MkAge = @@ -60,17 +61,17 @@ Roles13.$tc'MkAge = Roles13.$trModule $tc'MkAge2 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $tcAge1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $tcAge1 = "Age"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $tcAge2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $tcAge2 = GHC.Types.TrNameS $tcAge1 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} Roles13.$tcAge :: GHC.Types.TyCon [GblId, Caf=NoCafRefs] Roles13.$tcAge = @@ -80,17 +81,17 @@ Roles13.$tcAge = Roles13.$trModule $tcAge2 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $tc'MkWrap1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $tc'MkWrap1 = "'MkWrap"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $tc'MkWrap2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $tc'MkWrap2 = GHC.Types.TrNameS $tc'MkWrap1 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} Roles13.$tc'MkWrap :: GHC.Types.TyCon [GblId, Caf=NoCafRefs] Roles13.$tc'MkWrap = @@ -100,17 +101,17 @@ Roles13.$tc'MkWrap = Roles13.$trModule $tc'MkWrap2 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $tcWrap1 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $tcWrap1 = "Wrap"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $tcWrap2 :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $tcWrap2 = GHC.Types.TrNameS $tcWrap1 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} Roles13.$tcWrap :: GHC.Types.TyCon [GblId, Caf=NoCafRefs] Roles13.$tcWrap = diff --git a/testsuite/tests/simplCore/should_compile/Makefile b/testsuite/tests/simplCore/should_compile/Makefile index 5a465d9818..ef3e74ad7f 100644 --- a/testsuite/tests/simplCore/should_compile/Makefile +++ b/testsuite/tests/simplCore/should_compile/Makefile @@ -47,6 +47,7 @@ T5658b: $(RM) -f T5658b.o T5658b.hi '$(TEST_HC)' $(TEST_HC_OPTS) -O -c T5658b.hs -ddump-simpl | grep -c indexIntArray # Trac 5658 meant that there were three calls to indexIntArray instead of two +# (now four due to join-point discount causing W/W to stabilize unfolding) T5776: $(RM) -f T5776.o T5776.hi @@ -121,7 +122,7 @@ T13155: T13156: $(RM) -f T13156.hi T13156.o '$(TEST_HC)' $(TEST_HC_OPTS) -c T13156.hs -O -ddump-prep -dsuppress-uniques | grep "case" - # There should be a single 'case case' + # There should be a single 'case r @ GHC.Types.Any' .PHONY: T4138 T4138: diff --git a/testsuite/tests/simplCore/should_compile/T13156.hs b/testsuite/tests/simplCore/should_compile/T13156.hs index cdc322af38..2ddfa2cefb 100644 --- a/testsuite/tests/simplCore/should_compile/T13156.hs +++ b/testsuite/tests/simplCore/should_compile/T13156.hs @@ -4,39 +4,42 @@ f g x = let r :: [a] -> [a] r = case g x of True -> reverse . reverse False -> reverse in - r `seq` r `seq` True + r `seq` r `seq` r {- Expected -ddump-prep looks like this. - (Room for improvement on the case (case ..) line.) + (Case-of-type-lambda an oddity of Core Prep.) --- RHS size: {terms: 9, types: 9, coercions: 0} +-- RHS size: {terms: 9, types: 9, coercions: 0, joins: 0/0} T13156.f1 :: forall a. [a] -> [a] [GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U>, Unf=OtherCon []] T13156.f1 = - \ (@ a_aC4) (x_sNG [Occ=Once] :: [a]) -> - case GHC.List.reverse @ a x_sNG of sat_sNH { __DEFAULT -> - GHC.List.reverse1 @ a sat_sNH (GHC.Types.[] @ a) + \ (@ a) (x [Occ=Once] :: [a]) -> + case GHC.List.reverse @ a x of sat { __DEFAULT -> + GHC.List.reverse1 @ a sat (GHC.Types.[] @ a) } --- RHS size: {terms: 13, types: 20, coercions: 0} -T13156.f :: forall p. (p -> GHC.Types.Bool) -> p -> GHC.Types.Bool +-- RHS size: {terms: 17, types: 28, coercions: 0, joins: 0/0} +T13156.f + :: forall p. + (p -> GHC.Types.Bool) -> p -> [GHC.Types.Int] -> [GHC.Types.Int] [GblId, Arity=2, Caf=NoCafRefs, Str=<C(S),1*C1(U)><L,U>, Unf=OtherCon []] T13156.f = - \ (@ p_aBS) - (g_sNI [Occ=Once!] :: p -> GHC.Types.Bool) - (x_sNJ [Occ=Once] :: p) -> - case case g_sNI x_sNJ of { - GHC.Types.False -> GHC.List.reverse @ GHC.Types.Any; - GHC.Types.True -> T13156.f1 @ GHC.Types.Any - } - of + \ (@ p) + (g [Occ=Once!] :: p -> GHC.Types.Bool) + (x [Occ=Once] :: p) -> + case \ (@ a) -> + case g x of { + GHC.Types.False -> GHC.List.reverse @ a; + GHC.Types.True -> T13156.f1 @ a + } + of r [Dmd=<S,U>] { __DEFAULT -> - GHC.Types.True + case r @ GHC.Types.Any of { __DEFAULT -> r @ GHC.Types.Int } } -} diff --git a/testsuite/tests/simplCore/should_compile/T13156.stdout b/testsuite/tests/simplCore/should_compile/T13156.stdout index 51d10c851f..5aa8f6aa38 100644 --- a/testsuite/tests/simplCore/should_compile/T13156.stdout +++ b/testsuite/tests/simplCore/should_compile/T13156.stdout @@ -1,2 +1,4 @@ case GHC.List.reverse @ a x of sat { __DEFAULT -> - case case g x of { + case \ (@ a1) -> + case g x of { + case r @ GHC.Types.Any of { __DEFAULT -> r @ a } diff --git a/testsuite/tests/simplCore/should_compile/T3717.stderr b/testsuite/tests/simplCore/should_compile/T3717.stderr index f9adeb28da..9bcc4f31ac 100644 --- a/testsuite/tests/simplCore/should_compile/T3717.stderr +++ b/testsuite/tests/simplCore/should_compile/T3717.stderr @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 36, types: 15, coercions: 0} +Result size of Tidy Core + = {terms: 36, types: 15, coercions: 0, joins: 0/0} --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T3717.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -10,7 +11,7 @@ T3717.$trModule4 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T3717.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -19,7 +20,7 @@ T3717.$trModule3 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule3 = GHC.Types.TrNameS T3717.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T3717.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -27,7 +28,7 @@ T3717.$trModule2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T3717.$trModule2 = "T3717"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -36,7 +37,7 @@ T3717.$trModule1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3717.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, @@ -47,7 +48,7 @@ T3717.$trModule = GHC.Types.Module T3717.$trModule3 T3717.$trModule1 Rec { --- RHS size: {terms: 10, types: 2, coercions: 0} +-- RHS size: {terms: 10, types: 2, coercions: 0, joins: 0/0} T3717.$wfoo [InlPrag=[0], Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.Int# [GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U>] @@ -59,7 +60,7 @@ T3717.$wfoo = } end Rec } --- RHS size: {terms: 10, types: 4, coercions: 0} +-- RHS size: {terms: 10, types: 4, coercions: 0, joins: 0/0} foo [InlPrag=INLINE[0]] :: Int -> Int [GblId, Arity=1, diff --git a/testsuite/tests/simplCore/should_compile/T3772.stdout b/testsuite/tests/simplCore/should_compile/T3772.stdout index 76936e336f..98a809d95f 100644 --- a/testsuite/tests/simplCore/should_compile/T3772.stdout +++ b/testsuite/tests/simplCore/should_compile/T3772.stdout @@ -1,9 +1,10 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 40, types: 16, coercions: 0} +Result size of Tidy Core + = {terms: 40, types: 16, coercions: 0, joins: 0/0} Rec { --- RHS size: {terms: 10, types: 2, coercions: 0} +-- RHS size: {terms: 10, types: 2, coercions: 0, joins: 0/0} $wxs :: GHC.Prim.Int# -> () [GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U>] $wxs = @@ -14,7 +15,7 @@ $wxs = } end Rec } --- RHS size: {terms: 14, types: 5, coercions: 0} +-- RHS size: {terms: 14, types: 5, coercions: 0, joins: 0/0} foo [InlPrag=NOINLINE] :: Int -> () [GblId, Arity=1, Caf=NoCafRefs, Str=<S(S),1*U(U)>] foo = @@ -26,7 +27,7 @@ foo = } } --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T3772.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -34,7 +35,7 @@ T3772.$trModule2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T3772.$trModule2 = "T3772"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -43,7 +44,7 @@ T3772.$trModule1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T3772.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -51,7 +52,7 @@ T3772.$trModule4 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T3772.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -60,7 +61,7 @@ T3772.$trModule3 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule3 = GHC.Types.TrNameS T3772.$trModule4 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3772.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, diff --git a/testsuite/tests/simplCore/should_compile/T4908.stderr b/testsuite/tests/simplCore/should_compile/T4908.stderr index e9957bf9de..185b9b3529 100644 --- a/testsuite/tests/simplCore/should_compile/T4908.stderr +++ b/testsuite/tests/simplCore/should_compile/T4908.stderr @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 68, types: 43, coercions: 0} +Result size of Tidy Core + = {terms: 68, types: 43, coercions: 0, joins: 0/0} --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T4908.$trModule4 :: Addr# [GblId, Caf=NoCafRefs, @@ -10,7 +11,7 @@ T4908.$trModule4 :: Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T4908.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule3 :: TrName [GblId, Caf=NoCafRefs, @@ -19,7 +20,7 @@ T4908.$trModule3 :: TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule3 = GHC.Types.TrNameS T4908.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T4908.$trModule2 :: Addr# [GblId, Caf=NoCafRefs, @@ -27,7 +28,7 @@ T4908.$trModule2 :: Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T4908.$trModule2 = "T4908"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule1 :: TrName [GblId, Caf=NoCafRefs, @@ -36,7 +37,7 @@ T4908.$trModule1 :: TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4908.$trModule :: Module [GblId, Caf=NoCafRefs, @@ -47,7 +48,7 @@ T4908.$trModule = GHC.Types.Module T4908.$trModule3 T4908.$trModule1 Rec { --- RHS size: {terms: 19, types: 5, coercions: 0} +-- RHS size: {terms: 19, types: 5, coercions: 0, joins: 0/0} T4908.f_$s$wf [Occ=LoopBreaker] :: Int -> Int# -> Int# -> Bool [GblId, Arity=3, Caf=NoCafRefs, Str=<L,A><L,1*U><S,1*U>] T4908.f_$s$wf = @@ -62,7 +63,7 @@ T4908.f_$s$wf = } end Rec } --- RHS size: {terms: 24, types: 13, coercions: 0} +-- RHS size: {terms: 24, types: 13, coercions: 0, joins: 0/0} T4908.$wf [InlPrag=[0]] :: Int# -> (Int, Int) -> Bool [GblId, Arity=2, @@ -85,7 +86,7 @@ T4908.$wf = 0# -> GHC.Types.True } --- RHS size: {terms: 8, types: 6, coercions: 0} +-- RHS size: {terms: 8, types: 6, coercions: 0, joins: 0/0} f [InlPrag=INLINE[0]] :: Int -> (Int, Int) -> Bool [GblId, Arity=2, diff --git a/testsuite/tests/simplCore/should_compile/T4930.stderr b/testsuite/tests/simplCore/should_compile/T4930.stderr index 365584d3d0..9db97a5e1f 100644 --- a/testsuite/tests/simplCore/should_compile/T4930.stderr +++ b/testsuite/tests/simplCore/should_compile/T4930.stderr @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 49, types: 19, coercions: 0} +Result size of Tidy Core + = {terms: 44, types: 17, coercions: 0, joins: 0/0} --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T4930.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -10,7 +11,7 @@ T4930.$trModule4 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T4930.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -19,7 +20,7 @@ T4930.$trModule3 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule3 = GHC.Types.TrNameS T4930.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T4930.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -27,7 +28,7 @@ T4930.$trModule2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T4930.$trModule2 = "T4930"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -36,7 +37,7 @@ T4930.$trModule1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4930.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, @@ -47,24 +48,19 @@ T4930.$trModule = GHC.Types.Module T4930.$trModule3 T4930.$trModule1 Rec { --- RHS size: {terms: 23, types: 6, coercions: 0} +-- RHS size: {terms: 18, types: 4, coercions: 0, joins: 0/0} T4930.$wfoo [InlPrag=[0], Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.Int# [GblId, Arity=1, Caf=NoCafRefs, Str=<S,U>] T4930.$wfoo = \ (ww :: GHC.Prim.Int#) -> - case case GHC.Prim.tagToEnum# @ Bool (GHC.Prim.<# ww 5#) of { - False -> GHC.Types.I# (GHC.Prim.+# ww 2#); - True -> - case T4930.$wfoo ww of ww1 { __DEFAULT -> GHC.Types.I# ww1 } - } - of - { GHC.Types.I# ipv -> - GHC.Prim.+# ww 5# + case GHC.Prim.tagToEnum# @ Bool (GHC.Prim.<# ww 5#) of { + False -> GHC.Prim.+# ww 5#; + True -> case T4930.$wfoo ww of { __DEFAULT -> GHC.Prim.+# ww 5# } } end Rec } --- RHS size: {terms: 10, types: 4, coercions: 0} +-- RHS size: {terms: 10, types: 4, coercions: 0, joins: 0/0} foo [InlPrag=INLINE[0]] :: Int -> Int [GblId, Arity=1, diff --git a/testsuite/tests/simplCore/should_compile/T5658b.stdout b/testsuite/tests/simplCore/should_compile/T5658b.stdout index 0cfbf08886..b8626c4cff 100644 --- a/testsuite/tests/simplCore/should_compile/T5658b.stdout +++ b/testsuite/tests/simplCore/should_compile/T5658b.stdout @@ -1 +1 @@ -2 +4 diff --git a/testsuite/tests/simplCore/should_compile/T7360.stderr b/testsuite/tests/simplCore/should_compile/T7360.stderr index 2e387b27bc..b35c39931c 100644 --- a/testsuite/tests/simplCore/should_compile/T7360.stderr +++ b/testsuite/tests/simplCore/should_compile/T7360.stderr @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 94, types: 48, coercions: 0} +Result size of Tidy Core + = {terms: 94, types: 48, coercions: 0, joins: 0/0} --- RHS size: {terms: 6, types: 3, coercions: 0} +-- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} T7360.$WFoo3 [InlPrag=INLINE] :: Int -> Foo [GblId[DataConWrapper], Arity=1, @@ -17,19 +18,19 @@ T7360.$WFoo3 = \ (dt [Occ=Once!] :: Int) -> case dt of { GHC.Types.I# dt [Occ=Once] -> T7360.Foo3 dt } --- RHS size: {terms: 5, types: 2, coercions: 0} +-- RHS size: {terms: 5, types: 2, coercions: 0, joins: 0/0} fun1 [InlPrag=NOINLINE] :: Foo -> () [GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U>] fun1 = \ (x :: Foo) -> case x of { __DEFAULT -> GHC.Tuple.() } --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.fun5 :: () [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] T7360.fun5 = fun1 T7360.Foo1 --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.fun4 :: Int [GblId, Caf=NoCafRefs, @@ -38,7 +39,7 @@ T7360.fun4 :: Int WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.fun4 = GHC.Types.I# 0# --- RHS size: {terms: 16, types: 13, coercions: 0} +-- RHS size: {terms: 16, types: 13, coercions: 0, joins: 0/0} fun2 :: forall a. [a] -> ((), Int) [GblId, Arity=1, @@ -66,7 +67,7 @@ fun2 = } }) --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7360.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -74,7 +75,7 @@ T7360.$trModule4 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T7360.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -83,7 +84,7 @@ T7360.$trModule3 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule3 = GHC.Types.TrNameS T7360.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7360.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -91,7 +92,7 @@ T7360.$trModule2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T7360.$trModule2 = "T7360"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -100,7 +101,7 @@ T7360.$trModule1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, @@ -110,7 +111,7 @@ T7360.$trModule :: GHC.Types.Module T7360.$trModule = GHC.Types.Module T7360.$trModule3 T7360.$trModule1 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo9 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -118,7 +119,7 @@ T7360.$tc'Foo9 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T7360.$tc'Foo9 = "'Foo3"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo8 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -127,7 +128,7 @@ T7360.$tc'Foo8 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo8 = GHC.Types.TrNameS T7360.$tc'Foo9 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, Caf=NoCafRefs, @@ -141,7 +142,7 @@ T7360.$tc'Foo3 = T7360.$trModule T7360.$tc'Foo8 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo7 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -149,7 +150,7 @@ T7360.$tc'Foo7 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T7360.$tc'Foo7 = "'Foo2"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo6 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -158,7 +159,7 @@ T7360.$tc'Foo6 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo6 = GHC.Types.TrNameS T7360.$tc'Foo7 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, Caf=NoCafRefs, @@ -172,7 +173,7 @@ T7360.$tc'Foo2 = T7360.$trModule T7360.$tc'Foo6 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo5 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -180,7 +181,7 @@ T7360.$tc'Foo5 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] T7360.$tc'Foo5 = "'Foo1"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo4 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -189,7 +190,7 @@ T7360.$tc'Foo4 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo4 = GHC.Types.TrNameS T7360.$tc'Foo5 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, Caf=NoCafRefs, @@ -203,7 +204,7 @@ T7360.$tc'Foo1 = T7360.$trModule T7360.$tc'Foo4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -211,7 +212,7 @@ T7360.$tcFoo2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] T7360.$tcFoo2 = "Foo"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -220,7 +221,7 @@ T7360.$tcFoo1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 --- RHS size: {terms: 5, types: 0, coercions: 0} +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo :: GHC.Types.TyCon [GblId, Caf=NoCafRefs, diff --git a/testsuite/tests/simplCore/should_compile/T9400.stderr b/testsuite/tests/simplCore/should_compile/T9400.stderr index 92979b36b1..a8004dce8b 100644 --- a/testsuite/tests/simplCore/should_compile/T9400.stderr +++ b/testsuite/tests/simplCore/should_compile/T9400.stderr @@ -1,33 +1,34 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 37, types: 22, coercions: 0} +Result size of Tidy Core + = {terms: 37, types: 22, coercions: 0, joins: 0/0} --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule1 :: Addr# [GblId, Caf=NoCafRefs] $trModule1 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule2 :: TrName [GblId, Caf=NoCafRefs] $trModule2 = GHC.Types.TrNameS $trModule1 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule3 :: Addr# [GblId, Caf=NoCafRefs] $trModule3 = "T9400"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule4 :: TrName [GblId, Caf=NoCafRefs] $trModule4 = GHC.Types.TrNameS $trModule3 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T9400.$trModule :: Module [GblId, Caf=NoCafRefs] T9400.$trModule = GHC.Types.Module $trModule2 $trModule4 --- RHS size: {terms: 22, types: 15, coercions: 0} +-- RHS size: {terms: 22, types: 15, coercions: 0, joins: 0/0} main :: IO () [GblId] main = diff --git a/testsuite/tests/simplCore/should_compile/all.T b/testsuite/tests/simplCore/should_compile/all.T index d63d0d1958..4cc11de737 100644 --- a/testsuite/tests/simplCore/should_compile/all.T +++ b/testsuite/tests/simplCore/should_compile/all.T @@ -24,7 +24,6 @@ test('simpl020', [], multimod_compile, ['simpl020', '-v0']) test('simpl-T1370', normal, compile, ['']) test('T2520', normal, compile, ['']) - test('spec001', when(fast(), skip), compile, ['']) test('spec002', normal, compile, ['']) test('spec003', normal, compile, ['']) @@ -99,7 +98,7 @@ test('T4918', [], run_command, ['$MAKE -s --no-print-directory T4918']) # result of -ddump-simpl, which is never advertised to # be very stable test('T4945', - expect_broken(4945), + normal, run_command, ['$MAKE -s --no-print-directory T4945']) diff --git a/testsuite/tests/simplCore/should_compile/par01.stderr b/testsuite/tests/simplCore/should_compile/par01.stderr index 4ccb9d892b..bbcb9ef4fd 100644 --- a/testsuite/tests/simplCore/should_compile/par01.stderr +++ b/testsuite/tests/simplCore/should_compile/par01.stderr @@ -1,9 +1,10 @@ ==================== CorePrep ==================== -Result size of CorePrep = {terms: 22, types: 10, coercions: 0} +Result size of CorePrep + = {terms: 22, types: 10, coercions: 0, joins: 0/0} Rec { --- RHS size: {terms: 7, types: 3, coercions: 0} +-- RHS size: {terms: 7, types: 3, coercions: 0, joins: 0/0} Par01.depth [Occ=LoopBreaker] :: GHC.Types.Int -> GHC.Types.Int [GblId, Arity=1, Caf=NoCafRefs, Str=<L,U>, Unf=OtherCon []] Par01.depth = @@ -13,27 +14,27 @@ Par01.depth = } end Rec } --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} Par01.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, Unf=OtherCon []] Par01.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, Str=m1, Unf=OtherCon []] Par01.$trModule3 = GHC.Types.TrNameS Par01.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} Par01.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, Unf=OtherCon []] Par01.$trModule2 = "Par01"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, Str=m1, Unf=OtherCon []] Par01.$trModule1 = GHC.Types.TrNameS Par01.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Par01.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, Str=m, Unf=OtherCon []] Par01.$trModule = diff --git a/testsuite/tests/simplCore/should_compile/spec-inline.stderr b/testsuite/tests/simplCore/should_compile/spec-inline.stderr index 0de46d181d..dda28c8926 100644 --- a/testsuite/tests/simplCore/should_compile/spec-inline.stderr +++ b/testsuite/tests/simplCore/should_compile/spec-inline.stderr @@ -1,8 +1,9 @@ ==================== Tidy Core ==================== -Result size of Tidy Core = {terms: 178, types: 68, coercions: 0} +Result size of Tidy Core + = {terms: 178, types: 68, coercions: 0, joins: 0/2} --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} Roman.$trModule4 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -10,7 +11,7 @@ Roman.$trModule4 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] Roman.$trModule4 = "main"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule3 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -19,7 +20,7 @@ Roman.$trModule3 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule3 = GHC.Types.TrNameS Roman.$trModule4 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} Roman.$trModule2 :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs, @@ -27,7 +28,7 @@ Roman.$trModule2 :: GHC.Prim.Addr# WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] Roman.$trModule2 = "Roman"# --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule1 :: GHC.Types.TrName [GblId, Caf=NoCafRefs, @@ -36,7 +37,7 @@ Roman.$trModule1 :: GHC.Types.TrName WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 --- RHS size: {terms: 3, types: 0, coercions: 0} +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roman.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs, @@ -46,19 +47,19 @@ Roman.$trModule :: GHC.Types.Module Roman.$trModule = GHC.Types.Module Roman.$trModule3 Roman.$trModule1 --- RHS size: {terms: 1, types: 0, coercions: 0} +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} lvl :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] lvl = "spec-inline.hs:(19,5)-(29,25)|function go"# --- RHS size: {terms: 2, types: 2, coercions: 0} +-- RHS size: {terms: 2, types: 2, coercions: 0, joins: 0/0} Roman.foo3 :: Int [GblId, Str=x] Roman.foo3 = Control.Exception.Base.patError @ 'GHC.Types.LiftedRep @ Int lvl Rec { --- RHS size: {terms: 55, types: 9, coercions: 0} +-- RHS size: {terms: 55, types: 9, coercions: 0, joins: 0/1} Roman.foo_$s$wgo [Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# [GblId, Arity=2, Caf=NoCafRefs, Str=<S,U><S,U>] @@ -88,7 +89,7 @@ Roman.foo_$s$wgo = } end Rec } --- RHS size: {terms: 74, types: 22, coercions: 0} +-- RHS size: {terms: 74, types: 22, coercions: 0, joins: 0/1} Roman.$wgo [InlPrag=[0]] :: Maybe Int -> Maybe Int -> GHC.Prim.Int# [GblId, Arity=2, @@ -132,7 +133,7 @@ Roman.$wgo = } } --- RHS size: {terms: 9, types: 5, coercions: 0} +-- RHS size: {terms: 9, types: 5, coercions: 0, joins: 0/0} Roman.foo_go [InlPrag=INLINE[0]] :: Maybe Int -> Maybe Int -> Int [GblId, Arity=2, @@ -146,7 +147,7 @@ Roman.foo_go = \ (w :: Maybe Int) (w1 :: Maybe Int) -> case Roman.$wgo w w1 of ww { __DEFAULT -> GHC.Types.I# ww } --- RHS size: {terms: 2, types: 0, coercions: 0} +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.foo2 :: Int [GblId, Caf=NoCafRefs, @@ -155,7 +156,7 @@ Roman.foo2 :: Int WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo2 = GHC.Types.I# 6# --- RHS size: {terms: 2, types: 1, coercions: 0} +-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} Roman.foo1 :: Maybe Int [GblId, Caf=NoCafRefs, @@ -164,7 +165,7 @@ Roman.foo1 :: Maybe Int WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo1 = GHC.Base.Just @ Int Roman.foo2 --- RHS size: {terms: 11, types: 4, coercions: 0} +-- RHS size: {terms: 11, types: 4, coercions: 0, joins: 0/0} foo :: Int -> Int [GblId, Arity=1, |