2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 Taken quite directly from the Peyton Jones/Lester paper.
10 CoreExprWithFVs, CoreBindWithFVs
13 #include "HsVersions.h"
16 import CoreUtils ( idFreeVars )
19 import Var ( IdOrTyVar, isId )
20 import Name ( isLocallyDefined )
21 import Type ( tyVarsOfType, Type )
22 import Util ( mapAndUnzip )
25 %************************************************************************
27 \section[freevars-everywhere]{Attaching free variables to every sub-expression
29 %************************************************************************
31 The free variable pass annotates every node in the expression with its
32 NON-GLOBAL free variables and type variables.
35 type CoreBindWithFVs = AnnBind Id IdOrTyVarSet
36 type CoreExprWithFVs = AnnExpr Id IdOrTyVarSet
37 -- Every node annotated with its free variables,
38 -- both Ids and TyVars
40 freeVarsOf :: CoreExprWithFVs -> IdSet
41 freeVarsOf (free_vars, _) = free_vars
45 unionFVs = unionVarSet
47 filters :: IdOrTyVar -> IdOrTyVarSet -> IdOrTyVarSet
49 -- (b `filters` s) removes the binder b from the free variable set s,
51 -- (a) the free variables of b's type
52 -- (b) the idSpecVars of b
54 -- This is really important for some lambdas:
55 -- In (\x::a -> x) the only mention of "a" is in the binder.
58 -- let x::a = b in ...
59 -- we should really note that "a" is free in this expression.
60 -- It'll be pinned inside the /\a by the binding for b, but
61 -- it seems cleaner to make sure that a is in the free-var set
62 -- when it is mentioned.
64 -- This also shows up in recursive bindings. Consider:
65 -- /\a -> letrec x::a = x in E
66 -- Now, there are no explicit free type variables in the RHS of x,
67 -- but nevertheless "a" is free in its definition. So we add in
68 -- the free tyvars of the types of the binders, and include these in the
69 -- free vars of the group, attached to the top level of each RHS.
71 -- This actually happened in the defn of errorIO in IOBase.lhs:
72 -- errorIO (ST io) = case (errorIO# io) of
75 -- bottom = bottom -- Never evaluated
77 filters b s | isId b = (s `delVarSet` b) `unionFVs` idFreeVars b
78 | otherwise = s `delVarSet` b
82 %************************************************************************
84 \subsection{Free variables (and types)}
86 %************************************************************************
89 freeVars :: CoreExpr -> CoreExprWithFVs
94 -- ToDo: insert motivating example for why we *need*
95 -- to include the idSpecVars in the FV list.
96 -- Actually [June 98] I don't think it's necessary
97 -- fvs = fvs_v `unionVarSet` idSpecVars v
99 fvs | isLocallyDefined v = aFreeVar v
102 freeVars (Con con args)
103 = (foldr (unionFVs . freeVarsOf) noFVs args2, AnnCon con args2)
105 args2 = map freeVars args
107 freeVars (Lam b body)
108 = (b `filters` freeVarsOf body', AnnLam b body')
110 body' = freeVars body
112 freeVars (App fun arg)
113 = (freeVarsOf fun2 `unionFVs` freeVarsOf arg2, AnnApp fun2 arg2)
118 freeVars (Case scrut bndr alts)
119 = ((bndr `filters` alts_fvs) `unionFVs` freeVarsOf scrut2,
120 AnnCase scrut2 bndr alts2)
122 scrut2 = freeVars scrut
124 (alts_fvs_s, alts2) = mapAndUnzip fv_alt alts
125 alts_fvs = foldr1 unionFVs alts_fvs_s
127 fv_alt (con,args,rhs) = (foldr filters (freeVarsOf rhs2) args,
132 freeVars (Let (NonRec binder rhs) body)
133 = (freeVarsOf rhs2 `unionFVs` body_fvs,
134 AnnLet (AnnNonRec binder rhs2) body2)
137 body2 = freeVars body
138 body_fvs = binder `filters` freeVarsOf body2
140 freeVars (Let (Rec binds) body)
141 = (foldl delVarSet group_fvs binders,
142 -- The "filters" part may have added one of the binders
143 -- via the idSpecVars part, so we must delete it again
144 AnnLet (AnnRec (binders `zip` rhss2)) body2)
146 (binders, rhss) = unzip binds
148 rhss2 = map freeVars rhss
149 all_fvs = foldr (unionFVs . fst) body_fvs rhss2
150 group_fvs = foldr filters all_fvs binders
152 body2 = freeVars body
153 body_fvs = freeVarsOf body2
155 freeVars (Note (Coerce to_ty from_ty) expr)
156 = (freeVarsOf expr2 `unionFVs` tfvs1 `unionFVs` tfvs2,
157 AnnNote (Coerce to_ty from_ty) expr2)
159 expr2 = freeVars expr
160 tfvs1 = tyVarsOfType from_ty
161 tfvs2 = tyVarsOfType to_ty
163 freeVars (Note other_note expr)
164 = (freeVarsOf expr2, AnnNote other_note expr2)
166 expr2 = freeVars expr
168 freeVars (Type ty) = (tyVarsOfType ty, AnnType ty)