[commit: ghc] wip/nested-cpr: Change the handling of Bottom demands on free variables (e765e10)
git at git.haskell.org
git at git.haskell.org
Wed Dec 4 18:06:13 UTC 2013
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/nested-cpr
Link : http://ghc.haskell.org/trac/ghc/changeset/e765e106c613a7fd9c0fd7ed569b9744c536c6d4/ghc
>---------------------------------------------------------------
commit e765e106c613a7fd9c0fd7ed569b9744c536c6d4
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Wed Dec 4 17:59:09 2013 +0000
Change the handling of Bottom demands on free variables
and add a few Notes to explain it.
>---------------------------------------------------------------
e765e106c613a7fd9c0fd7ed569b9744c536c6d4
compiler/basicTypes/Demand.lhs | 52 +++++++++++++++++++++++-----------------
compiler/stranal/DmdAnal.lhs | 10 --------
2 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/compiler/basicTypes/Demand.lhs b/compiler/basicTypes/Demand.lhs
index bb2e215..34adac2 100644
--- a/compiler/basicTypes/Demand.lhs
+++ b/compiler/basicTypes/Demand.lhs
@@ -998,8 +998,7 @@ in GHC itself where the tuple was DynFlags
\begin{code}
type Demand = JointDmd
-type DmdEnv = VarEnv Demand -- If a variable v is not in the domain of the
- -- DmdEnv, it implicitly maps to <Lazy,Absent>
+type DmdEnv = VarEnv Demand -- See Note [Default demand on free variables]
data DmdType = DmdType
DmdEnv -- Demand on explicitly-mentioned
@@ -1045,8 +1044,14 @@ Similarly with
we get dt_scrut from the scrutinee and dt_rhs from the RHS, and then
compute (dt_rhs `bothType` dt_scrut).
-We take the CPR info from FIRST argument, but combine both to get
-termination info.
+We
+ 1. combine the information on the free variables,
+ 2. take the demand on arguments from the first argument
+ 3. combine the termination results, but
+ 4 take CPR info from the first argument.
+
+3 and 4 are implementd in bothDmdResult.
+
\begin{code}
@@ -1076,24 +1081,15 @@ lubDmdType (DmdType fv1 ds1 r1) (DmdType fv2 ds2 r2)
lub_ds ds1 [] = map (`lubDmd` resTypeArgDmd r2) ds1
lub_ds [] ds2 = map (resTypeArgDmd r1 `lubDmd`) ds2
--- TODO: This is used for both
--- * f `bothDmdType` e (in which case divergence of e does not prevent CPR of f e), and
--- * e `bothDmdType` scrut (in which case divergence of scurt prevence convergence of case scrut of _ -> e)
--- HACK for now: Use bothDmdTypeCase for case
--- Need to take strict demand into account?
bothDmdType :: DmdType -> DmdType -> DmdType
bothDmdType (DmdType fv1 ds1 r1) (DmdType fv2 _ r2)
-- See Note [Asymmetry of 'both' for DmdType and DmdResult]
-- 'both' takes the argument/result info from its *first* arg,
-- using its second arg just for its free-var info.
- -- NB: Don't forget about r2! It might be BotRes, which is
- -- a bottom demand on all the in-scope variables.
- = DmdType both_fv2 ds1 (r1 `bothDmdResult` r2)
-
- where
- both_fv = plusVarEnv_C bothDmd fv1 fv2
- both_fv1 = modifyEnv (isBotRes r1) (`bothDmd` botDmd) fv2 fv1 both_fv
- both_fv2 = modifyEnv (isBotRes r2) (`bothDmd` botDmd) fv1 fv2 both_fv1
+ -- Also See Note [Default demand on free variables]
+ = DmdType (fv1 `bothDmdEnv` fv2)
+ ds1
+ (r1 `bothDmdResult` r2)
bothDmdEnv :: DmdEnv -> DmdEnv -> DmdEnv
bothDmdEnv = plusVarEnv_C bothDmd
@@ -1257,18 +1253,30 @@ peelManyCalls arg_ds (CD { sd = str, ud = abs })
peelFV :: DmdType -> Var -> (DmdType, Demand)
peelFV (DmdType fv ds res) id = -- pprTrace "rfv" (ppr id <+> ppr dmd $$ ppr fv)
- (DmdType fv' ds res, dmd)
+ (DmdType fv' ds res, dmd')
where
fv' = fv `delVarEnv` id
- dmd = lookupVarEnv fv id `orElse` deflt
- -- See note [Default demand for variables]
- deflt | isBotRes res = botDmd
- | otherwise = absDmd
+ -- See note [Default demand on free variables]
+ dmd = lookupVarEnv fv id `orElse` absDmd
+ dmd' | isBotRes res = dmd `bothDmd` botDmd
+ | otherwise = dmd
addDemand :: Demand -> DmdType -> DmdType
addDemand dmd (DmdType fv ds res) = DmdType fv (dmd:ds) res
\end{code}
+Note [Default demand on free variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If the variable is not mentioned in the environment of a demand type,
+its demand is taken to be a result demand of the type: either L or the
+bottom. Both are safe from the semantical pont of view, however, for
+the safe result we also have absent demand set to Abs, which makes it
+possible to safely ignore non-mentioned variables (their joint demand
+is <L,A>). absDmd is the identity of bothDmd.
+
+If the result is bottom, we we still have to `bothDmd` the `botDmd` to the
+value in the environment; as we do _not_ do that in bothDmdType.
+
Note [Always analyse in virgin pass]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tricky point: make sure that we analyse in the 'virgin' pass. Consider
diff --git a/compiler/stranal/DmdAnal.lhs b/compiler/stranal/DmdAnal.lhs
index dc346b3..a43e963 100644
--- a/compiler/stranal/DmdAnal.lhs
+++ b/compiler/stranal/DmdAnal.lhs
@@ -769,16 +769,6 @@ addLazyFVs dmd_ty lazy_fvs
-- call to f. So we just get an L demand for x for g.
\end{code}
-Note [Default demand for variables]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If the variable is not mentioned in the environment of a demand type,
-its demand is taken to be a result demand of the type: either L or the
-bottom. Both are safe from the semantical pont of view, however, for
-the safe result we also have absent demand set to Abs, which makes it
-possible to safely ignore non-mentioned variables (their joint demand
-is <L,A>).
-
Note [do not strictify the argument dictionaries of a dfun]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
More information about the ghc-commits
mailing list