2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[CoreUtils]{Utility functions on @Core@ syntax}
9 InScopeSet, emptyInScopeSet, mkInScopeSet,
10 extendInScopeSet, extendInScopeSetList,
11 lookupInScope, elemInScopeSet, uniqAway,
15 Subst, TyVarSubst, IdSubst,
16 emptySubst, mkSubst, substEnv, substInScope,
17 lookupSubst, lookupIdSubst, isEmptySubst, extendSubst, extendSubstList,
18 zapSubstEnv, setSubstEnv,
20 extendInScope, extendInScopeList, extendNewInScope, extendNewInScopeList,
21 isInScope, modifyInScope,
23 bindSubst, unBindSubst, bindSubstList, unBindSubstList,
26 simplBndr, simplBndrs, simplLetId, simplIdInfo,
27 substAndCloneId, substAndCloneIds, substAndCloneRecIds,
30 mkTyVarSubst, mkTopTyVarSubst,
34 substExpr, substIdInfo
37 #include "HsVersions.h"
39 import CmdLineOpts ( opt_PprStyle_Debug )
40 import CoreSyn ( Expr(..), Bind(..), Note(..), CoreExpr,
41 CoreRules(..), CoreRule(..),
42 isEmptyCoreRules, seqRules, hasUnfolding, noUnfolding
44 import CoreFVs ( exprFreeVars )
45 import TypeRep ( Type(..), TyNote(..) ) -- friend
46 import Type ( ThetaType, SourceType(..), PredType,
47 tyVarsOfType, tyVarsOfTypes, mkAppTy, mkUTy, isUTy,
52 import Var ( setVarUnique, isId, mustHaveLocalBinding )
53 import Id ( idType, idInfo, setIdInfo, setIdType,
54 idOccInfo, maybeModifyIdInfo )
55 import IdInfo ( IdInfo, vanillaIdInfo,
56 occInfo, isFragileOcc, setOccInfo,
57 specInfo, setSpecInfo,
58 unfoldingInfo, setUnfoldingInfo,
59 WorkerInfo(..), workerExists, workerInfo, setWorkerInfo, WorkerInfo,
60 lbvarInfo, LBVarInfo(..), setLBVarInfo, hasNoLBVarInfo
62 import BasicTypes ( OccInfo(..) )
63 import Unique ( Unique, Uniquable(..), deriveUnique )
64 import UniqSet ( elemUniqSet_Directly )
65 import UniqSupply ( UniqSupply, uniqFromSupply, uniqsFromSupply )
66 import Var ( Var, Id, TyVar, isTyVar )
68 import PprCore () -- Instances
69 import UniqFM ( ufmToList ) -- Yuk (add a new op to VarEnv)
70 import Util ( mapAccumL, foldl2, seqList )
75 %************************************************************************
77 \subsection{The in-scope set}
79 %************************************************************************
82 data InScopeSet = InScope (VarEnv Var) FastInt
83 -- The Int# is a kind of hash-value used by uniqAway
84 -- For example, it might be the size of the set
85 -- INVARIANT: it's not zero; we use it as a multiplier in uniqAway
87 emptyInScopeSet :: InScopeSet
88 emptyInScopeSet = InScope emptyVarSet 1#
90 mkInScopeSet :: VarEnv Var -> InScopeSet
91 mkInScopeSet in_scope = InScope in_scope 1#
93 extendInScopeSet :: InScopeSet -> Var -> InScopeSet
94 extendInScopeSet (InScope in_scope n) v = InScope (extendVarEnv in_scope v v) (n +# 1#)
96 extendInScopeSetList :: InScopeSet -> [Var] -> InScopeSet
97 extendInScopeSetList (InScope in_scope n) vs
98 = InScope (foldl (\s v -> extendVarEnv s v v) in_scope vs)
99 (n +# iUnbox (length vs))
101 modifyInScopeSet :: InScopeSet -> Var -> Var -> InScopeSet
102 -- Exploit the fact that the in-scope "set" is really a map
103 -- Make old_v map to new_v
104 modifyInScopeSet (InScope in_scope n) old_v new_v = InScope (extendVarEnv in_scope old_v new_v) (n +# 1#)
106 delInScopeSet :: InScopeSet -> Var -> InScopeSet
107 delInScopeSet (InScope in_scope n) v = InScope (in_scope `delVarEnv` v) n
109 elemInScopeSet :: Var -> InScopeSet -> Bool
110 elemInScopeSet v (InScope in_scope n) = v `elemVarEnv` in_scope
112 lookupInScope :: InScopeSet -> Var -> Var
113 -- It's important to look for a fixed point
114 -- When we see (case x of y { I# v -> ... })
115 -- we add [x -> y] to the in-scope set (Simplify.simplCaseBinder).
116 -- When we lookup up an occurrence of x, we map to y, but then
117 -- we want to look up y in case it has acquired more evaluation information by now.
118 lookupInScope (InScope in_scope n) v
121 go v = case lookupVarEnv in_scope v of
122 Just v' | v == v' -> v' -- Reached a fixed point
124 Nothing -> WARN( mustHaveLocalBinding v, ppr v )
129 uniqAway :: InScopeSet -> Var -> Var
130 -- (uniqAway in_scope v) finds a unique that is not used in the
131 -- in-scope set, and gives that to v. It starts with v's current unique, of course,
132 -- in the hope that it won't have to change it, nad thereafter uses a combination
133 -- of that and the hash-code found in the in-scope set
134 uniqAway (InScope set n) var
135 | not (var `elemVarSet` set) = var -- Nothing to do
138 orig_unique = getUnique var
142 = pprPanic "uniqAway loop:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n))
144 | uniq `elemUniqSet_Directly` set = try (k +# 1#)
146 | opt_PprStyle_Debug && k ># 3#
147 = pprTrace "uniqAway:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n))
148 setVarUnique var uniq
150 | otherwise = setVarUnique var uniq
152 uniq = deriveUnique orig_unique (iBox (n *# k))
156 %************************************************************************
158 \subsection{Substitutions}
160 %************************************************************************
163 data Subst = Subst InScopeSet -- In scope
164 SubstEnv -- Substitution itself
165 -- INVARIANT 1: The (domain of the) in-scope set is a superset
166 -- of the free vars of the range of the substitution
167 -- that might possibly clash with locally-bound variables
168 -- in the thing being substituted in.
169 -- This is what lets us deal with name capture properly
170 -- It's a hard invariant to check...
171 -- There are various ways of causing it to happen:
172 -- - arrange that the in-scope set really is all the things in scope
173 -- - arrange that it's the free vars of the range of the substitution
174 -- - make it empty because all the free vars of the subst are fresh,
175 -- and hence can't possibly clash.a
177 -- INVARIANT 2: No variable is both in scope and in the domain of the substitution
178 -- Equivalently, the substitution is idempotent
179 -- [Sep 2000: Lies, all lies. The substitution now does contain
180 -- mappings x77 -> DoneId x77 occ
181 -- to record x's occurrence information.]
182 -- [Also watch out: the substitution can contain x77 -> DoneEx (Var x77)
183 -- Consider let x = case k of I# x77 -> ... in
184 -- let y = case k of I# x77 -> ... in ...
185 -- and suppose the body is strict in both x and y. Then the simplifier
186 -- will pull the first (case k) to the top; so the second (case k) will
187 -- cancel out, mapping x77 to, well, x77! But one is an in-Id and the
188 -- other is an out-Id. So the substitution is idempotent in the sense
189 -- that we *must not* repeatedly apply it.]
194 The general plan about the substitution and in-scope set for Ids is as follows
196 * substId always adds new_id to the in-scope set.
197 new_id has a correctly-substituted type, occ info
199 * substId adds a binding (DoneId new_id occ) to the substitution if
200 EITHER the Id's unique has changed
201 OR the Id has interesting occurrence information
202 So in effect you can only get to interesting occurrence information
203 by looking up the *old* Id; it's not really attached to the new id
206 Note, though that the substitution isn't necessarily extended
207 if the type changes. Why not? Because of the next point:
209 * We *always, always* finish by looking up in the in-scope set
210 any variable that doesn't get a DoneEx or DoneVar hit in the substitution.
211 Reason: so that we never finish up with a "old" Id in the result.
212 An old Id might point to an old unfolding and so on... which gives a space leak.
214 [The DoneEx and DoneVar hits map to "new" stuff.]
216 * It follows that substExpr must not do a no-op if the substitution is empty.
217 substType is free to do so, however.
219 * When we come to a let-binding (say) we generate new IdInfo, including an
220 unfolding, attach it to the binder, and add this newly adorned binder to
221 the in-scope set. So all subsequent occurrences of the binder will get mapped
222 to the full-adorned binder, which is also the one put in the binding site.
224 * The in-scope "set" usually maps x->x; we use it simply for its domain.
225 But sometimes we have two in-scope Ids that are synomyms, and should
226 map to the same target: x->x, y->x. Notably:
228 That's why the "set" is actually a VarEnv Var
232 isEmptySubst :: Subst -> Bool
233 isEmptySubst (Subst _ env) = isEmptySubstEnv env
236 emptySubst = Subst emptyInScopeSet emptySubstEnv
238 mkSubst :: InScopeSet -> SubstEnv -> Subst
239 mkSubst in_scope env = Subst in_scope env
241 substEnv :: Subst -> SubstEnv
242 substEnv (Subst _ env) = env
244 substInScope :: Subst -> InScopeSet
245 substInScope (Subst in_scope _) = in_scope
247 zapSubstEnv :: Subst -> Subst
248 zapSubstEnv (Subst in_scope env) = Subst in_scope emptySubstEnv
250 extendSubst :: Subst -> Var -> SubstResult -> Subst
251 extendSubst (Subst in_scope env) v r = UASSERT( case r of { DoneTy ty -> not (isUTy ty) ; _ -> True } )
252 Subst in_scope (extendSubstEnv env v r)
254 extendSubstList :: Subst -> [Var] -> [SubstResult] -> Subst
255 extendSubstList (Subst in_scope env) v r = UASSERT( all (\ r1 -> case r1 of { DoneTy ty -> not (isUTy ty) ; _ -> True }) r )
256 Subst in_scope (extendSubstEnvList env v r)
258 lookupSubst :: Subst -> Var -> Maybe SubstResult
259 lookupSubst (Subst _ env) v = lookupSubstEnv env v
261 lookupIdSubst :: Subst -> Id -> SubstResult
262 -- Does the lookup in the in-scope set too
263 lookupIdSubst (Subst in_scope env) v
264 = case lookupSubstEnv env v of
265 Just (DoneId v' occ) -> DoneId (lookupInScope in_scope v') occ
267 Nothing -> DoneId v' (idOccInfo v')
268 -- We don't use DoneId for LoopBreakers, so the idOccInfo is
269 -- very important! If isFragileOcc returned True for
270 -- loop breakers we could avoid this call, but at the expense
271 -- of adding more to the substitution, and building new Ids
272 -- in substId a bit more often than really necessary
274 v' = lookupInScope in_scope v
276 isInScope :: Var -> Subst -> Bool
277 isInScope v (Subst in_scope _) = v `elemInScopeSet` in_scope
279 modifyInScope :: Subst -> Var -> Var -> Subst
280 modifyInScope (Subst in_scope env) old_v new_v = Subst (modifyInScopeSet in_scope old_v new_v) env
281 -- make old_v map to new_v
283 extendInScope :: Subst -> Var -> Subst
284 -- Add a new variable as in-scope
285 -- Remember to delete any existing binding in the substitution!
286 extendInScope (Subst in_scope env) v = Subst (in_scope `extendInScopeSet` v)
287 (env `delSubstEnv` v)
289 extendInScopeList :: Subst -> [Var] -> Subst
290 extendInScopeList (Subst in_scope env) vs = Subst (extendInScopeSetList in_scope vs)
291 (delSubstEnvList env vs)
293 -- The "New" variants are guaranteed to be adding freshly-allocated variables
294 -- It's not clear that the gain (not needing to delete it from the substitution)
295 -- is worth the extra proof obligation
296 extendNewInScope :: Subst -> Var -> Subst
297 extendNewInScope (Subst in_scope env) v = Subst (in_scope `extendInScopeSet` v) env
299 extendNewInScopeList :: Subst -> [Var] -> Subst
300 extendNewInScopeList (Subst in_scope env) vs = Subst (in_scope `extendInScopeSetList` vs) env
302 -------------------------------
303 bindSubst :: Subst -> Var -> Var -> Subst
304 -- Extend with a substitution, v1 -> Var v2
305 -- and extend the in-scopes with v2
306 bindSubst (Subst in_scope env) old_bndr new_bndr
307 = Subst (in_scope `extendInScopeSet` new_bndr)
308 (extendSubstEnv env old_bndr subst_result)
310 subst_result | isId old_bndr = DoneEx (Var new_bndr)
311 | otherwise = DoneTy (TyVarTy new_bndr)
313 unBindSubst :: Subst -> Var -> Var -> Subst
314 -- Reverse the effect of bindSubst
315 -- If old_bndr was already in the substitution, this doesn't quite work
316 unBindSubst (Subst in_scope env) old_bndr new_bndr
317 = Subst (in_scope `delInScopeSet` new_bndr) (delSubstEnv env old_bndr)
319 -- And the "List" forms
320 bindSubstList :: Subst -> [Var] -> [Var] -> Subst
321 bindSubstList subst old_bndrs new_bndrs
322 = foldl2 bindSubst subst old_bndrs new_bndrs
324 unBindSubstList :: Subst -> [Var] -> [Var] -> Subst
325 unBindSubstList subst old_bndrs new_bndrs
326 = foldl2 unBindSubst subst old_bndrs new_bndrs
329 -------------------------------
330 setInScope :: Subst -- Take env part from here
333 setInScope (Subst in_scope1 env1) in_scope2
334 = Subst in_scope2 env1
336 setSubstEnv :: Subst -- Take in-scope part from here
337 -> SubstEnv -- ... and env part from here
339 setSubstEnv (Subst in_scope1 _) env2 = Subst in_scope1 env2
342 Pretty printing, for debugging only
345 instance Outputable SubstResult where
346 ppr (DoneEx e) = ptext SLIT("DoneEx") <+> ppr e
347 ppr (DoneId v _) = ptext SLIT("DoneId") <+> ppr v
348 ppr (ContEx _ e) = ptext SLIT("ContEx") <+> ppr e
349 ppr (DoneTy t) = ptext SLIT("DoneTy") <+> ppr t
351 instance Outputable SubstEnv where
352 ppr se = brackets (fsep (punctuate comma (map ppr_elt (ufmToList (substEnvEnv se)))))
354 ppr_elt (uniq,sr) = ppr uniq <+> ptext SLIT("->") <+> ppr sr
356 instance Outputable Subst where
357 ppr (Subst (InScope in_scope _) se)
358 = ptext SLIT("<InScope =") <+> braces (fsep (map ppr (rngVarEnv in_scope)))
359 $$ ptext SLIT(" Subst =") <+> ppr se <> char '>'
362 %************************************************************************
364 \subsection{Type substitution}
366 %************************************************************************
369 type TyVarSubst = Subst -- TyVarSubst are expected to have range elements
370 -- (We could have a variant of Subst, but it doesn't seem worth it.)
372 -- mkTyVarSubst generates the in-scope set from
373 -- the types given; but it's just a thunk so with a bit of luck
374 -- it'll never be evaluated
375 mkTyVarSubst :: [TyVar] -> [Type] -> Subst
376 mkTyVarSubst tyvars tys = Subst (mkInScopeSet (tyVarsOfTypes tys)) (zip_ty_env tyvars tys emptySubstEnv)
378 -- mkTopTyVarSubst is called when doing top-level substitutions.
379 -- Here we expect that the free vars of the range of the
380 -- substitution will be empty.
381 mkTopTyVarSubst :: [TyVar] -> [Type] -> Subst
382 mkTopTyVarSubst tyvars tys = Subst emptyInScopeSet (zip_ty_env tyvars tys emptySubstEnv)
384 zip_ty_env [] [] env = env
385 zip_ty_env (tv:tvs) (ty:tys) env
386 | Just tv' <- getTyVar_maybe ty, tv==tv' = zip_ty_env tvs tys env
387 -- Shortcut for the (I think not uncommon) case where we are
388 -- making an identity substitution
389 | otherwise = zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
392 substTy works with general Substs, so that it can be called from substExpr too.
395 substTy :: Subst -> Type -> Type
396 substTy subst ty | isEmptySubst subst = ty
397 | otherwise = subst_ty subst ty
399 substTheta :: TyVarSubst -> ThetaType -> ThetaType
400 substTheta subst theta
401 | isEmptySubst subst = theta
402 | otherwise = map (substPred subst) theta
404 substPred :: TyVarSubst -> PredType -> PredType
405 substPred = substSourceType
407 substSourceType subst (IParam n ty) = IParam n (subst_ty subst ty)
408 substSourceType subst (ClassP clas tys) = ClassP clas (map (subst_ty subst) tys)
409 substSourceType subst (NType tc tys) = NType tc (map (subst_ty subst) tys)
414 go (TyConApp tc tys) = let args = map go tys
415 in args `seqList` TyConApp tc args
417 go (SourceTy p) = SourceTy $! (substSourceType subst p)
419 go (NoteTy (SynNote ty1) ty2) = NoteTy (SynNote $! (go ty1)) $! (go ty2)
420 go (NoteTy (FTVNote _) ty2) = go ty2 -- Discard the free tyvar note
422 go (FunTy arg res) = (FunTy $! (go arg)) $! (go res)
423 go (AppTy fun arg) = mkAppTy (go fun) $! (go arg)
424 go ty@(TyVarTy tv) = case (lookupSubst subst tv) of
426 Just (DoneTy ty') -> ty'
428 go (ForAllTy tv ty) = case substTyVar subst tv of
429 (subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty)
431 go (UsageTy u ty) = mkUTy (go u) $! (go ty)
434 Here is where we invent a new binder if necessary.
437 substTyVar :: Subst -> TyVar -> (Subst, TyVar)
438 substTyVar subst@(Subst in_scope env) old_var
439 | old_var == new_var -- No need to clone
440 -- But we *must* zap any current substitution for the variable.
442 -- (\x.e) with id_subst = [x |-> e']
443 -- Here we must simply zap the substitution for x
445 -- The new_id isn't cloned, but it may have a different type
446 -- etc, so we must return it, not the old id
447 = (Subst (in_scope `extendInScopeSet` new_var)
448 (delSubstEnv env old_var),
451 | otherwise -- The new binder is in scope so
452 -- we'd better rename it away from the in-scope variables
453 -- Extending the substitution to do this renaming also
454 -- has the (correct) effect of discarding any existing
455 -- substitution for that variable
456 = (Subst (in_scope `extendInScopeSet` new_var)
457 (extendSubstEnv env old_var (DoneTy (TyVarTy new_var))),
460 new_var = uniqAway in_scope old_var
461 -- The uniqAway part makes sure the new variable is not already in scope
465 %************************************************************************
467 \section{Expression substitution}
469 %************************************************************************
471 This expression substituter deals correctly with name capture.
473 BUT NOTE that substExpr silently discards the
476 IdInfo attached to any binders in the expression. It's quite
477 tricky to do them 'right' in the case of mutually recursive bindings,
478 and so far has proved unnecessary.
481 substExpr :: Subst -> CoreExpr -> CoreExpr
483 -- NB: we do not do a no-op when the substitution is empty,
484 -- because we always want to substitute the variables in the
485 -- in-scope set for their occurrences. Why?
486 -- (a) because they may contain more information
487 -- (b) because leaving an un-substituted Id might cause
488 -- a space leak (its unfolding might point to an old version
489 -- of its right hand side).
493 go (Var v) = -- See the notes at the top, with the Subst data type declaration
494 case lookupIdSubst subst v of
496 ContEx env' e' -> substExpr (setSubstEnv subst env') e'
500 go (Type ty) = Type (go_ty ty)
501 go (Lit lit) = Lit lit
502 go (App fun arg) = App (go fun) (go arg)
503 go (Note note e) = Note (go_note note) (go e)
505 go (Lam bndr body) = Lam bndr' (substExpr subst' body)
507 (subst', bndr') = substBndr subst bndr
509 go (Let (NonRec bndr rhs) body) = Let (NonRec bndr' (go rhs)) (substExpr subst' body)
511 (subst', bndr') = substBndr subst bndr
513 go (Let (Rec pairs) body) = Let (Rec pairs') (substExpr subst' body)
515 (subst', bndrs') = substRecIds subst (map fst pairs)
516 pairs' = bndrs' `zip` rhss'
517 rhss' = map (substExpr subst' . snd) pairs
519 go (Case scrut bndr alts) = Case (go scrut) bndr' (map (go_alt subst') alts)
521 (subst', bndr') = substBndr subst bndr
523 go_alt subst (con, bndrs, rhs) = (con, bndrs', substExpr subst' rhs)
525 (subst', bndrs') = substBndrs subst bndrs
527 go_note (Coerce ty1 ty2) = Coerce (go_ty ty1) (go_ty ty2)
530 go_ty ty = substTy subst ty
535 %************************************************************************
537 \section{Substituting an Id binder}
539 %************************************************************************
542 -- simplBndr and simplLetId are used by the simplifier
544 simplBndr :: Subst -> Var -> (Subst, Var)
545 -- Used for lambda and case-bound variables
546 -- Clone Id if necessary, substitute type
547 -- Return with IdInfo already substituted, but (fragile) occurrence info zapped
548 -- The substitution is extended only if the variable is cloned, because
549 -- we *don't* need to use it to track occurrence info.
551 | isTyVar bndr = substTyVar subst bndr
552 | otherwise = subst_id isFragileOcc subst subst bndr
554 simplBndrs :: Subst -> [Var] -> (Subst, [Var])
555 simplBndrs subst bndrs = mapAccumL simplBndr subst bndrs
557 simplLetId :: Subst -> Id -> (Subst, Id)
558 -- Clone Id if necessary
559 -- Substitute its type
560 -- Return an Id with completely zapped IdInfo
561 -- [A subsequent substIdInfo will restore its IdInfo]
562 -- Augment the subtitution
563 -- if the unique changed, *or*
564 -- if there's interesting occurrence info
566 simplLetId subst@(Subst in_scope env) old_id
567 = (Subst (in_scope `extendInScopeSet` new_id) new_env, new_id)
569 old_info = idInfo old_id
570 id1 = uniqAway in_scope old_id
571 id2 = substIdType subst id1
572 new_id = setIdInfo id2 vanillaIdInfo
574 -- Extend the substitution if the unique has changed,
575 -- or there's some useful occurrence information
576 -- See the notes with substTyVar for the delSubstEnv
577 occ_info = occInfo old_info
578 new_env | new_id /= old_id || isFragileOcc occ_info
579 = extendSubstEnv env old_id (DoneId new_id occ_info)
581 = delSubstEnv env old_id
583 simplIdInfo :: Subst -> IdInfo -> Id -> Id
584 -- Used by the simplifier to compute new IdInfo for a let(rec) binder,
585 -- subsequent to simplLetId having zapped its IdInfo
586 simplIdInfo subst old_info bndr
587 = case substIdInfo subst isFragileOcc old_info of
588 Just new_info -> bndr `setIdInfo` new_info
589 Nothing -> bndr `setIdInfo` old_info
593 -- substBndr and friends are used when doing expression substitution only
594 -- In this case we can *preserve* occurrence information, and indeed we *want*
595 -- to do so else lose useful occ info in rules. Hence the calls to
596 -- simpl_id with keepOccInfo
598 substBndr :: Subst -> Var -> (Subst, Var)
600 | isTyVar bndr = substTyVar subst bndr
601 | otherwise = subst_id keepOccInfo subst subst bndr
603 substBndrs :: Subst -> [Var] -> (Subst, [Var])
604 substBndrs subst bndrs = mapAccumL substBndr subst bndrs
606 substRecIds :: Subst -> [Id] -> (Subst, [Id])
607 -- Substitute a mutually recursive group
608 substRecIds subst bndrs
609 = (new_subst, new_bndrs)
611 -- Here's the reason we need to pass rec_subst to subst_id
612 (new_subst, new_bndrs) = mapAccumL (subst_id keepOccInfo new_subst) subst bndrs
614 keepOccInfo occ = False -- Never fragile
619 subst_id :: (OccInfo -> Bool) -- True <=> the OccInfo is fragile
620 -> Subst -- Substitution to use for the IdInfo
621 -> Subst -> Id -- Substitition and Id to transform
622 -> (Subst, Id) -- Transformed pair
625 -- * Unique changed if necessary
626 -- * Type substituted
627 -- * Unfolding zapped
628 -- * Rules, worker, lbvar info all substituted
629 -- * Occurrence info zapped if is_fragile_occ returns True
630 -- * The in-scope set extended with the returned Id
631 -- * The substitution extended with a DoneId if unique changed
632 -- In this case, the var in the DoneId is the same as the
635 subst_id is_fragile_occ rec_subst subst@(Subst in_scope env) old_id
636 = (Subst (in_scope `extendInScopeSet` new_id) new_env, new_id)
638 -- id1 is cloned if necessary
639 id1 = uniqAway in_scope old_id
641 -- id2 has its type zapped
642 id2 = substIdType subst id1
644 -- new_id has the right IdInfo
645 -- The lazy-set is because we're in a loop here, with
646 -- rec_subst, when dealing with a mutually-recursive group
647 new_id = maybeModifyIdInfo (substIdInfo rec_subst is_fragile_occ) id2
649 -- Extend the substitution if the unique has changed
650 -- See the notes with substTyVar for the delSubstEnv
651 new_env | new_id /= old_id
652 = extendSubstEnv env old_id (DoneId new_id (idOccInfo old_id))
654 = delSubstEnv env old_id
657 Now a variant that unconditionally allocates a new unique.
658 It also unconditionally zaps the OccInfo.
661 subst_clone_id :: Subst -- Substitution to use (lazily) for the rules and worker
662 -> Subst -> (Id, Unique) -- Substitition and Id to transform
663 -> (Subst, Id) -- Transformed pair
665 subst_clone_id rec_subst subst@(Subst in_scope env) (old_id, uniq)
666 = (Subst (in_scope `extendInScopeSet` new_id) new_env, new_id)
668 id1 = setVarUnique old_id uniq
669 id2 = substIdType subst id1
671 new_id = maybeModifyIdInfo (substIdInfo rec_subst isFragileOcc) id2
672 new_env = extendSubstEnv env old_id (DoneId new_id NoOccInfo)
674 substAndCloneIds :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
675 substAndCloneIds subst us ids
676 = mapAccumL (subst_clone_id subst) subst (ids `zip` uniqsFromSupply us)
678 substAndCloneRecIds :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
679 substAndCloneRecIds subst us ids
682 (subst', ids') = mapAccumL (subst_clone_id subst') subst
683 (ids `zip` uniqsFromSupply us)
685 substAndCloneId :: Subst -> UniqSupply -> Id -> (Subst, Id)
686 substAndCloneId subst@(Subst in_scope env) us old_id
687 = subst_clone_id subst subst (old_id, uniqFromSupply us)
691 %************************************************************************
693 \section{IdInfo substitution}
695 %************************************************************************
699 -> (OccInfo -> Bool) -- True <=> zap the occurrence info
707 -- Zap the occ info if instructed to do so
709 -- Seq'ing on the returned IdInfo is enough to cause all the
710 -- substitutions to happen completely
712 substIdInfo subst is_fragile_occ info
713 | nothing_to_do = Nothing
714 | otherwise = Just (info `setOccInfo` (if zap_occ then NoOccInfo else old_occ)
715 `setSpecInfo` substRules subst old_rules
716 `setWorkerInfo` substWorker subst old_wrkr
717 `setLBVarInfo` substLBVar subst old_lbv
718 `setUnfoldingInfo` noUnfolding)
719 -- setSpecInfo does a seq
720 -- setWorkerInfo does a seq
722 nothing_to_do = not zap_occ &&
723 isEmptyCoreRules old_rules &&
724 not (workerExists old_wrkr) &&
725 hasNoLBVarInfo old_lbv &&
726 not (hasUnfolding (unfoldingInfo info))
728 zap_occ = is_fragile_occ old_occ
729 old_occ = occInfo info
730 old_rules = specInfo info
731 old_wrkr = workerInfo info
732 old_lbv = lbvarInfo info
734 substIdType :: Subst -> Id -> Id
735 substIdType subst@(Subst in_scope env) id
736 | noTypeSubst env || isEmptyVarSet (tyVarsOfType old_ty) = id
737 | otherwise = setIdType id (substTy subst old_ty)
738 -- The tyVarsOfType is cheaper than it looks
739 -- because we cache the free tyvars of the type
740 -- in a Note in the id's type itself
744 substWorker :: Subst -> WorkerInfo -> WorkerInfo
745 -- Seq'ing on the returned WorkerInfo is enough to cause all the
746 -- substitutions to happen completely
748 substWorker subst NoWorker
750 substWorker subst (HasWorker w a)
751 = case lookupIdSubst subst w of
752 (DoneId w1 _) -> HasWorker w1 a
753 (DoneEx (Var w1)) -> HasWorker w1 a
754 (DoneEx other) -> WARN( True, text "substWorker: DoneEx" <+> ppr w )
755 NoWorker -- Worker has got substituted away altogether
756 (ContEx se1 e) -> WARN( True, text "substWorker: ContEx" <+> ppr w <+> ppr e)
759 substRules :: Subst -> CoreRules -> CoreRules
760 -- Seq'ing on the returned CoreRules is enough to cause all the
761 -- substitutions to happen completely
763 substRules subst rules
764 | isEmptySubst subst = rules
766 substRules subst (Rules rules rhs_fvs)
767 = seqRules new_rules `seq` new_rules
769 new_rules = Rules (map do_subst rules) (substVarSet subst rhs_fvs)
771 do_subst rule@(BuiltinRule _) = rule
772 do_subst (Rule name tpl_vars lhs_args rhs)
773 = Rule name tpl_vars'
774 (map (substExpr subst') lhs_args)
775 (substExpr subst' rhs)
777 (subst', tpl_vars') = substBndrs subst tpl_vars
779 substVarSet subst fvs
780 = foldVarSet (unionVarSet . subst_fv subst) emptyVarSet fvs
782 subst_fv subst fv = case lookupIdSubst subst fv of
783 DoneId fv' _ -> unitVarSet fv'
784 DoneEx expr -> exprFreeVars expr
785 DoneTy ty -> tyVarsOfType ty
786 ContEx se' expr -> substVarSet (setSubstEnv subst se') (exprFreeVars expr)
788 substLBVar subst NoLBVarInfo = NoLBVarInfo
789 substLBVar subst (LBVarInfo ty) = ty1 `seq` LBVarInfo ty1
791 ty1 = substTy subst ty