summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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