diff options
-rw-r--r-- | compiler/GHC/Core/DataCon.hs | 24 | ||||
-rw-r--r-- | compiler/GHC/Core/Op/DmdAnal.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Core/Op/Simplify.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Types/Demand.hs | 8 | ||||
-rw-r--r-- | compiler/GHC/Types/Id/Make.hs | 25 |
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 |