X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FcoreSyn%2FCoreFVs.lhs;h=655495e8f6092e5f3c10f516851db3d1d2dfdbd9;hp=2fae6ac426c376c8c2134b2ff1985c2218f87767;hb=17b297d97d327620ed6bfab942f8992b2446f1bf;hpb=7656f8c4bd8d786bf83c1ab2dca0cdd1a903e5bf diff --git a/compiler/coreSyn/CoreFVs.lhs b/compiler/coreSyn/CoreFVs.lhs index 2fae6ac..655495e 100644 --- a/compiler/coreSyn/CoreFVs.lhs +++ b/compiler/coreSyn/CoreFVs.lhs @@ -1,9 +1,17 @@ % +% (c) The University of Glasgow 2006 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % Taken quite directly from the Peyton Jones/Lester paper. \begin{code} +{-# OPTIONS_GHC -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings +-- for details + module CoreFVs ( exprFreeVars, -- CoreExpr -> VarSet -- Find all locally-defined free Ids or tyvars exprsFreeVars, -- [CoreExpr] -> VarSet @@ -12,8 +20,8 @@ module CoreFVs ( exprSomeFreeVars, exprsSomeFreeVars, exprFreeNames, exprsFreeNames, - idRuleVars, idFreeVars, idFreeTyVars, - ruleRhsFreeVars, rulesRhsFreeVars, + idRuleVars, idFreeVars, varTypeTyVars, + ruleRhsFreeVars, rulesFreeVars, ruleLhsFreeNames, ruleLhsFreeIds, CoreExprWithFVs, -- = AnnExpr Id VarSet @@ -25,16 +33,15 @@ module CoreFVs ( #include "HsVersions.h" import CoreSyn -import Id ( Id, idType, idSpecialisation, isLocalId ) -import IdInfo ( specInfoFreeVars ) +import Id +import IdInfo import NameSet -import UniqFM ( delFromUFM ) -import Name ( isExternalName ) +import UniqFM +import Name import VarSet -import Var ( Var, isId, isLocalVar, varName ) -import Type ( tyVarsOfType ) -import TcType ( tyClsNamesOfType ) -import Util ( mapAndUnzip ) +import Var +import TcType +import Util import Outputable \end{code} @@ -138,10 +145,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 @@ -157,6 +164,7 @@ expr_fvs (Lit lit) = noVars expr_fvs (Note _ expr) = expr_fvs expr expr_fvs (App fun arg) = expr_fvs fun `union` expr_fvs arg expr_fvs (Lam bndr body) = addBndr bndr (expr_fvs body) +expr_fvs (Cast expr co) = expr_fvs expr `union` someVars (tyVarsOfType co) expr_fvs (Case scrut bndr ty alts) = expr_fvs scrut `union` someVars (tyVarsOfType ty) `union` addBndr bndr @@ -212,12 +220,13 @@ exprFreeNames e go (Var v) | isExternalName n = unitNameSet n | otherwise = emptyNameSet - where n = varName v + where n = idName v go (Lit _) = emptyNameSet go (Type ty) = tyClsNamesOfType ty -- Don't need free tyvars go (App e1 e2) = go e1 `unionNameSets` go e2 - go (Lam v e) = go e `delFromNameSet` varName v - go (Note n e) = go e + go (Lam v e) = go e `delFromNameSet` idName v + go (Note n e) = go e + go (Cast e co) = go e `unionNameSets` tyClsNamesOfType co go (Let (NonRec b r) e) = go e `unionNameSets` go r go (Let (Rec prs) e) = exprsFreeNames (map snd prs) `unionNameSets` go e go (Case e b ty as) = go e `unionNameSets` tyClsNamesOfType ty @@ -239,18 +248,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 @@ -259,6 +268,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. %************************************************************************ %* * @@ -316,18 +333,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) @@ -367,7 +384,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 @@ -382,7 +398,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 @@ -390,27 +407,26 @@ 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 -freeVars (Note (Coerce to_ty from_ty) expr) - = (freeVarsOf expr2 `unionFVs` tfvs1 `unionFVs` tfvs2, - AnnNote (Coerce to_ty from_ty) expr2) + +freeVars (Cast expr co) + = (freeVarsOf expr2 `unionFVs` cfvs, AnnCast expr2 co) where - expr2 = freeVars expr - tfvs1 = tyVarsOfType from_ty - tfvs2 = tyVarsOfType to_ty + expr2 = freeVars expr + cfvs = tyVarsOfType co freeVars (Note other_note expr) = (freeVarsOf expr2, AnnNote other_note expr2)