2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[CoreUtils]{Utility functions on @Core@ syntax}
9 InScopeSet, emptyInScopeSet,
10 lookupInScope, setInScope, extendInScope, extendInScopes, isInScope,
13 Subst, TyVarSubst, IdSubst,
14 emptySubst, mkSubst, substEnv, substInScope,
15 lookupSubst, isEmptySubst, extendSubst, extendSubstList,
16 zapSubstEnv, setSubstEnv,
18 bindSubst, unBindSubst, bindSubstList, unBindSubstList,
21 substBndr, substBndrs, substTyVar, substId, substIds,
22 substAndCloneId, substAndCloneIds,
25 mkTyVarSubst, mkTopTyVarSubst,
29 substExpr, substIdInfo
32 #include "HsVersions.h"
34 import CoreSyn ( Expr(..), Bind(..), Note(..), CoreExpr, CoreBndr,
35 CoreRules(..), CoreRule(..), emptyCoreRules, isEmptyCoreRules
37 import CoreFVs ( exprFreeVars )
38 import Type ( Type(..), ThetaType, TyNote(..),
39 tyVarsOfType, tyVarsOfTypes, mkAppTy
43 import Var ( setVarUnique, isId )
44 import Id ( idType, setIdType )
45 import IdInfo ( IdInfo, zapFragileIdInfo,
46 specInfo, setSpecInfo,
47 workerExists, workerInfo, setWorkerInfo, WorkerInfo
49 import UniqSupply ( UniqSupply, uniqFromSupply, splitUniqSupply )
50 import Var ( Var, IdOrTyVar, Id, TyVar, isTyVar, maybeModifyIdInfo )
52 import Util ( mapAccumL, foldl2, seqList, ($!) )
55 %************************************************************************
57 \subsection{Substitutions}
59 %************************************************************************
62 type InScopeSet = VarSet
64 data Subst = Subst InScopeSet -- In scope
65 SubstEnv -- Substitution itself
66 -- INVARIANT 1: The in-scope set is a superset
67 -- of the free vars of the range of the substitution
68 -- that might possibly clash with locally-bound variables
69 -- in the thing being substituted in.
70 -- This is what lets us deal with name capture properly
71 -- It's a hard invariant to check...
72 -- There are various ways of causing it to happen:
73 -- - arrange that the in-scope set really is all the things in scope
74 -- - arrange that it's the free vars of the range of the substitution
75 -- - make it empty because all the free vars of the subst are fresh,
76 -- and hence can't possibly clash.a
78 -- INVARIANT 2: No variable is both in scope and in the domain of the substitution
79 -- Equivalently, the substitution is idempotent
86 emptyInScopeSet :: InScopeSet
87 emptyInScopeSet = emptyVarSet
93 isEmptySubst :: Subst -> Bool
94 isEmptySubst (Subst _ env) = isEmptySubstEnv env
97 emptySubst = Subst emptyVarSet emptySubstEnv
99 mkSubst :: InScopeSet -> SubstEnv -> Subst
100 mkSubst in_scope env = Subst in_scope env
102 substEnv :: Subst -> SubstEnv
103 substEnv (Subst _ env) = env
105 substInScope :: Subst -> InScopeSet
106 substInScope (Subst in_scope _) = in_scope
108 zapSubstEnv :: Subst -> Subst
109 zapSubstEnv (Subst in_scope env) = Subst in_scope emptySubstEnv
111 extendSubst :: Subst -> Var -> SubstResult -> Subst
112 extendSubst (Subst in_scope env) v r = Subst in_scope (extendSubstEnv env v r)
114 extendSubstList :: Subst -> [Var] -> [SubstResult] -> Subst
115 extendSubstList (Subst in_scope env) v r = Subst in_scope (extendSubstEnvList env v r)
117 lookupSubst :: Subst -> Var -> Maybe SubstResult
118 lookupSubst (Subst _ env) v = lookupSubstEnv env v
120 lookupInScope :: Subst -> Var -> Maybe Var
121 lookupInScope (Subst in_scope _) v = lookupVarSet in_scope v
123 isInScope :: Var -> Subst -> Bool
124 isInScope v (Subst in_scope _) = v `elemVarSet` in_scope
126 extendInScope :: Subst -> Var -> Subst
127 extendInScope (Subst in_scope env) v = Subst (extendVarSet in_scope v) env
129 extendInScopes :: Subst -> [Var] -> Subst
130 extendInScopes (Subst in_scope env) vs = Subst (foldl extendVarSet in_scope vs) env
132 -------------------------------
133 bindSubst :: Subst -> Var -> Var -> Subst
134 -- Extend with a substitution, v1 -> Var v2
135 -- and extend the in-scopes with v2
136 bindSubst (Subst in_scope env) old_bndr new_bndr
137 = Subst (in_scope `extendVarSet` new_bndr)
138 (extendSubstEnv env old_bndr subst_result)
140 subst_result | isId old_bndr = DoneEx (Var new_bndr)
141 | otherwise = DoneTy (TyVarTy new_bndr)
143 unBindSubst :: Subst -> Var -> Var -> Subst
144 -- Reverse the effect of bindSubst
145 -- If old_bndr was already in the substitution, this doesn't quite work
146 unBindSubst (Subst in_scope env) old_bndr new_bndr
147 = Subst (in_scope `delVarSet` new_bndr) (delSubstEnv env old_bndr)
149 -- And the "List" forms
150 bindSubstList :: Subst -> [Var] -> [Var] -> Subst
151 bindSubstList subst old_bndrs new_bndrs
152 = foldl2 bindSubst subst old_bndrs new_bndrs
154 unBindSubstList :: Subst -> [Var] -> [Var] -> Subst
155 unBindSubstList subst old_bndrs new_bndrs
156 = foldl2 unBindSubst subst old_bndrs new_bndrs
159 -------------------------------
160 setInScope :: Subst -- Take env part from here
163 setInScope (Subst in_scope1 env1) in_scope2
164 = ASSERT( in_scope1 `subVarSet` in_scope1 )
167 setSubstEnv :: Subst -- Take in-scope part from here
168 -> SubstEnv -- ... and env part from here
170 setSubstEnv (Subst in_scope1 _) env2 = Subst in_scope1 env2
174 %************************************************************************
176 \subsection{Type substitution}
178 %************************************************************************
181 type TyVarSubst = Subst -- TyVarSubst are expected to have range elements
182 -- (We could have a variant of Subst, but it doesn't seem worth it.)
184 -- mkTyVarSubst generates the in-scope set from
185 -- the types given; but it's just a thunk so with a bit of luck
186 -- it'll never be evaluated
187 mkTyVarSubst :: [TyVar] -> [Type] -> Subst
188 mkTyVarSubst tyvars tys = Subst (tyVarsOfTypes tys) (zip_ty_env tyvars tys emptySubstEnv)
190 -- mkTopTyVarSubst is called when doing top-level substitutions.
191 -- Here we expect that the free vars of the range of the
192 -- substitution will be empty.
193 mkTopTyVarSubst :: [TyVar] -> [Type] -> Subst
194 mkTopTyVarSubst tyvars tys = Subst emptyVarSet (zip_ty_env tyvars tys emptySubstEnv)
196 zip_ty_env [] [] env = env
197 zip_ty_env (tv:tvs) (ty:tys) env = zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
200 substTy works with general Substs, so that it can be called from substExpr too.
203 substTy :: Subst -> Type -> Type
204 substTy subst ty | isEmptySubst subst = ty
205 | otherwise = subst_ty subst ty
207 substTheta :: TyVarSubst -> ThetaType -> ThetaType
208 substTheta subst theta
209 | isEmptySubst subst = theta
210 | otherwise = [(clas, map (subst_ty subst) tys) | (clas, tys) <- theta]
215 go (TyConApp tc tys) = let args = map go tys
216 in args `seqList` TyConApp tc args
217 go (NoteTy (SynNote ty1) ty2) = NoteTy (SynNote $! (go ty1)) $! (go ty2)
218 go (NoteTy (FTVNote _) ty2) = go ty2 -- Discard the free tyvar note
219 go (FunTy arg res) = (FunTy $! (go arg)) $! (go res)
220 go (NoteTy (UsgNote usg) ty2) = (NoteTy $! UsgNote usg) $! go ty2 -- Keep usage annot
221 go (AppTy fun arg) = mkAppTy (go fun) $! (go arg)
222 go ty@(TyVarTy tv) = case (lookupSubst subst tv) of
224 Just (DoneTy ty') -> ty'
226 go (ForAllTy tv ty) = case substTyVar subst tv of
227 (subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty)
230 Here is where we invent a new binder if necessary.
233 substTyVar :: Subst -> TyVar -> (Subst, TyVar)
234 substTyVar subst@(Subst in_scope env) old_var
235 | old_var == new_var -- No need to clone
236 -- But we *must* zap any current substitution for the variable.
238 -- (\x.e) with id_subst = [x |-> e']
239 -- Here we must simply zap the substitution for x
241 -- The new_id isn't cloned, but it may have a different type
242 -- etc, so we must return it, not the old id
243 = (Subst (in_scope `extendVarSet` new_var)
244 (delSubstEnv env old_var),
247 | otherwise -- The new binder is in scope so
248 -- we'd better rename it away from the in-scope variables
249 -- Extending the substitution to do this renaming also
250 -- has the (correct) effect of discarding any existing
251 -- substitution for that variable
252 = (Subst (in_scope `extendVarSet` new_var)
253 (extendSubstEnv env old_var (DoneTy (TyVarTy new_var))),
256 new_var = uniqAway in_scope old_var
257 -- The uniqAway part makes sure the new variable is not already in scope
261 %************************************************************************
263 \section{Expression substitution}
265 %************************************************************************
267 This expression substituter deals correctly with name capture.
269 BUT NOTE that substExpr silently discards the
272 IdInfo attached to any binders in the expression. It's quite
273 tricky to do them 'right' in the case of mutually recursive bindings,
274 and so far has proved unnecessary.
277 substExpr :: Subst -> CoreExpr -> CoreExpr
278 substExpr subst expr | isEmptySubst subst = expr
279 | otherwise = subst_expr subst expr
281 subst_expr subst expr
284 go (Var v) = case lookupSubst subst v of
285 Just (DoneEx e') -> e'
286 Just (ContEx env' e') -> subst_expr (setSubstEnv subst env') e'
287 Nothing -> case lookupInScope subst v of
290 -- NB: we look up in the in_scope set because the variable
291 -- there may have more info. In particular, when substExpr
292 -- is called from the simplifier, the type inside the *occurrences*
293 -- of a variable may not be right; we should replace it with the
294 -- binder, from the in_scope set.
296 go (Type ty) = Type (go_ty ty)
297 go (Con con args) = Con con (map go args)
298 go (App fun arg) = App (go fun) (go arg)
299 go (Note note e) = Note (go_note note) (go e)
301 go (Lam bndr body) = Lam bndr' (subst_expr subst' body)
303 (subst', bndr') = substBndr subst bndr
305 go (Let (NonRec bndr rhs) body) = Let (NonRec bndr' (go rhs)) (subst_expr subst' body)
307 (subst', bndr') = substBndr subst bndr
309 go (Let (Rec pairs) body) = Let (Rec pairs') (subst_expr subst' body)
311 (subst', bndrs') = substBndrs subst (map fst pairs)
312 pairs' = bndrs' `zip` rhss'
313 rhss' = map (subst_expr subst' . snd) pairs
315 go (Case scrut bndr alts) = Case (go scrut) bndr' (map (go_alt subst') alts)
317 (subst', bndr') = substBndr subst bndr
319 go_alt subst (con, bndrs, rhs) = (con, bndrs', subst_expr subst' rhs)
321 (subst', bndrs') = substBndrs subst bndrs
323 go_note (Coerce ty1 ty2) = Coerce (go_ty ty1) (go_ty ty2)
326 go_ty ty = substTy subst ty
330 Substituting in binders is a rather tricky part of the whole compiler.
332 When we hit a binder we may need to
333 (a) apply the the type envt (if non-empty) to its type
334 (b) apply the type envt and id envt to its SpecEnv (if it has one)
335 (c) give it a new unique to avoid name clashes
338 substBndr :: Subst -> IdOrTyVar -> (Subst, IdOrTyVar)
340 | isTyVar bndr = substTyVar subst bndr
341 | otherwise = substId subst bndr
343 substBndrs :: Subst -> [IdOrTyVar] -> (Subst, [IdOrTyVar])
344 substBndrs subst bndrs = mapAccumL substBndr subst bndrs
347 substIds :: Subst -> [Id] -> (Subst, [Id])
348 substIds subst bndrs = mapAccumL substId subst bndrs
350 substId :: Subst -> Id -> (Subst, Id)
352 -- Returns an Id with empty unfolding and spec-env.
353 -- It's up to the caller to sort these out.
355 substId subst@(Subst in_scope env) old_id
356 = (Subst (in_scope `extendVarSet` new_id)
357 (extendSubstEnv env old_id (DoneEx (Var new_id))),
360 id_ty = idType old_id
362 -- id1 has its type zapped
363 id1 | noTypeSubst env
364 || isEmptyVarSet (tyVarsOfType id_ty) = old_id
365 -- The tyVarsOfType is cheaper than it looks
366 -- because we cache the free tyvars of the type
367 -- in a Note in the id's type itself
368 | otherwise = setIdType old_id (substTy subst id_ty)
370 -- id2 has its fragile IdInfo zapped
371 id2 = maybeModifyIdInfo zapFragileIdInfo id1
373 -- new_id is cloned if necessary
374 new_id = uniqAway in_scope id2
377 Now a variant that unconditionally allocates a new unique.
380 substAndCloneIds :: Subst -> UniqSupply -> [Id] -> (Subst, UniqSupply, [Id])
381 substAndCloneIds subst us [] = (subst, us, [])
382 substAndCloneIds subst us (b:bs) = case substAndCloneId subst us b of { (subst1, us1, b') ->
383 case substAndCloneIds subst1 us1 bs of { (subst2, us2, bs') ->
384 (subst2, us2, (b':bs')) }}
386 substAndCloneId :: Subst -> UniqSupply -> Id -> (Subst, UniqSupply, Id)
387 substAndCloneId subst@(Subst in_scope env) us old_id
388 = (Subst (in_scope `extendVarSet` new_id)
389 (extendSubstEnv env old_id (DoneEx (Var new_id))),
393 id_ty = idType old_id
394 id1 | noTypeSubst env || isEmptyVarSet (tyVarsOfType id_ty) = old_id
395 | otherwise = setIdType old_id (substTy subst id_ty)
397 id2 = maybeModifyIdInfo zapFragileIdInfo id1
398 new_id = setVarUnique id2 (uniqFromSupply us1)
399 (us1,new_us) = splitUniqSupply us
403 %************************************************************************
405 \section{IdInfo substitution}
407 %************************************************************************
410 substIdInfo :: Subst -> IdInfo -> IdInfo
411 substIdInfo subst info
414 info1 | isEmptyCoreRules old_rules = info
415 | otherwise = info `setSpecInfo` substRules subst old_rules
417 info2 | not (workerExists old_wrkr) = info1
418 | otherwise = info1 `setWorkerInfo` substWorker subst old_wrkr
420 old_rules = specInfo info
421 old_wrkr = workerInfo info
423 substWorker :: Subst -> WorkerInfo -> WorkerInfo
424 substWorker subst Nothing
426 substWorker subst (Just w)
427 = case lookupSubst subst w of
429 Just (DoneEx (Var w1)) -> Just w1
430 Just (DoneEx other) -> WARN( True, text "substWorker: DoneEx" <+> ppr w )
431 Nothing -- Worker has got substituted away altogether
432 Just (ContEx se1 e) -> WARN( True, text "substWorker: ContEx" <+> ppr w )
435 substRules :: Subst -> CoreRules -> CoreRules
436 substRules subst (Rules rules rhs_fvs)
437 = Rules (map do_subst rules)
438 (subst_fvs (substEnv subst) rhs_fvs)
440 do_subst (Rule name tpl_vars lhs_args rhs)
441 = Rule name tpl_vars'
442 (map (substExpr subst') lhs_args)
443 (substExpr subst' rhs)
445 (subst', tpl_vars') = substBndrs subst tpl_vars
448 = foldVarSet (unionVarSet . subst_fv) emptyVarSet rhs_fvs
450 subst_fv fv = case lookupSubstEnv se fv of
451 Nothing -> unitVarSet fv
452 Just (DoneEx expr) -> exprFreeVars expr
453 Just (DoneTy ty) -> tyVarsOfType ty
454 Just (ContEx se' expr) -> subst_fvs se' (exprFreeVars expr)