[Git][ghc/ghc][wip/cpr-expandable-unfoldings] CprAnal: Don't attach CPR sigs to expandable bindings (#18154)

Sebastian Graf gitlab at gitlab.haskell.org
Wed May 6 15:14:00 UTC 2020



Sebastian Graf pushed to branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC


Commits:
68b5786d by Sebastian Graf at 2020-05-06T17:13:44+02:00
CprAnal: Don't attach CPR sigs to expandable bindings (#18154)

Instead, look through expandable unfoldings in `cprTransform`.
See the new Note [CPR for expandable unfoldings]:

```
GHC generates a lot of TyCon and KindRep bindings, one for each new data
declaration. Attaching CPR signatures to each of them is quite wasteful.
In general, DataCon application bindings
  * Never get WW'd, so their CPR signature should be irrelevant after analysis
  * Would need to be inlined to see their CPR
  * Recording (Nested!) CPR on them blows up interface file sizes
But we can't just stop giving DataCon application bindings the CPR property,
for example
  fac 0 = 1
  fac n = n * fac (n-1)
fac certainly has the CPR property and should be WW'd! But FloatOut will
transform the first clause to
  lvl = 1
  fac 0 = lvl
If lvl doesn't have the CPR property, fac won't either. So instead we keep on
looking through *expandable* unfoldings for these arity 0 bindings.
```

Fixes #18154.

- - - - -


1 changed file:

- compiler/GHC/Core/Opt/CprAnal.hs


Changes:

=====================================
compiler/GHC/Core/Opt/CprAnal.hs
=====================================
@@ -231,9 +231,14 @@ cprTransform env id
     sig
   where
     sig
-      | isGlobalId id                   -- imported function or data con worker
+      -- See Note [CPR for expandable unfoldings]
+      | Just rhs <- lookupExpandableUnfolding id
+      = fst $ cprAnal env rhs
+      -- Imported function or data con worker
+      | isGlobalId id
       = getCprSig (idCprInfo id)
-      | Just sig <- lookupSigEnv env id -- local let-bound
+      -- Local let-bound
+      | Just sig <- lookupSigEnv env id
       = getCprSig sig
       | otherwise
       = topCprType
@@ -303,6 +308,8 @@ cprAnalBind top_lvl env id rhs
       | stays_thunk = trimCprTy rhs_ty
       -- See Note [CPR for sum types]
       | returns_sum = trimCprTy rhs_ty
+      -- See Note [CPR for expandable unfoldings]
+      | will_expand = topCprType
       | otherwise   = rhs_ty
     -- See Note [Arity trimming for CPR signatures]
     sig             = mkCprSigForArity (idArity id) rhs_ty'
@@ -316,6 +323,19 @@ cprAnalBind top_lvl env id rhs
     (_, ret_ty) = splitPiTys (idType id)
     not_a_prod  = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty)
     returns_sum = not (isTopLevel top_lvl) && not_a_prod
+    -- See Note [CPR for expandable unfoldings]
+    will_expand = isJust (lookupExpandableUnfolding id)
+
+lookupExpandableUnfolding :: Id -> Maybe CoreExpr
+lookupExpandableUnfolding id
+  | idArity id == 0 = expandUnfolding_maybe (cprIdUnfolding id)
+  | otherwise       = Nothing
+
+cprIdUnfolding :: IdUnfoldingFun
+cprIdUnfolding id
+  -- There will only be phase 0 Simplifier runs after CprAnal
+  | isActiveIn 0 (idInlineActivation id) = idUnfolding id
+  | otherwise                            = noUnfolding
 
 {- Note [Arity trimming for CPR signatures]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -626,6 +646,28 @@ fac won't have the CPR property here when we trim every thunk! But the
 assumption is that error cases are rarely entered and we are diverging anyway,
 so WW doesn't hurt.
 
+Should we also trim CPR on DataCon bindings?
+See Note [CPR for expandable unfoldings]!
+
+Note [CPR for expandable unfoldings]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GHC generates a lot of TyCon and KindRep bindings, one for each new data
+declaration. Attaching CPR signatures to each of them is quite wasteful.
+In general, DataCon application bindings
+  * Never get WW'd, so their CPR signature should be irrelevant after analysis
+  * Would need to be inlined to see their CPR
+  * Recording (Nested!) CPR on them blows up interface file sizes
+But we can't just stop giving DataCon application bindings the CPR property,
+for example
+  fac 0 = 1
+  fac n = n * fac (n-1)
+fac certainly has the CPR property and should be WW'd! But FloatOut will
+transform the first clause to
+  lvl = 1
+  fac 0 = lvl
+If lvl doesn't have the CPR property, fac won't either. So instead we keep on
+looking through *expandable* unfoldings for these arity 0 bindings.
+
 Note [CPR examples]
 ~~~~~~~~~~~~~~~~~~~~
 Here are some examples (stranal/should_compile/T10482a) of the



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68b5786d17d8c9f801f15d5e4fc25167b6eff8fe

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68b5786d17d8c9f801f15d5e4fc25167b6eff8fe
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/20200506/e2fc4120/attachment-0001.html>


More information about the ghc-commits mailing list