[project @ 2002-02-14 13:59:22 by simonpj]
[ghc-hetmet.git] / ghc / compiler / coreSyn / Subst.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[CoreUtils]{Utility functions on @Core@ syntax}
5
6 \begin{code}
7 module Subst (
8         -- In-scope set
9         InScopeSet, emptyInScopeSet, mkInScopeSet,
10         extendInScopeSet, extendInScopeSetList,
11         lookupInScope, elemInScopeSet, uniqAway,
12
13
14         -- Substitution stuff
15         Subst, TyVarSubst, IdSubst,
16         emptySubst, mkSubst, substEnv, substInScope,
17         lookupSubst, lookupIdSubst, isEmptySubst, extendSubst, extendSubstList,
18         zapSubstEnv, setSubstEnv, 
19         setInScope, 
20         extendInScope, extendInScopeList, extendNewInScope, extendNewInScopeList, 
21         isInScope, modifyInScope,
22
23         bindSubst, unBindSubst, bindSubstList, unBindSubstList,
24
25         -- Binders
26         simplBndr, simplBndrs, simplLetId, simplLamBndr, simplIdInfo,
27         substAndCloneId, substAndCloneIds, substAndCloneRecIds,
28
29         -- Type stuff
30         mkTyVarSubst, mkTopTyVarSubst, 
31         substTyWith, substTy, substTheta,
32
33         -- Expression stuff
34         substExpr
35     ) where
36
37 #include "HsVersions.h"
38
39 import CmdLineOpts      ( opt_PprStyle_Debug )
40 import CoreSyn          ( Expr(..), Bind(..), Note(..), CoreExpr,
41                           CoreRules(..), CoreRule(..), 
42                           isEmptyCoreRules, seqRules, hasUnfolding, noUnfolding, hasSomeUnfolding,
43                           Unfolding(..)
44                         )
45 import CoreFVs          ( exprFreeVars )
46 import TypeRep          ( Type(..), TyNote(..) )  -- friend
47 import Type             ( ThetaType, SourceType(..), PredType,
48                           tyVarsOfType, tyVarsOfTypes, mkAppTy, 
49                         )
50 import VarSet
51 import VarEnv
52 import Var              ( setVarUnique, isId, mustHaveLocalBinding )
53 import Id               ( idType, idInfo, setIdInfo, setIdType, 
54                           idUnfolding, setIdUnfolding,
55                           idOccInfo, maybeModifyIdInfo )
56 import IdInfo           ( IdInfo, vanillaIdInfo,
57                           occInfo, isFragileOcc, setOccInfo, 
58                           specInfo, setSpecInfo, 
59                           unfoldingInfo, setUnfoldingInfo,
60                           WorkerInfo(..), workerExists, workerInfo, setWorkerInfo, WorkerInfo,
61                           lbvarInfo, LBVarInfo(..), setLBVarInfo, hasNoLBVarInfo
62                         )
63 import BasicTypes       ( OccInfo(..) )
64 import Unique           ( Unique, Uniquable(..), deriveUnique )
65 import UniqSet          ( elemUniqSet_Directly )
66 import UniqSupply       ( UniqSupply, uniqFromSupply, uniqsFromSupply )
67 import Var              ( Var, Id, TyVar, isTyVar )
68 import Outputable
69 import PprCore          ()              -- Instances
70 import UniqFM           ( ufmToList )   -- Yuk (add a new op to VarEnv)
71 import Util             ( mapAccumL, foldl2, seqList )
72 import FastTypes
73 \end{code}
74
75
76 %************************************************************************
77 %*                                                                      *
78 \subsection{The in-scope set}
79 %*                                                                      *
80 %************************************************************************
81
82 \begin{code}
83 data InScopeSet = InScope (VarEnv Var) FastInt
84         -- The Int# is a kind of hash-value used by uniqAway
85         -- For example, it might be the size of the set
86         -- INVARIANT: it's not zero; we use it as a multiplier in uniqAway
87
88 emptyInScopeSet :: InScopeSet
89 emptyInScopeSet = InScope emptyVarSet 1#
90
91 mkInScopeSet :: VarEnv Var -> InScopeSet
92 mkInScopeSet in_scope = InScope in_scope 1#
93
94 extendInScopeSet :: InScopeSet -> Var -> InScopeSet
95 extendInScopeSet (InScope in_scope n) v = InScope (extendVarEnv in_scope v v) (n +# 1#)
96
97 extendInScopeSetList :: InScopeSet -> [Var] -> InScopeSet
98 extendInScopeSetList (InScope in_scope n) vs
99    = InScope (foldl (\s v -> extendVarEnv s v v) in_scope vs)
100                     (n +# iUnbox (length vs))
101
102 modifyInScopeSet :: InScopeSet -> Var -> Var -> InScopeSet
103 -- Exploit the fact that the in-scope "set" is really a map
104 --      Make old_v map to new_v
105 modifyInScopeSet (InScope in_scope n) old_v new_v = InScope (extendVarEnv in_scope old_v new_v) (n +# 1#)
106
107 delInScopeSet :: InScopeSet -> Var -> InScopeSet
108 delInScopeSet (InScope in_scope n) v = InScope (in_scope `delVarEnv` v) n
109
110 elemInScopeSet :: Var -> InScopeSet -> Bool
111 elemInScopeSet v (InScope in_scope n) = v `elemVarEnv` in_scope
112
113 lookupInScope :: InScopeSet -> Var -> Var
114 -- It's important to look for a fixed point
115 -- When we see (case x of y { I# v -> ... })
116 -- we add  [x -> y] to the in-scope set (Simplify.simplCaseBinder).
117 -- When we lookup up an occurrence of x, we map to y, but then
118 -- we want to look up y in case it has acquired more evaluation information by now.
119 lookupInScope (InScope in_scope n) v 
120   = go v
121   where
122     go v = case lookupVarEnv in_scope v of
123                 Just v' | v == v'   -> v'       -- Reached a fixed point
124                         | otherwise -> go v'
125                 Nothing             -> WARN( mustHaveLocalBinding v, ppr v )
126                                        v
127 \end{code}
128
129 \begin{code}
130 uniqAway :: InScopeSet -> Var -> Var
131 -- (uniqAway in_scope v) finds a unique that is not used in the
132 -- in-scope set, and gives that to v.  It starts with v's current unique, of course,
133 -- in the hope that it won't have to change it, nad thereafter uses a combination
134 -- of that and the hash-code found in the in-scope set
135 uniqAway (InScope set n) var
136   | not (var `elemVarSet` set) = var                            -- Nothing to do
137   | otherwise                  = try 1#
138   where
139     orig_unique = getUnique var
140     try k 
141 #ifdef DEBUG
142           | k ># 1000#
143           = pprPanic "uniqAway loop:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n)) 
144 #endif                      
145           | uniq `elemUniqSet_Directly` set = try (k +# 1#)
146 #ifdef DEBUG
147           | opt_PprStyle_Debug && k ># 3#
148           = pprTrace "uniqAway:" (ppr (iBox k) <+> text "tries" <+> ppr var <+> int (iBox n)) 
149             setVarUnique var uniq
150 #endif                      
151           | otherwise = setVarUnique var uniq
152           where
153             uniq = deriveUnique orig_unique (iBox (n *# k))
154 \end{code}
155
156
157 %************************************************************************
158 %*                                                                      *
159 \subsection{Substitutions}
160 %*                                                                      *
161 %************************************************************************
162
163 \begin{code}
164 data Subst = Subst InScopeSet           -- In scope
165                    SubstEnv             -- Substitution itself
166         -- INVARIANT 1: The (domain of the) in-scope set is a superset
167         --              of the free vars of the range of the substitution
168         --              that might possibly clash with locally-bound variables
169         --              in the thing being substituted in.
170         -- This is what lets us deal with name capture properly
171         -- It's a hard invariant to check...
172         -- There are various ways of causing it to happen:
173         --      - arrange that the in-scope set really is all the things in scope
174         --      - arrange that it's the free vars of the range of the substitution
175         --      - make it empty because all the free vars of the subst are fresh,
176         --              and hence can't possibly clash.a
177         --
178         -- INVARIANT 2: No variable is both in scope and in the domain of the substitution
179         --              Equivalently, the substitution is idempotent
180         --      [Sep 2000: Lies, all lies.  The substitution now does contain
181         --                 mappings x77 -> DoneId x77 occ
182         --                 to record x's occurrence information.]
183         --      [Also watch out: the substitution can contain x77 -> DoneEx (Var x77)
184         --       Consider let x = case k of I# x77 -> ... in
185         --                let y = case k of I# x77 -> ... in ...
186         --       and suppose the body is strict in both x and y.  Then the simplifier
187         --       will pull the first (case k) to the top; so the second (case k) will
188         --       cancel out, mapping x77 to, well, x77!  But one is an in-Id and the 
189         --       other is an out-Id. So the substitution is idempotent in the sense
190         --       that we *must not* repeatedly apply it.]
191
192 type IdSubst    = Subst
193 \end{code}
194
195 The general plan about the substitution and in-scope set for Ids is as follows
196
197 * substId always adds new_id to the in-scope set.
198   new_id has a correctly-substituted type, occ info
199
200 * substId adds a binding (DoneId new_id occ) to the substitution if 
201         EITHER the Id's unique has changed
202         OR     the Id has interesting occurrence information
203   So in effect you can only get to interesting occurrence information
204   by looking up the *old* Id; it's not really attached to the new id
205   at all.
206
207   Note, though that the substitution isn't necessarily extended
208   if the type changes.  Why not?  Because of the next point:
209
210 * We *always, always* finish by looking up in the in-scope set 
211   any variable that doesn't get a DoneEx or DoneVar hit in the substitution.
212   Reason: so that we never finish up with a "old" Id in the result.  
213   An old Id might point to an old unfolding and so on... which gives a space leak.
214
215   [The DoneEx and DoneVar hits map to "new" stuff.]
216
217 * It follows that substExpr must not do a no-op if the substitution is empty.
218   substType is free to do so, however.
219
220 * When we come to a let-binding (say) we generate new IdInfo, including an
221   unfolding, attach it to the binder, and add this newly adorned binder to
222   the in-scope set.  So all subsequent occurrences of the binder will get mapped
223   to the full-adorned binder, which is also the one put in the binding site.
224
225 * The in-scope "set" usually maps x->x; we use it simply for its domain.
226   But sometimes we have two in-scope Ids that are synomyms, and should
227   map to the same target:  x->x, y->x.  Notably:
228         case y of x { ... }
229   That's why the "set" is actually a VarEnv Var
230
231
232 \begin{code}
233 isEmptySubst :: Subst -> Bool
234 isEmptySubst (Subst _ env) = isEmptySubstEnv env
235
236 emptySubst :: Subst
237 emptySubst = Subst emptyInScopeSet emptySubstEnv
238
239 mkSubst :: InScopeSet -> SubstEnv -> Subst
240 mkSubst in_scope env = Subst in_scope env
241
242 substEnv :: Subst -> SubstEnv
243 substEnv (Subst _ env) = env
244
245 substInScope :: Subst -> InScopeSet
246 substInScope (Subst in_scope _) = in_scope
247
248 zapSubstEnv :: Subst -> Subst
249 zapSubstEnv (Subst in_scope env) = Subst in_scope emptySubstEnv
250
251 extendSubst :: Subst -> Var -> SubstResult -> Subst
252 extendSubst (Subst in_scope env) v r = Subst in_scope (extendSubstEnv env v r)
253
254 extendSubstList :: Subst -> [Var] -> [SubstResult] -> Subst
255 extendSubstList (Subst in_scope env) v r = Subst in_scope (extendSubstEnvList env v r)
256
257 lookupSubst :: Subst -> Var -> Maybe SubstResult
258 lookupSubst (Subst _ env) v = lookupSubstEnv env v
259
260 lookupIdSubst :: Subst -> Id -> SubstResult
261 -- Does the lookup in the in-scope set too
262 lookupIdSubst (Subst in_scope env) v
263   = case lookupSubstEnv env v of
264         Just (DoneId v' occ) -> DoneId (lookupInScope in_scope v') occ
265         Just res             -> res
266         Nothing              -> DoneId v' (idOccInfo v')
267                                 -- We don't use DoneId for LoopBreakers, so the idOccInfo is
268                                 -- very important!  If isFragileOcc returned True for
269                                 -- loop breakers we could avoid this call, but at the expense
270                                 -- of adding more to the substitution, and building new Ids
271                                 -- in substId a bit more often than really necessary
272                              where
273                                     v' = lookupInScope in_scope v
274
275 isInScope :: Var -> Subst -> Bool
276 isInScope v (Subst in_scope _) = v `elemInScopeSet` in_scope
277
278 modifyInScope :: Subst -> Var -> Var -> Subst
279 modifyInScope (Subst in_scope env) old_v new_v = Subst (modifyInScopeSet in_scope old_v new_v) env
280         -- make old_v map to new_v
281
282 extendInScope :: Subst -> Var -> Subst
283         -- Add a new variable as in-scope
284         -- Remember to delete any existing binding in the substitution!
285 extendInScope (Subst in_scope env) v = Subst (in_scope `extendInScopeSet` v)
286                                              (env `delSubstEnv` v)
287
288 extendInScopeList :: Subst -> [Var] -> Subst
289 extendInScopeList (Subst in_scope env) vs = Subst (extendInScopeSetList in_scope vs)
290                                                   (delSubstEnvList env vs)
291
292 -- The "New" variants are guaranteed to be adding freshly-allocated variables
293 -- It's not clear that the gain (not needing to delete it from the substitution)
294 -- is worth the extra proof obligation
295 extendNewInScope :: Subst -> Var -> Subst
296 extendNewInScope (Subst in_scope env) v = Subst (in_scope `extendInScopeSet` v) env
297
298 extendNewInScopeList :: Subst -> [Var] -> Subst
299 extendNewInScopeList (Subst in_scope env) vs = Subst (in_scope `extendInScopeSetList` vs) env
300
301 -------------------------------
302 bindSubst :: Subst -> Var -> Var -> Subst
303 -- Extend with a substitution, v1 -> Var v2
304 -- and extend the in-scopes with v2
305 bindSubst (Subst in_scope env) old_bndr new_bndr
306   = Subst (in_scope `extendInScopeSet` new_bndr)
307           (extendSubstEnv env old_bndr subst_result)
308   where
309     subst_result | isId old_bndr = DoneEx (Var new_bndr)
310                  | otherwise     = DoneTy (TyVarTy new_bndr)
311
312 unBindSubst :: Subst -> Var -> Var -> Subst
313 -- Reverse the effect of bindSubst
314 -- If old_bndr was already in the substitution, this doesn't quite work
315 unBindSubst (Subst in_scope env) old_bndr new_bndr
316   = Subst (in_scope `delInScopeSet` new_bndr) (delSubstEnv env old_bndr)
317
318 -- And the "List" forms
319 bindSubstList :: Subst -> [Var] -> [Var] -> Subst
320 bindSubstList subst old_bndrs new_bndrs
321   = foldl2 bindSubst subst old_bndrs new_bndrs
322
323 unBindSubstList :: Subst -> [Var] -> [Var] -> Subst
324 unBindSubstList subst old_bndrs new_bndrs
325   = foldl2 unBindSubst subst old_bndrs new_bndrs
326
327
328 -------------------------------
329 setInScope :: Subst     -- Take env part from here
330            -> InScopeSet
331            -> Subst
332 setInScope (Subst in_scope1 env1) in_scope2
333   = Subst in_scope2 env1
334
335 setSubstEnv :: Subst            -- Take in-scope part from here
336             -> SubstEnv         -- ... and env part from here
337             -> Subst
338 setSubstEnv (Subst in_scope1 _) env2 = Subst in_scope1 env2
339 \end{code}
340
341 Pretty printing, for debugging only
342
343 \begin{code}
344 instance Outputable SubstResult where
345   ppr (DoneEx e)   = ptext SLIT("DoneEx") <+> ppr e
346   ppr (DoneId v _) = ptext SLIT("DoneId") <+> ppr v
347   ppr (ContEx _ e) = ptext SLIT("ContEx") <+> ppr e
348   ppr (DoneTy t)   = ptext SLIT("DoneTy") <+> ppr t
349
350 instance Outputable SubstEnv where
351   ppr se = brackets (fsep (punctuate comma (map ppr_elt (ufmToList (substEnvEnv se)))))
352         where
353            ppr_elt (uniq,sr) = ppr uniq <+> ptext SLIT("->") <+> ppr sr
354
355 instance Outputable Subst where
356   ppr (Subst (InScope in_scope _) se) 
357         =  ptext SLIT("<InScope =") <+> braces   (fsep (map ppr (rngVarEnv in_scope)))
358         $$ ptext SLIT(" Subst   =") <+> ppr se <> char '>'
359 \end{code}
360
361 %************************************************************************
362 %*                                                                      *
363 \subsection{Type substitution}
364 %*                                                                      *
365 %************************************************************************
366
367 \begin{code}
368 type TyVarSubst = Subst -- TyVarSubst are expected to have range elements
369         -- (We could have a variant of Subst, but it doesn't seem worth it.)
370
371 -- mkTyVarSubst generates the in-scope set from
372 -- the types given; but it's just a thunk so with a bit of luck
373 -- it'll never be evaluated
374 mkTyVarSubst :: [TyVar] -> [Type] -> Subst
375 mkTyVarSubst tyvars tys = Subst (mkInScopeSet (tyVarsOfTypes tys)) 
376                                 (zip_ty_env tyvars tys emptySubstEnv)
377
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)
383
384 zip_ty_env []       []       env = env
385 zip_ty_env (tv:tvs) (ty:tys) env = zip_ty_env tvs tys (extendSubstEnv env tv (DoneTy ty))
386         -- There used to be a special case for when 
387         --      ty == TyVarTy tv
388         -- (a not-uncommon case) in which case the substitution was dropped.
389         -- But the type-tidier changes the print-name of a type variable without
390         -- changing the unique, and that led to a bug.   Why?  Pre-tidying, we had 
391         -- a type {Foo t}, where Foo is a one-method class.  So Foo is really a newtype.
392         -- And it happened that t was the type variable of the class.  Post-tiding, 
393         -- it got turned into {Foo t2}.  The ext-core printer expanded this using
394         -- sourceTypeRep, but that said "Oh, t == t2" because they have the same unique,
395         -- and so generated a rep type mentioning t not t2.  
396         --
397         -- Simplest fix is to nuke the "optimisation"
398 \end{code}
399
400 substTy works with general Substs, so that it can be called from substExpr too.
401
402 \begin{code}
403 substTyWith :: [TyVar] -> [Type] -> Type -> Type
404 substTyWith tvs tys = substTy (mkTyVarSubst tvs tys)
405
406 substTy :: Subst -> Type  -> Type
407 substTy subst ty | isEmptySubst subst = ty
408                  | otherwise          = subst_ty subst ty
409
410 substTheta :: TyVarSubst -> ThetaType -> ThetaType
411 substTheta subst theta
412   | isEmptySubst subst = theta
413   | otherwise          = map (substPred subst) theta
414
415 substPred :: TyVarSubst -> PredType -> PredType
416 substPred = substSourceType
417
418 substSourceType subst (IParam n ty)     = IParam n (subst_ty subst ty)
419 substSourceType subst (ClassP clas tys) = ClassP clas (map (subst_ty subst) tys)
420 substSourceType subst (NType  tc   tys) = NType  tc   (map (subst_ty subst) tys)
421
422 subst_ty subst ty
423    = go ty
424   where
425     go (TyConApp tc tys)           = let args = map go tys
426                                      in  args `seqList` TyConApp tc args
427
428     go (SourceTy p)                = SourceTy $! (substSourceType subst p)
429
430     go (NoteTy (SynNote ty1) ty2)  = NoteTy (SynNote $! (go ty1)) $! (go ty2)
431     go (NoteTy (FTVNote _) ty2)    = go ty2             -- Discard the free tyvar note
432
433     go (FunTy arg res)             = (FunTy $! (go arg)) $! (go res)
434     go (AppTy fun arg)             = mkAppTy (go fun) $! (go arg)
435     go ty@(TyVarTy tv)             = case (lookupSubst subst tv) of
436                                         Nothing            -> ty
437                                         Just (DoneTy ty')  -> ty'
438                                         
439     go (ForAllTy tv ty)            = case substTyVar subst tv of
440                                         (subst', tv') -> ForAllTy tv' $! (subst_ty subst' ty)
441 \end{code}
442
443 Here is where we invent a new binder if necessary.
444
445 \begin{code}
446 substTyVar :: Subst -> TyVar -> (Subst, TyVar)  
447 substTyVar subst@(Subst in_scope env) old_var
448   | old_var == new_var  -- No need to clone
449                         -- But we *must* zap any current substitution for the variable.
450                         --  For example:
451                         --      (\x.e) with id_subst = [x |-> e']
452                         -- Here we must simply zap the substitution for x
453                         --
454                         -- The new_id isn't cloned, but it may have a different type
455                         -- etc, so we must return it, not the old id
456   = (Subst (in_scope `extendInScopeSet` new_var)
457            (delSubstEnv env old_var),
458      new_var)
459
460   | otherwise   -- The new binder is in scope so
461                 -- we'd better rename it away from the in-scope variables
462                 -- Extending the substitution to do this renaming also
463                 -- has the (correct) effect of discarding any existing
464                 -- substitution for that variable
465   = (Subst (in_scope `extendInScopeSet` new_var) 
466            (extendSubstEnv env old_var (DoneTy (TyVarTy new_var))),
467      new_var)
468   where
469     new_var = uniqAway in_scope old_var
470         -- The uniqAway part makes sure the new variable is not already in scope
471 \end{code}
472
473
474 %************************************************************************
475 %*                                                                      *
476 \section{Expression substitution}
477 %*                                                                      *
478 %************************************************************************
479
480 This expression substituter deals correctly with name capture.
481
482 BUT NOTE that substExpr silently discards the
483         unfolding, and
484         spec env
485 IdInfo attached to any binders in the expression.  It's quite
486 tricky to do them 'right' in the case of mutually recursive bindings,
487 and so far has proved unnecessary.
488
489 \begin{code}
490 substExpr :: Subst -> CoreExpr -> CoreExpr
491 substExpr subst expr
492         -- NB: we do not do a no-op when the substitution is empty,
493         -- because we always want to substitute the variables in the
494         -- in-scope set for their occurrences.  Why?
495         --      (a) because they may contain more information
496         --      (b) because leaving an un-substituted Id might cause
497         --          a space leak (its unfolding might point to an old version
498         --          of its right hand side).
499
500   = go expr
501   where
502     go (Var v) = -- See the notes at the top, with the Subst data type declaration
503                  case lookupIdSubst subst v of
504         
505                     ContEx env' e' -> substExpr (setSubstEnv subst env') e'
506                     DoneId v _     -> Var v
507                     DoneEx e'      -> e'
508
509     go (Type ty)      = Type (go_ty ty)
510     go (Lit lit)      = Lit lit
511     go (App fun arg)  = App (go fun) (go arg)
512     go (Note note e)  = Note (go_note note) (go e)
513
514     go (Lam bndr body) = Lam bndr' (substExpr subst' body)
515                        where
516                          (subst', bndr') = substBndr subst bndr
517
518     go (Let (NonRec bndr rhs) body) = Let (NonRec bndr' (go rhs)) (substExpr subst' body)
519                                     where
520                                       (subst', bndr') = substBndr subst bndr
521
522     go (Let (Rec pairs) body) = Let (Rec pairs') (substExpr subst' body)
523                               where
524                                 (subst', bndrs') = substRecIds subst (map fst pairs)
525                                 pairs'  = bndrs' `zip` rhss'
526                                 rhss'   = map (substExpr subst' . snd) pairs
527
528     go (Case scrut bndr alts) = Case (go scrut) bndr' (map (go_alt subst') alts)
529                               where
530                                 (subst', bndr') = substBndr subst bndr
531
532     go_alt subst (con, bndrs, rhs) = (con, bndrs', substExpr subst' rhs)
533                                  where
534                                    (subst', bndrs') = substBndrs subst bndrs
535
536     go_note (Coerce ty1 ty2) = Coerce (go_ty ty1) (go_ty ty2)
537     go_note note             = note
538
539     go_ty ty = substTy subst ty
540
541 \end{code}
542
543
544 %************************************************************************
545 %*                                                                      *
546 \section{Substituting an Id binder}
547 %*                                                                      *
548 %************************************************************************
549
550 \begin{code}
551 -- simplBndr and simplLetId are used by the simplifier
552
553 simplBndr :: Subst -> Var -> (Subst, Var)
554 -- Used for lambda and case-bound variables
555 -- Clone Id if necessary, substitute type
556 -- Return with IdInfo already substituted, but (fragile) occurrence info zapped
557 -- The substitution is extended only if the variable is cloned, because
558 -- we *don't* need to use it to track occurrence info.
559 simplBndr subst bndr
560   | isTyVar bndr  = substTyVar subst bndr
561   | otherwise     = subst_id isFragileOcc subst subst bndr
562
563 simplBndrs :: Subst -> [Var] -> (Subst, [Var])
564 simplBndrs subst bndrs = mapAccumL simplBndr subst bndrs
565
566 simplLamBndr :: Subst -> Var -> (Subst, Var)
567 -- Used for lambda binders.  These sometimes have unfoldings added by
568 -- the worker/wrapper pass that must be preserved, becuase they can't
569 -- be reconstructed from context.  For example:
570 --      f x = case x of (a,b) -> fw a b x
571 --      fw a b x{=(a,b)} = ...
572 -- The "{=(a,b)}" is an unfolding we can't reconstruct otherwise.
573 simplLamBndr subst bndr
574   | not (isId bndr && hasSomeUnfolding old_unf)
575   = simplBndr subst bndr        -- Normal case
576   | otherwise
577   = (subst', bndr' `setIdUnfolding` substUnfolding subst old_unf)
578   where
579     old_unf = idUnfolding bndr
580     (subst', bndr') = subst_id isFragileOcc subst subst bndr
581                 
582
583 simplLetId :: Subst -> Id -> (Subst, Id)
584 -- Clone Id if necessary
585 -- Substitute its type
586 -- Return an Id with completely zapped IdInfo
587 --      [A subsequent substIdInfo will restore its IdInfo]
588 -- Augment the subtitution 
589 --      if the unique changed, *or* 
590 --      if there's interesting occurrence info
591
592 simplLetId subst@(Subst in_scope env) old_id
593   = (Subst (in_scope `extendInScopeSet` new_id) new_env, new_id)
594   where
595     old_info = idInfo old_id
596     id1     = uniqAway in_scope old_id
597     id2     = substIdType subst id1
598     new_id  = setIdInfo id2 vanillaIdInfo
599
600         -- Extend the substitution if the unique has changed,
601         -- or there's some useful occurrence information
602         -- See the notes with substTyVar for the delSubstEnv
603     occ_info = occInfo old_info
604     new_env | new_id /= old_id || isFragileOcc occ_info
605             = extendSubstEnv env old_id (DoneId new_id occ_info)
606             | otherwise 
607             = delSubstEnv env old_id
608
609 simplIdInfo :: Subst -> IdInfo -> IdInfo
610   -- Used by the simplifier to compute new IdInfo for a let(rec) binder,
611   -- subsequent to simplLetId having zapped its IdInfo
612 simplIdInfo subst old_info
613   = case substIdInfo subst isFragileOcc old_info of 
614         Just new_info -> new_info
615         Nothing       -> old_info
616 \end{code}
617
618 \begin{code}
619 -- substBndr and friends are used when doing expression substitution only
620 -- In this case we can *preserve* occurrence information, and indeed we *want*
621 -- to do so else lose useful occ info in rules.  Hence the calls to 
622 -- simpl_id with keepOccInfo
623
624 substBndr :: Subst -> Var -> (Subst, Var)
625 substBndr subst bndr
626   | isTyVar bndr  = substTyVar subst bndr
627   | otherwise     = subst_id keepOccInfo subst subst bndr
628
629 substBndrs :: Subst -> [Var] -> (Subst, [Var])
630 substBndrs subst bndrs = mapAccumL substBndr subst bndrs
631
632 substRecIds :: Subst -> [Id] -> (Subst, [Id])
633 -- Substitute a mutually recursive group
634 substRecIds subst bndrs 
635   = (new_subst, new_bndrs)
636   where
637         -- Here's the reason we need to pass rec_subst to subst_id
638     (new_subst, new_bndrs) = mapAccumL (subst_id keepOccInfo new_subst) subst bndrs
639
640 keepOccInfo occ = False -- Never fragile
641 \end{code}
642
643
644 \begin{code}
645 subst_id :: (OccInfo -> Bool)   -- True <=> the OccInfo is fragile
646          -> Subst               -- Substitution to use for the IdInfo
647          -> Subst -> Id         -- Substitition and Id to transform
648          -> (Subst, Id)         -- Transformed pair
649
650 -- Returns with:
651 --      * Unique changed if necessary
652 --      * Type substituted
653 --      * Unfolding zapped
654 --      * Rules, worker, lbvar info all substituted 
655 --      * Occurrence info zapped if is_fragile_occ returns True
656 --      * The in-scope set extended with the returned Id
657 --      * The substitution extended with a DoneId if unique changed
658 --        In this case, the var in the DoneId is the same as the
659 --        var returned
660
661 subst_id is_fragile_occ rec_subst subst@(Subst in_scope env) old_id
662   = (Subst (in_scope `extendInScopeSet` new_id) new_env, new_id)
663   where
664         -- id1 is cloned if necessary
665     id1 = uniqAway in_scope old_id
666
667         -- id2 has its type zapped
668     id2 = substIdType subst id1
669
670         -- new_id has the right IdInfo
671         -- The lazy-set is because we're in a loop here, with 
672         -- rec_subst, when dealing with a mutually-recursive group
673     new_id = maybeModifyIdInfo (substIdInfo rec_subst is_fragile_occ) id2
674
675         -- Extend the substitution if the unique has changed
676         -- See the notes with substTyVar for the delSubstEnv
677     new_env | new_id /= old_id
678             = extendSubstEnv env old_id (DoneId new_id (idOccInfo old_id))
679             | otherwise 
680             = delSubstEnv env old_id
681 \end{code}
682
683 Now a variant that unconditionally allocates a new unique.
684 It also unconditionally zaps the OccInfo.
685
686 \begin{code}
687 subst_clone_id :: Subst                 -- Substitution to use (lazily) for the rules and worker
688                -> Subst -> (Id, Unique) -- Substitition and Id to transform
689                -> (Subst, Id)           -- Transformed pair
690
691 subst_clone_id rec_subst subst@(Subst in_scope env) (old_id, uniq)
692   = (Subst (in_scope `extendInScopeSet` new_id) new_env, new_id)
693   where
694     id1  = setVarUnique old_id uniq
695     id2  = substIdType subst id1
696
697     new_id  = maybeModifyIdInfo (substIdInfo rec_subst isFragileOcc) id2
698     new_env = extendSubstEnv env old_id (DoneId new_id NoOccInfo)
699
700 substAndCloneIds :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
701 substAndCloneIds subst us ids
702   = mapAccumL (subst_clone_id subst) subst (ids `zip` uniqsFromSupply us)
703
704 substAndCloneRecIds :: Subst -> UniqSupply -> [Id] -> (Subst, [Id])
705 substAndCloneRecIds subst us ids
706   = (subst', ids')
707   where
708     (subst', ids') = mapAccumL (subst_clone_id subst') subst
709                                (ids `zip` uniqsFromSupply us)
710
711 substAndCloneId :: Subst -> UniqSupply -> Id -> (Subst, Id)
712 substAndCloneId subst@(Subst in_scope env) us old_id
713   = subst_clone_id subst subst (old_id, uniqFromSupply us)
714 \end{code}
715
716
717 %************************************************************************
718 %*                                                                      *
719 \section{IdInfo substitution}
720 %*                                                                      *
721 %************************************************************************
722
723 \begin{code}
724 substIdInfo :: Subst 
725             -> (OccInfo -> Bool)        -- True <=> zap the occurrence info
726             -> IdInfo
727             -> Maybe IdInfo
728 -- Substitute the 
729 --      rules
730 --      worker info
731 --      LBVar info
732 -- Zap the unfolding 
733 -- Zap the occ info if instructed to do so
734 -- 
735 -- Seq'ing on the returned IdInfo is enough to cause all the 
736 -- substitutions to happen completely
737
738 substIdInfo subst is_fragile_occ info
739   | nothing_to_do = Nothing
740   | otherwise     = Just (info `setOccInfo`       (if zap_occ then NoOccInfo else old_occ)
741                                `setSpecInfo`      substRules  subst old_rules
742                                `setWorkerInfo`    substWorker subst old_wrkr
743                                `setLBVarInfo`     substLBVar  subst old_lbv
744                                `setUnfoldingInfo` noUnfolding)
745                         -- setSpecInfo does a seq
746                         -- setWorkerInfo does a seq
747   where
748     nothing_to_do = not zap_occ && 
749                     isEmptyCoreRules old_rules &&
750                     not (workerExists old_wrkr) &&
751                     hasNoLBVarInfo old_lbv &&
752                     not (hasUnfolding (unfoldingInfo info))
753     
754     zap_occ   = is_fragile_occ old_occ
755     old_occ   = occInfo info
756     old_rules = specInfo info
757     old_wrkr  = workerInfo info
758     old_lbv   = lbvarInfo info
759
760 ------------------
761 substIdType :: Subst -> Id -> Id
762 substIdType subst@(Subst in_scope env) id
763   |  noTypeSubst env || isEmptyVarSet (tyVarsOfType old_ty) = id
764   | otherwise                                               = setIdType id (substTy subst old_ty)
765                 -- The tyVarsOfType is cheaper than it looks
766                 -- because we cache the free tyvars of the type
767                 -- in a Note in the id's type itself
768   where
769     old_ty = idType id
770
771 ------------------
772 substWorker :: Subst -> WorkerInfo -> WorkerInfo
773         -- Seq'ing on the returned WorkerInfo is enough to cause all the 
774         -- substitutions to happen completely
775
776 substWorker subst NoWorker
777   = NoWorker
778 substWorker subst (HasWorker w a)
779   = case lookupIdSubst subst w of
780         (DoneId w1 _)     -> HasWorker w1 a
781         (DoneEx (Var w1)) -> HasWorker w1 a
782         (DoneEx other)    -> WARN( True, text "substWorker: DoneEx" <+> ppr w )
783                                   NoWorker      -- Worker has got substituted away altogether
784         (ContEx se1 e)    -> WARN( True, text "substWorker: ContEx" <+> ppr w <+> ppr e)
785                                   NoWorker      -- Ditto
786                         
787 ------------------
788 substUnfolding subst NoUnfolding                 = NoUnfolding
789 substUnfolding subst (OtherCon cons)             = OtherCon cons
790 substUnfolding subst (CompulsoryUnfolding rhs)   = CompulsoryUnfolding (substExpr subst rhs)
791 substUnfolding subst (CoreUnfolding rhs t v w g) = CoreUnfolding (substExpr subst rhs) t v w g
792
793 ------------------
794 substRules :: Subst -> CoreRules -> CoreRules
795         -- Seq'ing on the returned CoreRules is enough to cause all the 
796         -- substitutions to happen completely
797
798 substRules subst rules
799  | isEmptySubst subst = rules
800
801 substRules subst (Rules rules rhs_fvs)
802   = seqRules new_rules `seq` new_rules
803   where
804     new_rules = Rules (map do_subst rules) (substVarSet subst rhs_fvs)
805
806     do_subst rule@(BuiltinRule _ _) = rule
807     do_subst (Rule name act tpl_vars lhs_args rhs)
808         = Rule name act tpl_vars' 
809                (map (substExpr subst') lhs_args)
810                (substExpr subst' rhs)
811         where
812           (subst', tpl_vars') = substBndrs subst tpl_vars
813
814 ------------------
815 substVarSet subst fvs 
816   = foldVarSet (unionVarSet . subst_fv subst) emptyVarSet fvs
817   where
818     subst_fv subst fv = case lookupIdSubst subst fv of
819                             DoneId fv' _    -> unitVarSet fv'
820                             DoneEx expr     -> exprFreeVars expr
821                             DoneTy ty       -> tyVarsOfType ty 
822                             ContEx se' expr -> substVarSet (setSubstEnv subst se') (exprFreeVars expr)
823
824 ------------------
825 substLBVar subst NoLBVarInfo    = NoLBVarInfo
826 substLBVar subst (LBVarInfo ty) = ty1 `seq` LBVarInfo ty1
827                                 where
828                                   ty1 = substTy subst ty
829 \end{code}