diff options
author | Alexis King <lexi.lambda@gmail.com> | 2020-04-17 16:43:49 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-04-22 23:11:12 -0400 |
commit | 6c9fae2342f19ab3e6ac688825a3817b23bf1fcc (patch) | |
tree | b996d1bdca3e275c77b61de77e54ea107b771d19 /testsuite/tests/simplCore/should_run | |
parent | 401f7bb312aa6c570287d313f8b587aaebca72b2 (diff) | |
download | haskell-6c9fae2342f19ab3e6ac688825a3817b23bf1fcc.tar.gz |
Mark DataCon wrappers CONLIKE
Now that DataCon wrappers don’t inline until phase 0 (see commit
b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that
case-of-known-constructor and RULE matching be able to see saturated
applications of DataCon wrappers in unfoldings. Making them conlike is a
natural way to do it, since they are, in fact, precisely the sort of
thing the CONLIKE pragma exists to solve.
Fixes #18012.
This also bumps the version of the parsec submodule to incorporate a
patch that avoids a metric increase on the haddock perf tests. The
increase was not really a flaw in this patch, as parsec was implicitly
relying on inlining heuristics. The patch to parsec just adds some
INLINABLE pragmas, and we get a nice performance bump out of it (well
beyond the performance we lost from this patch).
Metric Decrease:
T12234
WWRec
haddock.Cabal
haddock.base
haddock.compiler
Diffstat (limited to 'testsuite/tests/simplCore/should_run')
-rw-r--r-- | testsuite/tests/simplCore/should_run/T18012.hs | 41 | ||||
-rw-r--r-- | testsuite/tests/simplCore/should_run/T18012.stdout | 1 | ||||
-rw-r--r-- | testsuite/tests/simplCore/should_run/all.T | 1 |
3 files changed, 43 insertions, 0 deletions
diff --git a/testsuite/tests/simplCore/should_run/T18012.hs b/testsuite/tests/simplCore/should_run/T18012.hs new file mode 100644 index 0000000000..9118b75ff4 --- /dev/null +++ b/testsuite/tests/simplCore/should_run/T18012.hs @@ -0,0 +1,41 @@ +module Main (main) where + +{- This program is designed to check that case-of-known-constructor +fires even if an application of a DataCon wrapper is floated out: + + * The early FloatOut pass will float `D False` out of `g`, since + it’s a constant, non-trivial expression. + + * But since `D` is strict, the floated-out expression will actually + be `$WD False`. + + * In simplifier phase 2, `f` will be inlined into `g`, leading to a + case expression that scrutinizes the floated-out binding. + + * If case-of-known-constructor fires, we’ll end up with `notRule + False`, the RULE will fire, and we get True. + + * If it doesn’t fire at phase 2, it will fire later at phase 0 when + we inline the DataCon wrapper. But now the RULE is inactive, so + we’ll end up with False instead. + +We want case-of-known-constructor to fire early, so we want the output +to be True. See #18012 for more details. -} + +main :: IO () +main = print (g ()) + +data T = D !Bool + +notRule :: Bool -> Bool +notRule x = x +{-# INLINE [0] notRule #-} +{-# RULES "notRule/False" [~0] notRule False = True #-} + +f :: T -> () -> Bool +f (D a) () = notRule a +{-# INLINE [100] f #-} -- so it isn’t inlined before FloatOut + +g :: () -> Bool +g x = f (D False) x +{-# NOINLINE g #-} diff --git a/testsuite/tests/simplCore/should_run/T18012.stdout b/testsuite/tests/simplCore/should_run/T18012.stdout new file mode 100644 index 0000000000..0ca95142bb --- /dev/null +++ b/testsuite/tests/simplCore/should_run/T18012.stdout @@ -0,0 +1 @@ +True diff --git a/testsuite/tests/simplCore/should_run/all.T b/testsuite/tests/simplCore/should_run/all.T index d101bff84b..210949d9c6 100644 --- a/testsuite/tests/simplCore/should_run/all.T +++ b/testsuite/tests/simplCore/should_run/all.T @@ -93,3 +93,4 @@ test('T15840a', normal, compile_and_run, ['']) test('T16066', exit_code(1), compile_and_run, ['-O1']) test('T17206', exit_code(1), compile_and_run, ['']) test('T17151', [], multimod_compile_and_run, ['T17151', '']) +test('T18012', normal, compile_and_run, ['']) |