[commit: ghc] wip/nested-cpr: Inline the datacon wrapper more aggressively (ecb4cc4)

git at git.haskell.org git at git.haskell.org
Tue Feb 4 18:27:19 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/nested-cpr
Link       : http://ghc.haskell.org/trac/ghc/changeset/ecb4cc42c87d4efa433b866d67b004c90a58b1ce/ghc

>---------------------------------------------------------------

commit ecb4cc42c87d4efa433b866d67b004c90a58b1ce
Author: Joachim Breitner <mail at joachim-breitner.de>
Date:   Tue Jan 14 10:18:48 2014 +0000

    Inline the datacon wrapper more aggressively
    
    so that the CPR analysis find the real constructor and can return a
    nested CPR result.
    
    An alternative would be to look through the unfolding and analize that
    (but that would only be a good idea if the wrapper is going to be
    inlined afterwards), or special-case wrappers in the demand analyzer.
    Both not very nice.
    
    According to nofib: The impact of this is (on code size and allocations)
    is ... nil.


>---------------------------------------------------------------

ecb4cc42c87d4efa433b866d67b004c90a58b1ce
 compiler/basicTypes/MkId.lhs                       |    2 +-
 compiler/coreSyn/CoreUnfold.lhs                    |   31 ++++++++++++++++++++
 .../tests/deSugar/should_compile/T2431.stderr      |    2 +-
 .../tests/simplCore/should_compile/T7360.stderr    |    2 +-
 4 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/compiler/basicTypes/MkId.lhs b/compiler/basicTypes/MkId.lhs
index b7716b2..150cf0d 100644
--- a/compiler/basicTypes/MkId.lhs
+++ b/compiler/basicTypes/MkId.lhs
@@ -513,7 +513,7 @@ mkDataConRep dflags fam_envs wrap_name data_con
     	         --      ...(let w = C x in ...(w p q)...)...
     	         -- we want to see that w is strict in its two arguments
 
-    	     wrap_unf = mkInlineUnfolding (Just wrap_arity) wrap_rhs
+             wrap_unf = mkDataConWrapUnfolding wrap_arity wrap_rhs
              wrap_tvs = (univ_tvs `minusList` map fst eq_spec) ++ ex_tvs
     	     wrap_rhs = mkLams wrap_tvs $ 
     	                mkLams wrap_args $
diff --git a/compiler/coreSyn/CoreUnfold.lhs b/compiler/coreSyn/CoreUnfold.lhs
index a219de8..2df8139 100644
--- a/compiler/coreSyn/CoreUnfold.lhs
+++ b/compiler/coreSyn/CoreUnfold.lhs
@@ -29,6 +29,7 @@ module CoreUnfold (
         mkUnfolding, mkCoreUnfolding,
 	mkTopUnfolding, mkSimpleUnfolding,
 	mkInlineUnfolding, mkInlinableUnfolding, mkWwInlineRule,
+        mkDataConWrapUnfolding,
 	mkCompulsoryUnfolding, mkDFunUnfolding,
 
 	interestingArg, ArgSummary(..),
@@ -127,6 +128,16 @@ mkInlineUnfolding mb_arity expr
               
     boring_ok = inlineBoringOk expr'
 
+mkDataConWrapUnfolding :: Arity -> CoreExpr -> Unfolding
+mkDataConWrapUnfolding arity expr
+  = mkCoreUnfolding InlineStable
+                    True
+                    expr' arity
+                    (UnfWhen needSaturated boringCxtOk)
+                    -- Note [Inline data constructor wrappers aggresively]
+  where
+    expr' = simpleOptExpr expr
+
 mkInlinableUnfolding :: DynFlags -> CoreExpr -> Unfolding
 mkInlinableUnfolding dflags expr
   = mkUnfolding dflags InlineStable True is_bot expr'
@@ -199,6 +210,26 @@ This can occasionally mean that the guidance is very pessimistic;
 it gets fixed up next round.  And it should be rare, because large
 let-bound things that are dead are usually caught by preInlineUnconditionally
 
+Note [Inline data constructor wrappers aggresively]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The wrappers for strict data type constructors are to be inlined even in
+a boring context. This increases the chance that the demand analyzer will
+see the real constructor and return a nested CPR property.
+
+For example:
+    data P a = P !a !b
+    f :: Int -> P Int Int
+    f x = P x x
+previously, the demand analyzer would only see
+    f x = $WP x x
+and infer a strictness signature of "<S,U>m(,)", i.e. a non-nested CPR property.
+
+But if we inline $WP, we get
+    f x = case x of _ -> P x x
+and we would get "<S,U>,m(t(),t())", i.e. a nested CPR property.
+
+A real world example of this issue is the function mean in [ticket:2289#comment:1].
+
 
 %************************************************************************
 %*									*
diff --git a/testsuite/tests/deSugar/should_compile/T2431.stderr b/testsuite/tests/deSugar/should_compile/T2431.stderr
index dbafaed..0d68d40 100644
--- a/testsuite/tests/deSugar/should_compile/T2431.stderr
+++ b/testsuite/tests/deSugar/should_compile/T2431.stderr
@@ -8,7 +8,7 @@ T2431.$WRefl [InlPrag=INLINE] :: forall a. a T2431.:~: a
  Str=DmdType,
  Unf=Unf{Src=InlineStable, TopLvl=True, Arity=0, Value=True,
          ConLike=True, WorkFree=True, Expandable=True,
-         Guidance=ALWAYS_IF(unsat_ok=False,boring_ok=False)
+         Guidance=ALWAYS_IF(unsat_ok=False,boring_ok=True)
          Tmpl= \ (@ a) -> T2431.Refl @ a @ a @~ <a>_N}]
 T2431.$WRefl = \ (@ a) -> T2431.Refl @ a @ a @~ <a>_N
 
diff --git a/testsuite/tests/simplCore/should_compile/T7360.stderr b/testsuite/tests/simplCore/should_compile/T7360.stderr
index 51207a6..b3f70e9 100644
--- a/testsuite/tests/simplCore/should_compile/T7360.stderr
+++ b/testsuite/tests/simplCore/should_compile/T7360.stderr
@@ -9,7 +9,7 @@ T7360.$WFoo3 [InlPrag=INLINE] :: GHC.Types.Int -> T7360.Foo
  Str=DmdType <S,U>m3,
  Unf=Unf{Src=InlineStable, TopLvl=True, Arity=1, Value=True,
          ConLike=True, WorkFree=True, Expandable=True,
-         Guidance=ALWAYS_IF(unsat_ok=False,boring_ok=False)
+         Guidance=ALWAYS_IF(unsat_ok=False,boring_ok=True)
          Tmpl= \ (dt [Occ=Once!] :: GHC.Types.Int) ->
                  case dt of _ [Occ=Dead] { GHC.Types.I# dt [Occ=Once] ->
                  T7360.Foo3 dt



More information about the ghc-commits mailing list