diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2020-04-08 21:54:07 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-04-09 23:11:57 -0400 |
commit | f5212dfc10414212e42247c2f2dcc45252f7e1d2 (patch) | |
tree | f3b71173b757242cae2e25ee65979e5091a905d2 /compiler | |
parent | 101fab6ee6cee72b9ffce40e45ebf39466d1c01a (diff) | |
download | haskell-f5212dfc10414212e42247c2f2dcc45252f7e1d2.tar.gz |
DmdAnal: No need to attach a StrictSig to DataCon workers
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.
Diffstat (limited to 'compiler')
-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 |