summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2020-04-08 21:54:07 +0200
committerSebastian Graf <sebastian.graf@kit.edu>2020-04-08 22:33:07 +0200
commit594163c5968e086cc18ef7e1aa36693fb7947a6f (patch)
tree48f8bfc7472c58043c9e26fa39ee81961e58a4bc
parent255418da5d264fb2758bc70925adb2094f34adc3 (diff)
downloadhaskell-wip/dmdanal-datacon-sig.tar.gz
DmdAnal: No need to attach a StrictSig to DataCon workerswip/dmdanal-datacon-sig
In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon.
-rw-r--r--compiler/GHC/Core/DataCon.hs24
-rw-r--r--compiler/GHC/Core/Op/DmdAnal.hs2
-rw-r--r--compiler/GHC/Core/Op/Simplify.hs2
-rw-r--r--compiler/GHC/Types/Demand.hs8
-rw-r--r--compiler/GHC/Types/Id/Make.hs25
5 files changed, 28 insertions, 33 deletions
diff --git a/compiler/GHC/Core/DataCon.hs b/compiler/GHC/Core/DataCon.hs
index 13470c93af..c4563202a9 100644
--- a/compiler/GHC/Core/DataCon.hs
+++ b/compiler/GHC/Core/DataCon.hs
@@ -614,7 +614,7 @@ data DataConRep
-- and *including* all evidence args
, dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys
- -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make
+ -- See also Note [Data-con worker strictness]
, dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures)
-- about the original arguments; 1-1 with orig_arg_tys
@@ -715,8 +715,26 @@ filterEqSpec eq_spec
instance Outputable EqSpec where
ppr (EqSpec tv ty) = ppr (tv, ty)
-{- Note [Bangs on data constructor arguments]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{- Note [Data-con worker strictness]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Notice that we do *not* say the worker Id is strict even if the data
+constructor is declared strict
+ e.g. data T = MkT !(Int,Int)
+Why? Because the *wrapper* $WMkT is strict (and its unfolding has case
+expressions that do the evals) but the *worker* MkT itself is not. If we
+pretend it is strict then when we see
+ case x of y -> MkT y
+the simplifier thinks that y is "sure to be evaluated" (because the worker MkT
+is strict) and drops the case. No, the workerId MkT is not strict.
+
+However, the worker does have StrictnessMarks. When the simplifier sees a
+pattern
+ case e of MkT x -> ...
+it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's
+fine... dataConRepStrictness comes from the data con not from the worker Id.
+
+Note [Bangs on data constructor arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
data T = MkT !Int {-# UNPACK #-} !Int Bool
diff --git a/compiler/GHC/Core/Op/DmdAnal.hs b/compiler/GHC/Core/Op/DmdAnal.hs
index 08d244a36a..79f8d3df61 100644
--- a/compiler/GHC/Core/Op/DmdAnal.hs
+++ b/compiler/GHC/Core/Op/DmdAnal.hs
@@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment
dmdTransform env var dmd
| isDataConWorkId var -- Data constructor
- = dmdTransformDataConSig (idArity var) (idStrictness var) dmd
+ = dmdTransformDataConSig (idArity var) dmd
| gopt Opt_DmdTxDictSel (ae_dflags env),
Just _ <- isClassOpId_maybe var -- Dictionary component selector
diff --git a/compiler/GHC/Core/Op/Simplify.hs b/compiler/GHC/Core/Op/Simplify.hs
index 0227ee9cf0..d1e4f693da 100644
--- a/compiler/GHC/Core/Op/Simplify.hs
+++ b/compiler/GHC/Core/Op/Simplify.hs
@@ -2758,7 +2758,7 @@ a case pattern. This is *important*. Consider
We really must record that b is already evaluated so that we don't
go and re-evaluate it when constructing the result.
-See Note [Data-con worker strictness] in GHC.Types.Id.Make
+See Note [Data-con worker strictness] in GHC.Core.DataCon
NB: simplLamBndrs preserves this eval info
diff --git a/compiler/GHC/Types/Demand.hs b/compiler/GHC/Types/Demand.hs
index fe82d473b2..8d736aa369 100644
--- a/compiler/GHC/Types/Demand.hs
+++ b/compiler/GHC/Types/Demand.hs
@@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd
= postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty
-- see Note [Demands from unsaturated function calls]
-dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType
+dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType
-- Same as dmdTransformSig but for a data constructor (worker),
-- which has a special kind of demand transformer.
-- If the constructor is saturated, we feed the demand on
-- the result into the constructor arguments.
-dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res))
- (JD { sd = str, ud = abs })
+dmdTransformDataConSig arity (JD { sd = str, ud = abs })
| Just str_dmds <- go_str arity str
, Just abs_dmds <- go_abs arity abs
- = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res
- -- Must remember whether it's a product, hence con_res, not TopRes
+ = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv
| otherwise -- Not saturated
= nopDmdType
diff --git a/compiler/GHC/Types/Id/Make.hs b/compiler/GHC/Types/Id/Make.hs
index 052345f3c9..ca0ba944af 100644
--- a/compiler/GHC/Types/Id/Make.hs
+++ b/compiler/GHC/Types/Id/Make.hs
@@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con
tycon = dataConTyCon data_con -- The representation TyCon
wkr_ty = dataConRepType data_con
- ----------- Workers for data types --------------
+ ----------- Workers for data types --------------
alg_wkr_info = noCafIdInfo
`setArityInfo` wkr_arity
- `setStrictnessInfo` wkr_sig
`setCprInfo` mkCprSig wkr_arity (dataConCPR data_con)
`setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated,
-- even if arity = 0
@@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con
-- setNeverLevPoly
wkr_arity = dataConRepArity data_con
- wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv
- -- Note [Data-con worker strictness]
- -- Notice that we do *not* say the worker Id is strict
- -- even if the data constructor is declared strict
- -- e.g. data T = MkT !(Int,Int)
- -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has
- -- case expressions that do the evals) but the *worker* MkT itself is
- -- not. If we pretend it is strict then when we see
- -- case x of y -> MkT y
- -- the simplifier thinks that y is "sure to be evaluated" (because
- -- the worker MkT is strict) and drops the case. No, the workerId
- -- MkT is not strict.
- --
- -- However, the worker does have StrictnessMarks. When the simplifier
- -- sees a pattern
- -- case e of MkT x -> ...
- -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
- -- but that's fine... dataConRepStrictness comes from the data con
- -- not from the worker Id.
-
- ----------- Workers for newtypes --------------
+ ----------- Workers for newtypes --------------
univ_tvs = dataConUnivTyVars data_con
arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys
nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo