2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 Taken quite directly from the Peyton Jones/Lester paper.
8 isLocalVar, mustHaveLocalBinding,
10 exprFreeVars, exprsFreeVars,
11 exprSomeFreeVars, exprsSomeFreeVars,
12 idRuleVars, idFreeVars, idFreeTyVars,
13 ruleSomeFreeVars, ruleSomeLhsFreeVars, ruleRhsFreeVars,
15 CoreExprWithFVs, CoreBindWithFVs, freeVars, freeVarsOf,
18 #include "HsVersions.h"
21 import Id ( Id, idName, idType, isLocalId, hasNoBinding, idSpecialisation )
23 import Var ( Var, isId )
24 import Type ( tyVarsOfType )
25 import Util ( mapAndUnzip )
30 %************************************************************************
32 \subsection{isLocalVar}
34 %************************************************************************
36 @isLocalVar@ returns True of all TyVars, and of Ids that are defined in
37 this module and are not constants like data constructors and record selectors.
38 These are the variables that we need to pay attention to when finding free
39 variables, or doing dependency analysis.
42 isLocalVar :: Var -> Bool
43 isLocalVar v = isTyVar v || isLocalId v
47 mustHaveLocalBinding :: Var -> Bool
48 -- True <=> the variable must have a binding in this module
49 mustHaveLocalBinding v = isTyVar v || (isLocalId v && not (hasNoBinding v))
53 %************************************************************************
55 \section{Finding the free variables of an expression}
57 %************************************************************************
59 This function simply finds the free variables of an expression.
60 So far as type variables are concerned, it only finds tyvars that are
62 * free in type arguments,
63 * free in the type of a binder,
65 but not those that are free in the type of variable occurrence.
68 exprFreeVars :: CoreExpr -> VarSet -- Find all locally-defined free Ids or tyvars
69 exprFreeVars = exprSomeFreeVars isLocalVar
71 exprsFreeVars :: [CoreExpr] -> VarSet
72 exprsFreeVars = foldr (unionVarSet . exprFreeVars) emptyVarSet
74 exprSomeFreeVars :: InterestingVarFun -- Says which Vars are interesting
77 exprSomeFreeVars fv_cand e = expr_fvs e fv_cand emptyVarSet
79 exprsSomeFreeVars :: InterestingVarFun -- Says which Vars are interesting
82 exprsSomeFreeVars fv_cand = foldr (unionVarSet . exprSomeFreeVars fv_cand) emptyVarSet
84 type InterestingVarFun = Var -> Bool -- True <=> interesting
89 type FV = InterestingVarFun
91 -> VarSet -- Free vars
93 union :: FV -> FV -> FV
94 union fv1 fv2 fv_cand in_scope = fv1 fv_cand in_scope `unionVarSet` fv2 fv_cand in_scope
97 noVars fv_cand in_scope = emptyVarSet
99 -- At a variable occurrence, add in any free variables of its rule rhss
100 -- Curiously, we gather the Id's free *type* variables from its binding
101 -- site, but its free *rule-rhs* variables from its usage sites. This
102 -- is a little weird. The reason is that the former is more efficient,
103 -- but the latter is more fine grained, and a makes a difference when
104 -- a variable mentions itself one of its own rule RHSs
106 oneVar var fv_cand in_scope
108 foldVarSet add_rule_var var_itself_set (idRuleVars var)
110 var_itself_set | keep_it fv_cand in_scope var = unitVarSet var
111 | otherwise = emptyVarSet
112 add_rule_var var set | keep_it fv_cand in_scope var = extendVarSet set var
115 someVars :: VarSet -> FV
116 someVars vars fv_cand in_scope
117 = filterVarSet (keep_it fv_cand in_scope) vars
119 keep_it fv_cand in_scope var
120 | var `elemVarSet` in_scope = False
125 addBndr :: CoreBndr -> FV -> FV
126 addBndr bndr fv fv_cand in_scope
127 | isId bndr = inside_fvs `unionVarSet` someVars (idFreeTyVars bndr) fv_cand in_scope
128 | otherwise = inside_fvs
130 inside_fvs = fv fv_cand (in_scope `extendVarSet` bndr)
132 addBndrs :: [CoreBndr] -> FV -> FV
133 addBndrs bndrs fv = foldr addBndr fv bndrs
138 expr_fvs :: CoreExpr -> FV
140 expr_fvs (Type ty) = someVars (tyVarsOfType ty)
141 expr_fvs (Var var) = oneVar var
142 expr_fvs (Lit lit) = noVars
143 expr_fvs (Note _ expr) = expr_fvs expr
144 expr_fvs (App fun arg) = expr_fvs fun `union` expr_fvs arg
145 expr_fvs (Lam bndr body) = addBndr bndr (expr_fvs body)
147 expr_fvs (Case scrut bndr alts)
148 = expr_fvs scrut `union` addBndr bndr (foldr (union . alt_fvs) noVars alts)
150 alt_fvs (con, bndrs, rhs) = addBndrs bndrs (expr_fvs rhs)
152 expr_fvs (Let (NonRec bndr rhs) body)
153 = expr_fvs rhs `union` addBndr bndr (expr_fvs body)
155 expr_fvs (Let (Rec pairs) body)
156 = addBndrs bndrs (foldr (union . expr_fvs) (expr_fvs body) rhss)
158 (bndrs,rhss) = unzip pairs
164 idFreeVars :: Id -> VarSet
165 idFreeVars id = ASSERT( isId id) idRuleVars id `unionVarSet` idFreeTyVars id
167 idFreeTyVars :: Id -> TyVarSet
168 -- Only local Ids conjured up locally, can have free type variables.
169 -- (During type checking top-level Ids can have free tyvars)
170 idFreeTyVars id = tyVarsOfType (idType id)
171 -- | isLocalId id = tyVarsOfType (idType id)
172 -- | otherwise = emptyVarSet
174 idRuleVars ::Id -> VarSet
175 idRuleVars id = ASSERT( isId id) rulesRhsFreeVars (idSpecialisation id)
177 rulesSomeFreeVars :: InterestingVarFun -> CoreRules -> VarSet
178 rulesSomeFreeVars interesting (Rules rules _)
179 = foldr (unionVarSet . ruleSomeFreeVars interesting) emptyVarSet rules
181 ruleRhsFreeVars :: CoreRule -> VarSet
182 ruleRhsFreeVars (BuiltinRule _) = noFVs
183 ruleRhsFreeVars (Rule str tpl_vars tpl_args rhs)
184 = rule_fvs isLocalVar emptyVarSet
186 rule_fvs = addBndrs tpl_vars (expr_fvs rhs)
188 ruleSomeFreeVars :: InterestingVarFun -> CoreRule -> VarSet
189 ruleSomeFreeVars interesting (BuiltinRule _) = noFVs
190 ruleSomeFreeVars interesting (Rule _ tpl_vars tpl_args rhs)
191 = rule_fvs interesting emptyVarSet
193 rule_fvs = addBndrs tpl_vars $
194 foldr (union . expr_fvs) (expr_fvs rhs) tpl_args
196 ruleSomeLhsFreeVars :: InterestingVarFun -> CoreRule -> VarSet
197 ruleSomeLhsFreeVars fn (BuiltinRule _) = noFVs
198 ruleSomeLhsFreeVars fn (Rule _ tpl_vars tpl_args rhs)
199 = foldl delVarSet (exprsSomeFreeVars fn tpl_args) tpl_vars
203 %************************************************************************
205 \section[freevars-everywhere]{Attaching free variables to every sub-expression}
207 %************************************************************************
209 The free variable pass annotates every node in the expression with its
210 NON-GLOBAL free variables and type variables.
213 type CoreBindWithFVs = AnnBind Id VarSet
214 type CoreExprWithFVs = AnnExpr Id VarSet
215 -- Every node annotated with its free variables,
216 -- both Ids and TyVars
218 freeVarsOf :: CoreExprWithFVs -> IdSet
219 freeVarsOf (free_vars, _) = free_vars
222 aFreeVar = unitVarSet
223 unionFVs = unionVarSet
225 filters :: Var -> VarSet -> VarSet
227 -- (b `filters` s) removes the binder b from the free variable set s,
229 -- (a) the free variables of b's type
230 -- (b) the idSpecVars of b
232 -- This is really important for some lambdas:
233 -- In (\x::a -> x) the only mention of "a" is in the binder.
236 -- let x::a = b in ...
237 -- we should really note that "a" is free in this expression.
238 -- It'll be pinned inside the /\a by the binding for b, but
239 -- it seems cleaner to make sure that a is in the free-var set
240 -- when it is mentioned.
242 -- This also shows up in recursive bindings. Consider:
243 -- /\a -> letrec x::a = x in E
244 -- Now, there are no explicit free type variables in the RHS of x,
245 -- but nevertheless "a" is free in its definition. So we add in
246 -- the free tyvars of the types of the binders, and include these in the
247 -- free vars of the group, attached to the top level of each RHS.
249 -- This actually happened in the defn of errorIO in IOBase.lhs:
250 -- errorIO (ST io) = case (errorIO# io) of
253 -- bottom = bottom -- Never evaluated
255 filters b s | isId b = (s `delVarSet` b) `unionFVs` idFreeVars b
256 | otherwise = s `delVarSet` b
260 %************************************************************************
262 \subsection{Free variables (and types)}
264 %************************************************************************
267 freeVars :: CoreExpr -> CoreExprWithFVs
272 -- ToDo: insert motivating example for why we *need*
273 -- to include the idSpecVars in the FV list.
274 -- Actually [June 98] I don't think it's necessary
275 -- fvs = fvs_v `unionVarSet` idSpecVars v
277 fvs | isLocalVar v = aFreeVar v
280 freeVars (Lit lit) = (noFVs, AnnLit lit)
281 freeVars (Lam b body)
282 = (b `filters` freeVarsOf body', AnnLam b body')
284 body' = freeVars body
286 freeVars (App fun arg)
287 = (freeVarsOf fun2 `unionFVs` freeVarsOf arg2, AnnApp fun2 arg2)
292 freeVars (Case scrut bndr alts)
293 = ((bndr `filters` alts_fvs) `unionFVs` freeVarsOf scrut2,
294 AnnCase scrut2 bndr alts2)
296 scrut2 = freeVars scrut
298 (alts_fvs_s, alts2) = mapAndUnzip fv_alt alts
299 alts_fvs = foldr1 unionFVs alts_fvs_s
301 fv_alt (con,args,rhs) = (foldr filters (freeVarsOf rhs2) args,
306 freeVars (Let (NonRec binder rhs) body)
307 = (freeVarsOf rhs2 `unionFVs` body_fvs,
308 AnnLet (AnnNonRec binder rhs2) body2)
311 body2 = freeVars body
312 body_fvs = binder `filters` freeVarsOf body2
314 freeVars (Let (Rec binds) body)
315 = (foldl delVarSet group_fvs binders,
316 -- The "filters" part may have added one of the binders
317 -- via the idSpecVars part, so we must delete it again
318 AnnLet (AnnRec (binders `zip` rhss2)) body2)
320 (binders, rhss) = unzip binds
322 rhss2 = map freeVars rhss
323 all_fvs = foldr (unionFVs . fst) body_fvs rhss2
324 group_fvs = foldr filters all_fvs binders
326 body2 = freeVars body
327 body_fvs = freeVarsOf body2
329 freeVars (Note (Coerce to_ty from_ty) expr)
330 = (freeVarsOf expr2 `unionFVs` tfvs1 `unionFVs` tfvs2,
331 AnnNote (Coerce to_ty from_ty) expr2)
333 expr2 = freeVars expr
334 tfvs1 = tyVarsOfType from_ty
335 tfvs2 = tyVarsOfType to_ty
337 freeVars (Note other_note expr)
338 = (freeVarsOf expr2, AnnNote other_note expr2)
340 expr2 = freeVars expr
342 freeVars (Type ty) = (tyVarsOfType ty, AnnType ty)