Commit 59a4ad63 authored by simonpj@microsoft.com's avatar simonpj@microsoft.com
Browse files

Fix dependency information for RULES

A SpecInfo (inside IdInfo) keeps track of the free variables of a RULE
so that the occurrency analyser knows about its dependencies.

Previously it was only tracking the *rhs* free vars, but it should
really include the *lhs* ones too.  See Note [Rule dependency info]
in IdInfo.

This fixes a WARNING when compiling some libraries.
parent de905f50
......@@ -464,9 +464,11 @@ type InlinePragInfo = Activation
%************************************************************************
\begin{code}
-- CoreRules is used only in an idSpecialisation (move to IdInfo?)
data SpecInfo
= SpecInfo [CoreRule] VarSet -- Locally-defined free vars of RHSs
= SpecInfo
[CoreRule]
VarSet -- Locally-defined free vars of *both* LHS and RHS of rules
-- Note [Rule dependency info]
emptySpecInfo :: SpecInfo
emptySpecInfo = SpecInfo [] emptyVarSet
......@@ -483,6 +485,17 @@ specInfoRules (SpecInfo rules _) = rules
seqSpecInfo (SpecInfo rules fvs) = seqRules rules `seq` seqVarSet fvs
\end{code}
Note [Rule dependency info]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
THe VarSet in a SpecInfo is used for dependency analysis in the
occurrence analyser. We must track free vars in *both* lhs and rhs. Why both?
Consider
x = y
RULE f x = 4
Then if we substitute y for x, we'd better do so in the
rule's LHS too, so we'd better ensure the dependency is respsected
%************************************************************************
%* *
......
......@@ -14,7 +14,7 @@ module CoreFVs (
exprFreeNames, exprsFreeNames,
idRuleVars, idFreeVars, varTypeTyVars,
ruleRhsFreeVars, rulesRhsFreeVars,
ruleRhsFreeVars, rulesFreeVars,
ruleLhsFreeNames, ruleLhsFreeIds,
CoreExprWithFVs, -- = AnnExpr Id VarSet
......@@ -241,18 +241,18 @@ exprsFreeNames es = foldr (unionNameSets . exprFreeNames) emptyNameSet es
ruleRhsFreeVars :: CoreRule -> VarSet
ruleRhsFreeVars (BuiltinRule {}) = noFVs
ruleRhsFreeVars (Rule { ru_fn = fn, ru_bndrs = bndrs, ru_rhs = rhs })
= delFromUFM fvs fn
-- Hack alert!
-- Don't include the Id in its own rhs free-var set.
-- Otherwise the occurrence analyser makes bindings recursive
-- that shoudn't be. E.g.
-- RULE: f (f x y) z ==> f x (f y z)
= delFromUFM fvs fn -- Note [Rule free var hack]
where
fvs = addBndrs bndrs (expr_fvs rhs) isLocalVar emptyVarSet
rulesRhsFreeVars :: [CoreRule] -> VarSet
rulesRhsFreeVars rules
= foldr (unionVarSet . ruleRhsFreeVars) emptyVarSet rules
ruleFreeVars :: CoreRule -> VarSet -- All free variables, both left and right
ruleFreeVars (Rule { ru_fn = fn, ru_bndrs = bndrs, ru_rhs = rhs, ru_args = args })
= delFromUFM fvs fn -- Note [Rule free var hack]
where
fvs = addBndrs bndrs (exprs_fvs (rhs:args)) isLocalVar emptyVarSet
rulesFreeVars :: [CoreRule] -> VarSet
rulesFreeVars rules = foldr (unionVarSet . ruleFreeVars) emptyVarSet rules
ruleLhsFreeIds :: CoreRule -> VarSet
-- This finds all locally-defined free Ids on the LHS of the rule
......@@ -261,6 +261,14 @@ ruleLhsFreeIds (Rule { ru_bndrs = bndrs, ru_args = args })
= addBndrs bndrs (exprs_fvs args) isLocalId emptyVarSet
\end{code}
Note [Rule free var hack]
~~~~~~~~~~~~~~~~~~~~~~~~~
Don't include the Id in its own rhs free-var set.
Otherwise the occurrence analyser makes bindings recursive
that shoudn't be. E.g.
RULE: f (f x y) z ==> f x (f y z)
Also since rule_fn is a Name, not a Var, we have to use the grungy delUFM.
%************************************************************************
%* *
......
......@@ -20,7 +20,7 @@ module Rules (
import CoreSyn -- All of it
import OccurAnal ( occurAnalyseExpr )
import CoreFVs ( exprFreeVars, exprsFreeVars, bindFreeVars, rulesRhsFreeVars )
import CoreFVs ( exprFreeVars, exprsFreeVars, bindFreeVars, rulesFreeVars )
import CoreUnfold ( isCheapUnfolding, unfoldingTemplate )
import CoreUtils ( tcEqExprX, exprType )
import PprCore ( pprRules )
......@@ -136,11 +136,11 @@ ruleCantMatch ts as = False
\begin{code}
mkSpecInfo :: [CoreRule] -> SpecInfo
mkSpecInfo rules = SpecInfo rules (rulesRhsFreeVars rules)
mkSpecInfo rules = SpecInfo rules (rulesFreeVars rules)
extendSpecInfo :: SpecInfo -> [CoreRule] -> SpecInfo
extendSpecInfo (SpecInfo rs1 fvs1) rs2
= SpecInfo (rs2 ++ rs1) (rulesRhsFreeVars rs2 `unionVarSet` fvs1)
= SpecInfo (rs2 ++ rs1) (rulesFreeVars rs2 `unionVarSet` fvs1)
addSpecInfo :: SpecInfo -> SpecInfo -> SpecInfo
addSpecInfo (SpecInfo rs1 fvs1) (SpecInfo rs2 fvs2)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment