X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FcoreSyn%2FCoreFVs.lhs;h=9d2cc8fcec9b017494ee7924755d2365b417634b;hb=dd313897eb9a14bcc7b81f97e4f2292c30039efd;hp=57844395ca4466bd2b2cbb7220292806aabf69a4;hpb=495ef8bd9ef30bffe50ea399b91e3ba09646b59a;p=ghc-hetmet.git diff --git a/ghc/compiler/coreSyn/CoreFVs.lhs b/ghc/compiler/coreSyn/CoreFVs.lhs index 5784439..9d2cc8f 100644 --- a/ghc/compiler/coreSyn/CoreFVs.lhs +++ b/ghc/compiler/coreSyn/CoreFVs.lhs @@ -5,42 +5,38 @@ Taken quite directly from the Peyton Jones/Lester paper. \begin{code} module CoreFVs ( - exprFreeVars, exprsFreeVars, + exprFreeVars, -- CoreExpr -> VarSet -- Find all locally-defined free Ids or tyvars + exprsFreeVars, -- [CoreExpr] -> VarSet + exprSomeFreeVars, exprsSomeFreeVars, - idRuleVars, idFreeVars, - ruleSomeFreeVars, ruleSomeLhsFreeVars, ruleRhsFreeVars, + exprFreeNames, exprsFreeNames, - mustHaveLocalBinding, + idRuleVars, idFreeVars, idFreeTyVars, + ruleRhsFreeVars, rulesRhsFreeVars, + ruleLhsFreeNames, ruleLhsFreeIds, - CoreExprWithFVs, CoreBindWithFVs, freeVars, freeVarsOf, + CoreExprWithFVs, -- = AnnExpr Id VarSet + CoreBindWithFVs, -- = AnnBind Id VarSet + freeVars, -- CoreExpr -> CoreExprWithFVs + freeVarsOf -- CoreExprWithFVs -> IdSet ) where #include "HsVersions.h" import CoreSyn -import Id ( Id, idFreeTyVars, mayHaveNoBinding, idSpecialisation ) +import Id ( Id, idType, idSpecialisation, isLocalId ) +import IdInfo ( specInfoFreeVars ) +import NameSet +import UniqFM ( delFromUFM ) +import Name ( isExternalName ) import VarSet -import Var ( Var, isId ) -import Name ( isLocallyDefined ) -import Type ( tyVarsOfType, Type ) +import Var ( Var, isId, isLocalVar, varName ) +import Type ( tyVarsOfType ) +import TcType ( tyClsNamesOfType ) import Util ( mapAndUnzip ) import Outputable \end{code} -%************************************************************************ -%* * -\section{Utilities} -%* * -%************************************************************************ - -\begin{code} -mustHaveLocalBinding :: Var -> Bool --- True <=> the variable must have a binding in this module -mustHaveLocalBinding v - | isId v = isLocallyDefined v && not (mayHaveNoBinding v) - | otherwise = True -- TyVars etc must -\end{code} - %************************************************************************ %* * @@ -58,7 +54,7 @@ but not those that are free in the type of variable occurrence. \begin{code} exprFreeVars :: CoreExpr -> VarSet -- Find all locally-defined free Ids or tyvars -exprFreeVars = exprSomeFreeVars isLocallyDefined +exprFreeVars = exprSomeFreeVars isLocalVar exprsFreeVars :: [CoreExpr] -> VarSet exprsFreeVars = foldr (unionVarSet . exprFreeVars) emptyVarSet @@ -79,8 +75,8 @@ type InterestingVarFun = Var -> Bool -- True <=> interesting \begin{code} type FV = InterestingVarFun - -> VarSet -- In scope - -> VarSet -- Free vars + -> VarSet -- In scope + -> VarSet -- Free vars union :: FV -> FV -> FV union fv1 fv2 fv_cand in_scope = fv1 fv_cand in_scope `unionVarSet` fv2 fv_cand in_scope @@ -136,8 +132,9 @@ 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 (Case scrut bndr alts) - = expr_fvs scrut `union` addBndr bndr (foldr (union . alt_fvs) noVars alts) +expr_fvs (Case scrut bndr ty alts) + = expr_fvs scrut `union` someVars (tyVarsOfType ty) `union` addBndr bndr + (foldr (union . alt_fvs) noVars alts) where alt_fvs (con, bndrs, rhs) = addBndrs bndrs (expr_fvs rhs) @@ -148,40 +145,89 @@ expr_fvs (Let (Rec pairs) body) = addBndrs bndrs (foldr (union . expr_fvs) (expr_fvs body) rhss) where (bndrs,rhss) = unzip pairs + +--------- +exprs_fvs exprs = foldr (union . expr_fvs) noVars exprs \end{code} +%************************************************************************ +%* * +\section{Free names} +%* * +%************************************************************************ + +exprFreeNames finds the free *external* *names* of an expression, notably +including the names of type constructors (which of course do not show +up in exprFreeVars). Similarly ruleLhsFreeNames. The latter is used +when deciding whether a rule is an orphan. In particular, suppose that +T is defined in this module; we want to avoid declaring that a rule like + fromIntegral T = fromIntegral_T +is an orphan. Of course it isn't, an declaring it an orphan would +make the whole module an orphan module, which is bad. + +There's no need to delete local binders, because they will all +be *internal* names. \begin{code} -idRuleVars ::Id -> VarSet -idRuleVars id = ASSERT( isId id) rulesRhsFreeVars (idSpecialisation id) +ruleLhsFreeNames :: CoreRule -> NameSet +ruleLhsFreeNames (BuiltinRule { ru_fn = fn }) = unitNameSet fn +ruleLhsFreeNames (Rule { ru_fn = fn, ru_bndrs = tpl_vars, ru_args = tpl_args }) + = addOneToNameSet (exprsFreeNames tpl_args) fn + +exprFreeNames :: CoreExpr -> NameSet +-- Find the free *external* names of an expression +exprFreeNames e + = go e + where + go (Var v) + | isExternalName n = unitNameSet n + | otherwise = emptyNameSet + where n = varName 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 (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 + `unionNameSets` unionManyNameSets (map go_alt as) + + go_alt (_,_,r) = go r + +exprsFreeNames es = foldr (unionNameSets . exprFreeNames) emptyNameSet es +\end{code} -idFreeVars :: Id -> VarSet -idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` idFreeTyVars id +%************************************************************************ +%* * +\section[freevars-everywhere]{Attaching free variables to every sub-expression} +%* * +%************************************************************************ -rulesSomeFreeVars :: InterestingVarFun -> CoreRules -> VarSet -rulesSomeFreeVars interesting (Rules rules _) - = foldr (unionVarSet . ruleSomeFreeVars interesting) emptyVarSet rules +\begin{code} ruleRhsFreeVars :: CoreRule -> VarSet -ruleRhsFreeVars (BuiltinRule _) = noFVs -ruleRhsFreeVars (Rule str tpl_vars tpl_args rhs) - = rule_fvs isLocallyDefined emptyVarSet +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) where - rule_fvs = addBndrs tpl_vars (expr_fvs rhs) + fvs = addBndrs bndrs (expr_fvs rhs) isLocalVar emptyVarSet -ruleSomeFreeVars :: InterestingVarFun -> CoreRule -> VarSet -ruleSomeFreeVars interesting (BuiltinRule _) = noFVs -ruleSomeFreeVars interesting (Rule _ tpl_vars tpl_args rhs) - = rule_fvs interesting emptyVarSet - where - rule_fvs = addBndrs tpl_vars $ - foldr (union . expr_fvs) (expr_fvs rhs) tpl_args +rulesRhsFreeVars :: [CoreRule] -> VarSet +rulesRhsFreeVars rules + = foldr (unionVarSet . ruleRhsFreeVars) emptyVarSet rules -ruleSomeLhsFreeVars :: InterestingVarFun -> CoreRule -> VarSet -ruleSomeLhsFreeVars fn (BuiltinRule _) = noFVs -ruleSomeLhsFreeVars fn (Rule _ tpl_vars tpl_args rhs) - = foldl delVarSet (exprsSomeFreeVars fn tpl_args) tpl_vars +ruleLhsFreeIds :: CoreRule -> VarSet +-- This finds all locally-defined free Ids on the LHS of the rule +ruleLhsFreeIds (BuiltinRule {}) = noFVs +ruleLhsFreeIds (Rule { ru_bndrs = bndrs, ru_args = args }) + = addBndrs bndrs (exprs_fvs args) isLocalId emptyVarSet \end{code} @@ -207,9 +253,13 @@ noFVs = emptyVarSet aFreeVar = unitVarSet unionFVs = unionVarSet -filters :: Var -> VarSet -> VarSet +delBindersFV :: [Var] -> VarSet -> VarSet +delBindersFV bs fvs = foldr delBinderFV fvs bs + +delBinderFV :: Var -> VarSet -> VarSet +-- This way round, so we can do it multiple times using foldr --- (b `filters` s) removes the binder b from the free variable set s, +-- (b `delBinderFV` s) removes the binder b from the free variable set s, -- but *adds* to s -- (a) the free variables of b's type -- (b) the idSpecVars of b @@ -237,8 +287,21 @@ filters :: Var -> VarSet -> VarSet -- where -- bottom = bottom -- Never evaluated -filters b s | isId b = (s `delVarSet` b) `unionFVs` idFreeVars b - | otherwise = s `delVarSet` b +delBinderFV b s | isId b = (s `delVarSet` b) `unionFVs` idFreeVars b + | otherwise = s `delVarSet` b + +idFreeVars :: Id -> VarSet +idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` idFreeTyVars id + +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 + +idRuleVars ::Id -> VarSet +idRuleVars id = ASSERT( isId id) specInfoFreeVars (idSpecialisation id) \end{code} @@ -259,12 +322,12 @@ freeVars (Var v) -- Actually [June 98] I don't think it's necessary -- fvs = fvs_v `unionVarSet` idSpecVars v - fvs | isLocallyDefined v = aFreeVar v - | otherwise = noFVs + fvs | isLocalVar v = aFreeVar v + | otherwise = noFVs freeVars (Lit lit) = (noFVs, AnnLit lit) freeVars (Lam b body) - = (b `filters` freeVarsOf body', AnnLam b body') + = (b `delBinderFV` freeVarsOf body', AnnLam b body') where body' = freeVars body @@ -274,16 +337,17 @@ freeVars (App fun arg) fun2 = freeVars fun arg2 = freeVars arg -freeVars (Case scrut bndr alts) - = ((bndr `filters` alts_fvs) `unionFVs` freeVarsOf scrut2, - AnnCase scrut2 bndr alts2) +freeVars (Case scrut bndr ty alts) +-- gaw 2004 + = ((bndr `delBinderFV` alts_fvs) `unionFVs` freeVarsOf scrut2 `unionFVs` tyVarsOfType ty, + AnnCase scrut2 bndr ty alts2) where scrut2 = freeVars scrut (alts_fvs_s, alts2) = mapAndUnzip fv_alt alts alts_fvs = foldr1 unionFVs alts_fvs_s - fv_alt (con,args,rhs) = (foldr filters (freeVarsOf rhs2) args, + fv_alt (con,args,rhs) = (delBindersFV args (freeVarsOf rhs2), (con, args, rhs2)) where rhs2 = freeVars rhs @@ -294,11 +358,11 @@ freeVars (Let (NonRec binder rhs) body) where rhs2 = freeVars rhs body2 = freeVars body - body_fvs = binder `filters` freeVarsOf body2 + body_fvs = binder `delBinderFV` freeVarsOf body2 freeVars (Let (Rec binds) body) = (foldl delVarSet group_fvs binders, - -- The "filters" part may have added one of the binders + -- The "delBinderFV" part may have added one of the binders -- via the idSpecVars part, so we must delete it again AnnLet (AnnRec (binders `zip` rhss2)) body2) where @@ -306,7 +370,7 @@ freeVars (Let (Rec binds) body) rhss2 = map freeVars rhss all_fvs = foldr (unionFVs . fst) body_fvs rhss2 - group_fvs = foldr filters all_fvs binders + group_fvs = delBindersFV binders all_fvs body2 = freeVars body body_fvs = freeVarsOf body2