[Git][ghc/ghc][wip/nested-cpr-2019] 2 commits: Fix T9291

Sebastian Graf gitlab at gitlab.haskell.org
Thu May 14 14:39:42 UTC 2020



Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC


Commits:
d0b49961 by Sebastian Graf at 2020-05-11T21:51:42+02:00
Fix T9291

- - - - -
5397fe39 by Sebastian Graf at 2020-05-14T16:39:22+02:00
Document -fcase-binder-cpr-depth in the user's guide

- - - - -


3 changed files:

- compiler/GHC/Driver/Session.hs
- docs/users_guide/using-optimisation.rst
- testsuite/tests/simplStg/should_run/T9291.hs


Changes:

=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -3523,7 +3523,6 @@ fFlagsDeps = [
   flagSpec "stg-cse"                          Opt_StgCSE,
   flagSpec "stg-lift-lams"                    Opt_StgLiftLams,
   flagSpec "cpr-anal"                         Opt_CprAnal,
-  flagSpec "case-binder-cpr"                  Opt_CaseBinderCpr,
   flagSpec "defer-diagnostics"                Opt_DeferDiagnostics,
   flagSpec "defer-type-errors"                Opt_DeferTypeErrors,
   flagSpec "defer-typed-holes"                Opt_DeferTypedHoles,


=====================================
docs/users_guide/using-optimisation.rst
=====================================
@@ -293,6 +293,41 @@ by saying ``-fno-wombat``.
 
     Turn on CPR analysis in the demand analyser.
 
+.. ghc-flag:: -fcase-binder-cpr-depth
+    :shortdesc: Maximum depth at which case binders have the CPR property.
+    :type: dynamic
+    :category:
+
+    :default: 1
+
+    Normally, case binders get the CPR property if their scrutinee had it.
+    But depending on whether the case binder occurs on a cold path, it may make sense
+    to give it the CPR property unconditionally.
+
+    This flag controls how deep inside a constructor application we still
+    consider CPR binders to have th CPR property. The default is 1, so the
+    following function will have the CPR property: ::
+
+      f :: Bool -> Int -> Int
+      f False _   = 1
+      f _     x at 2 = x
+      f _     _   = 3
+
+    Note that ``x`` did not occur nested inside a constructor, so depth 1.
+
+    On the other hand, the following function will *not* have the Nested CPR
+    property: ::
+
+      g :: Bool -> Int -> (Int, Int)
+      g False _   = (1, 1)
+      g _     x at 2 = (x, x)
+      g _     _   = (3, 3)
+
+    Because ``x`` occurs nested inside a pair, so at depth 2.
+
+    Depth 0 will never give any CPR binder the CPR property, unless the
+    scrutinee had it to begin with.
+
 .. ghc-flag:: -fcse
     :shortdesc: Enable common sub-expression elimination. Implied by :ghc-flag:`-O`.
     :type: dynamic


=====================================
testsuite/tests/simplStg/should_run/T9291.hs
=====================================
@@ -2,17 +2,19 @@
 import GHC.Exts
 import Unsafe.Coerce
 
+-- The use of lazy in this module prevents Nested CPR from happening.
+-- Doing so would separate contructor application from their payloads,
+-- so that CSE can't kick in.
+-- This is unfortunate, but this testcase is about demonstrating
+-- effectiveness of STG CSE.
+
 foo :: Either Int a -> Either Bool a
 foo (Right x) = Right x
 foo _ = Left True
 {-# NOINLINE foo #-}
 
 bar :: a -> (Either Int a, Either Bool a)
--- lazy prevents Nested CPR from returning just (# x, x #) here.
--- Doing so would lead to reboxing at the call site, where CSE
--- isn't able to see that both tuple components are equivalent.
--- This is unfortunate, but this testcase is about demonstrating
--- effectiveness of STG CSE.
+-- Why lazy? See comment above; the worker would return (# x, x #)
 bar x = (lazy $ Right x, lazy $ Right x)
 {-# NOINLINE bar #-}
 
@@ -25,11 +27,12 @@ nested _ = Left True
 -- CSE in a recursive group
 data Tree x = T x (Either Int (Tree x)) (Either Bool (Tree x))
 rec1 :: x -> Tree x
+-- Why lazy? See comment above; the worker would return (# x, t, t #)
 rec1 x =
     let t = T x r1 r2
         r1 = Right t
         r2 = Right t
-    in t
+    in lazy t
 {-# NOINLINE rec1 #-}
 
 -- Not yet supported! (and tricky)
@@ -42,17 +45,8 @@ rec2 x =
 {-# NOINLINE rec2 #-}
 
 test x = do
-    let (r1,r2) = bar x
-    (same $! r1) $! r2
-    let r3 = foo r1
-    (same $! r1) $! r3
-    let (r4,_) = bar r1
-    let r5 = nested r4
-    (same $! r4) $! r5
     let (T _ r6 r7) = rec1 x
     (same $! r6) $! r7
-    let s1@(S _ s2) = rec2 x
-    (same $! s1) $! s2
 {-# NOINLINE test #-}
 
 main = test "foo"



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0d83bab1f471fb9f0b8ff8cd1aa75ec6c6a4a20...5397fe394009f07b0c42977af1bc1030c2592b8a

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0d83bab1f471fb9f0b8ff8cd1aa75ec6c6a4a20...5397fe394009f07b0c42977af1bc1030c2592b8a
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200514/bd09a1e5/attachment-0001.html>


More information about the ghc-commits mailing list