[commit: ghc] wip/nested-cpr: Pass nested CPR information from scrunitee to body (60d9a40)
git at git.haskell.org
git at git.haskell.org
Wed Jan 15 18:07:22 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/nested-cpr
Link : http://ghc.haskell.org/trac/ghc/changeset/60d9a40cef5e5e9079cdc93e66868c5531ccc240/ghc
>---------------------------------------------------------------
commit 60d9a40cef5e5e9079cdc93e66868c5531ccc240
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Wed Jan 8 15:09:42 2014 +0000
Pass nested CPR information from scrunitee to body
in case of a complex case scrunitee.
>---------------------------------------------------------------
60d9a40cef5e5e9079cdc93e66868c5531ccc240
compiler/basicTypes/Demand.lhs | 16 ++++++++++++++--
compiler/stranal/DmdAnal.lhs | 41 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/compiler/basicTypes/Demand.lhs b/compiler/basicTypes/Demand.lhs
index 23dacea..b2a9465 100644
--- a/compiler/basicTypes/Demand.lhs
+++ b/compiler/basicTypes/Demand.lhs
@@ -27,8 +27,9 @@ module Demand (
peelFV,
DmdResult, CPRResult,
- isBotRes, isTopRes, getDmdResult,
+ isBotRes, isTopRes, getDmdResult, resTypeArgDmd,
topRes, convRes, botRes, cprProdRes, vanillaCprProdRes, cprSumRes,
+ splitNestedRes,
appIsBottom, isBottomingSig, pprIfaceStrictSig,
returnsCPR, returnsCPR_maybe,
forgetCPR, forgetSumCPR,
@@ -704,6 +705,7 @@ splitProdDmd_maybe (JD {strd = s, absd = u})
(Str s, Use _ (UProd ux)) -> Just (mkJointDmds (splitStrProdDmd (length ux) s) ux)
(Lazy, Use _ (UProd ux)) -> Just (mkJointDmds (replicate (length ux) Lazy) ux)
_ -> Nothing
+
\end{code}
%************************************************************************
@@ -875,13 +877,23 @@ forgetSumCPR_help (RetProd ds) = RetProd (map forgetSumCPR ds)
forgetSumCPR_help (RetSum _) = NoCPR
forgetSumCPR_help NoCPR = NoCPR
-
vanillaCprProdRes :: Arity -> DmdResult
vanillaCprProdRes arity
| opt_CprOff = topRes
| opt_NestedCprOff = Converges $ cutCPRResult flatCPRDepth $ RetProd (replicate arity topRes)
| otherwise = Converges $ cutCPRResult maxCPRDepth $ RetProd (replicate arity topRes)
+splitNestedRes :: DmdResult -> [DmdResult]
+splitNestedRes Diverges = repeat topRes
+splitNestedRes (Dunno c) = splitNestedCPR c
+splitNestedRes (Converges c) = splitNestedCPR c
+
+splitNestedCPR :: CPRResult -> [DmdResult]
+splitNestedCPR NoCPR = repeat topRes
+splitNestedCPR (RetSum _) = repeat topRes
+splitNestedCPR (RetProd cs) = cs
+
+
isTopRes :: DmdResult -> Bool
isTopRes (Dunno NoCPR) = True
isTopRes _ = False
diff --git a/compiler/stranal/DmdAnal.lhs b/compiler/stranal/DmdAnal.lhs
index a080930..d37e5bc 100644
--- a/compiler/stranal/DmdAnal.lhs
+++ b/compiler/stranal/DmdAnal.lhs
@@ -190,6 +190,44 @@ dmdAnal env dmd (Lam var body)
in
(postProcessUnsat defer_and_use lam_ty, Lam var' body')
+dmdAnal env dmd (Case scrut case_bndr ty [alt@(DataAlt dc, bndrs, _)])
+ -- Only one alternative with a product constructor, and a complex scrutinee
+ | let tycon = dataConTyCon dc
+ , isProductTyCon tycon
+ -- If the scrutinee is not trivial, we are not going to get much from
+ -- passing the body demand to it. OTOH, we might be getting some nested CPR
+ -- information from the scrutinee that we can feed into the bound variables.
+ , not (exprIsTrivial scrut)
+ , Just rec_tc' <- checkRecTc (ae_rec_tc env) tycon
+ = let
+ scrut_dmd = mkProdDmd (replicate (dataConRepArity dc) topDmd)
+ (scrut_ty, scrut') = dmdAnal env scrut_dmd scrut
+
+ scrut_ret = getDmdResult scrut_ty
+ -- The case binder has the same signature as the scrunitee,
+ -- but at least the usual CPR property according to dc
+ case_bndr_sig | returnsCPR scrut_ret = convergeSig (mkClosedStrictSig [] scrut_ret)
+ | otherwise = cprProdSig (dataConRepArity dc)
+
+
+ env_w_tc = env { ae_rec_tc = rec_tc' }
+ env_alt = extendAnalEnvs NotTopLevel env_w_tc $
+ (case_bndr, case_bndr_sig) :
+ zipWith (\b ty -> (b, mkClosedStrictSig [] ty))
+ bndrs (splitNestedRes scrut_ret)
+
+ (alt_ty, alt') = dmdAnalAlt env_alt dmd alt
+ (alt_ty1, case_bndr') = annotateBndr env alt_ty case_bndr
+ res_ty = alt_ty1 `bothDmdType` toBothDmdArg scrut_ty
+ in
+ -- pprTrace "dmdAnal:CaseComplex" (vcat [ text "scrut" <+> ppr scrut
+ -- , text "dmd" <+> ppr dmd
+ -- , text "scrut_dmd" <+> ppr scrut_dmd
+ -- , text "scrut_ty" <+> ppr scrut_ty
+ -- , text "alt_ty" <+> ppr alt_ty1
+ -- , text "res_ty" <+> ppr res_ty ]) $
+ (res_ty, Case scrut' case_bndr' ty [alt'])
+
dmdAnal env dmd (Case scrut case_bndr ty [alt@(DataAlt dc, _, _)])
-- Only one alternative with a product constructor
| let tycon = dataConTyCon dc
@@ -1109,6 +1147,9 @@ sigEnv = ae_sigs
updSigEnv :: AnalEnv -> SigEnv -> AnalEnv
updSigEnv env sigs = env { ae_sigs = sigs }
+extendAnalEnvs :: TopLevelFlag -> AnalEnv -> [(Id, StrictSig)] -> AnalEnv
+extendAnalEnvs top_lvl = foldl' (\e (i,s) -> extendAnalEnv top_lvl e i s)
+
extendAnalEnv :: TopLevelFlag -> AnalEnv -> Id -> StrictSig -> AnalEnv
extendAnalEnv top_lvl env var sig
= env { ae_sigs = extendSigEnv top_lvl (ae_sigs env) var sig' }
More information about the ghc-commits
mailing list