X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FcoreSyn%2FCoreFVs.lhs;h=807b76c02e04da08eb02f9653b1599a7325b11df;hb=59a4ad63f93f4fd7b8ede74bb2ea36778fe25e06;hp=c32ca7c54e8b9d17077f56e9bb7058a7bcc237a7;hpb=49c98d143c382a1341e1046f5ca00819a25691ba;p=ghc-hetmet.git diff --git a/compiler/coreSyn/CoreFVs.lhs b/compiler/coreSyn/CoreFVs.lhs index c32ca7c..807b76c 100644 --- a/compiler/coreSyn/CoreFVs.lhs +++ b/compiler/coreSyn/CoreFVs.lhs @@ -13,8 +13,8 @@ module CoreFVs ( exprSomeFreeVars, exprsSomeFreeVars, exprFreeNames, exprsFreeNames, - idRuleVars, idFreeVars, idFreeTyVars, - ruleRhsFreeVars, rulesRhsFreeVars, + idRuleVars, idFreeVars, varTypeTyVars, + ruleRhsFreeVars, rulesFreeVars, ruleLhsFreeNames, ruleLhsFreeIds, CoreExprWithFVs, -- = AnnExpr Id VarSet @@ -138,10 +138,10 @@ keep_it fv_cand in_scope var addBndr :: CoreBndr -> FV -> FV addBndr bndr fv fv_cand in_scope - | isId bndr = inside_fvs `unionVarSet` someVars (idFreeTyVars bndr) fv_cand in_scope - | otherwise = inside_fvs - where - inside_fvs = fv fv_cand (in_scope `extendVarSet` bndr) + = someVars (varTypeTyVars bndr) fv_cand in_scope + -- Include type varibles in the binder's type + -- (not just Ids; coercion variables too!) + `unionVarSet` fv fv_cand (in_scope `extendVarSet` bndr) addBndrs :: [CoreBndr] -> FV -> FV addBndrs bndrs fv = foldr addBndr fv bndrs @@ -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. %************************************************************************ %* * @@ -318,18 +326,18 @@ delBinderFV :: Var -> VarSet -> VarSet -- where -- bottom = bottom -- Never evaluated -delBinderFV b s | isId b = (s `delVarSet` b) `unionFVs` idFreeVars b - | otherwise = s `delVarSet` b +delBinderFV b s = (s `delVarSet` b) `unionFVs` varTypeTyVars b + -- Include coercion variables too! -idFreeVars :: Id -> VarSet -idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` idFreeTyVars id +varTypeTyVars :: Var -> TyVarSet +-- Find the type variables free in the type of the variable +-- Remember, coercion variables can mention type variables... +varTypeTyVars var + | isLocalId var || isCoVar var = tyVarsOfType (idType var) + | otherwise = emptyVarSet -- Global Ids and non-coercion TyVars -idFreeTyVars :: Id -> TyVarSet --- Only local Ids conjured up locally, can have free type variables. --- (During type checking top-level Ids can have free tyvars) -idFreeTyVars id = tyVarsOfType (idType id) --- | isLocalId id = tyVarsOfType (idType id) --- | otherwise = emptyVarSet +idFreeVars :: Id -> VarSet +idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` varTypeTyVars id idRuleVars ::Id -> VarSet idRuleVars id = ASSERT( isId id) specInfoFreeVars (idSpecialisation id) @@ -369,7 +377,6 @@ freeVars (App fun arg) arg2 = freeVars arg freeVars (Case scrut bndr ty alts) --- gaw 2004 = ((bndr `delBinderFV` alts_fvs) `unionFVs` freeVarsOf scrut2 `unionFVs` tyVarsOfType ty, AnnCase scrut2 bndr ty alts2) where @@ -384,7 +391,8 @@ freeVars (Case scrut bndr ty alts) rhs2 = freeVars rhs freeVars (Let (NonRec binder rhs) body) - = (freeVarsOf rhs2 `unionFVs` body_fvs, + = (freeVarsOf rhs2 `unionFVs` body_fvs `unionFVs` idRuleVars binder, + -- Remember any rules; cf rhs_fvs above AnnLet (AnnNonRec binder rhs2) body2) where rhs2 = freeVars rhs @@ -392,16 +400,16 @@ freeVars (Let (NonRec binder rhs) body) body_fvs = binder `delBinderFV` freeVarsOf body2 freeVars (Let (Rec binds) body) - = (foldl delVarSet group_fvs binders, - -- The "delBinderFV" part may have added one of the binders - -- via the idSpecVars part, so we must delete it again + = (delBindersFV binders all_fvs, AnnLet (AnnRec (binders `zip` rhss2)) body2) where (binders, rhss) = unzip binds rhss2 = map freeVars rhss - all_fvs = foldr (unionFVs . fst) body_fvs rhss2 - group_fvs = delBindersFV binders all_fvs + rhs_body_fvs = foldr (unionFVs . freeVarsOf) body_fvs rhss2 + all_fvs = foldr (unionFVs . idRuleVars) rhs_body_fvs binders + -- The "delBinderFV" happens after adding the idSpecVars, + -- since the latter may add some of the binders as fvs body2 = freeVars body body_fvs = freeVarsOf body2