[project @ 2001-10-03 09:20:20 by simonmar]
[ghc-hetmet.git] / ghc / compiler / coreSyn / CoreTidy.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section{Tidying up Core}
5
6 \begin{code}
7 module CoreTidy (
8         tidyCorePgm, tidyExpr, tidyCoreExpr,
9         tidyBndr, tidyBndrs
10     ) where
11
12 #include "HsVersions.h"
13
14 import CmdLineOpts      ( DynFlags, DynFlag(..), opt_OmitInterfacePragmas )
15 import CoreSyn
16 import CoreUnfold       ( noUnfolding, mkTopUnfolding, okToUnfoldInHiFile )
17 import CoreFVs          ( ruleSomeFreeVars, exprSomeFreeVars )
18 import PprCore          ( pprIdCoreRule )
19 import CoreLint         ( showPass, endPass )
20 import VarEnv
21 import VarSet
22 import Var              ( Id, Var )
23 import Id               ( idType, idInfo, idName, isExportedId, 
24                           idSpecialisation, idUnique, isDataConWrapId,
25                           mkVanillaGlobal, mkGlobalId, isLocalId, 
26                           hasNoBinding, mkUserLocal, isGlobalId, globalIdDetails,
27                           idNewDemandInfo, setIdNewDemandInfo, 
28                           idNewStrictness_maybe, setIdNewStrictness
29                         ) 
30 import IdInfo           {- loads of stuff -}
31 import NewDemand        ( isBottomingSig, topSig, isStrictDmd )
32 import BasicTypes       ( isNeverActive )
33 import Name             ( getOccName, nameOccName, globaliseName, setNameOcc, 
34                           localiseName, isGlobalName, setNameUnique
35                         )
36 import NameEnv          ( filterNameEnv )
37 import OccName          ( TidyOccEnv, initTidyOccEnv, tidyOccName )
38 import Type             ( tidyTopType, tidyType, tidyTyVarBndr )
39 import Module           ( Module, moduleName )
40 import HscTypes         ( PersistentCompilerState( pcs_PRS ), 
41                           PersistentRenamerState( prsOrig ),
42                           NameSupply( nsNames, nsUniqs ),
43                           TypeEnv, extendTypeEnvList, 
44                           ModDetails(..), TyThing(..)
45                         )
46 import FiniteMap        ( lookupFM, addToFM )
47 import Maybes           ( orElse )
48 import ErrUtils         ( showPass, dumpIfSet_core )
49 import SrcLoc           ( noSrcLoc )
50 import UniqFM           ( mapUFM )
51 import UniqSupply       ( splitUniqSupply, uniqFromSupply )
52 import List             ( partition )
53 import Util             ( mapAccumL )
54 import Maybe            ( isJust, fromJust, isNothing )
55 import Outputable
56 \end{code}
57
58
59
60 %************************************************************************
61 %*                                                                      *
62 \subsection{What goes on}
63 %*                                                                      * 
64 %************************************************************************
65
66 [SLPJ: 19 Nov 00]
67
68 The plan is this.  
69
70 Step 1: Figure out external Ids
71 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
72 First we figure out which Ids are "external" Ids.  An
73 "external" Id is one that is visible from outside the compilation
74 unit.  These are
75         a) the user exported ones
76         b) ones mentioned in the unfoldings, workers, 
77            or rules of externally-visible ones 
78 This exercise takes a sweep of the bindings bottom to top.  Actually,
79 in Step 2 we're also going to need to know which Ids should be
80 exported with their unfoldings, so we produce not an IdSet but an
81 IdEnv Bool
82
83
84 Step 2: Tidy the program
85 ~~~~~~~~~~~~~~~~~~~~~~~~
86 Next we traverse the bindings top to bottom.  For each *top-level*
87 binder
88
89  1. Make it into a GlobalId
90
91  2. Give it a system-wide Unique.
92     [Even non-exported things need system-wide Uniques because the
93     byte-code generator builds a single Name->BCO symbol table.]
94
95     We use the NameSupply kept in the PersistentRenamerState as the
96     source of such system-wide uniques.
97
98     For external Ids, use the original-name cache in the NameSupply 
99     to ensure that the unique assigned is the same as the Id had 
100     in any previous compilation run.
101   
102  3. If it's an external Id, make it have a global Name, otherwise
103     make it have a local Name.
104     This is used by the code generator to decide whether
105     to make the label externally visible
106
107  4. Give external Ids a "tidy" occurrence name.  This means
108     we can print them in interface files without confusing 
109     "x" (unique 5) with "x" (unique 10).
110   
111  5. Give it its UTTERLY FINAL IdInfo; in ptic, 
112         * Its IdDetails becomes VanillaGlobal, reflecting the fact that
113           from now on we regard it as a global, not local, Id
114
115         * its unfolding, if it should have one
116         
117         * its arity, computed from the number of visible lambdas
118
119         * its CAF info, computed from what is free in its RHS
120
121                 
122 Finally, substitute these new top-level binders consistently
123 throughout, including in unfoldings.  We also tidy binders in
124 RHSs, so that they print nicely in interfaces.
125
126 \begin{code}
127 tidyCorePgm :: DynFlags -> Module
128             -> PersistentCompilerState
129             -> CgInfoEnv                -- Information from the back end,
130                                         -- to be splatted into the IdInfo
131             -> ModDetails
132             -> IO (PersistentCompilerState, ModDetails)
133
134 tidyCorePgm dflags mod pcs cg_info_env
135             (ModDetails { md_types = env_tc, md_insts = insts_tc, 
136                           md_binds = binds_in, md_rules = orphans_in })
137   = do  { showPass dflags "Tidy Core"
138
139         ; let ext_ids   = findExternalSet   binds_in orphans_in
140         ; let ext_rules = findExternalRules binds_in orphans_in ext_ids
141
142         -- We also make sure to avoid any exported binders.  Consider
143         --      f{-u1-} = 1     -- Local decl
144         --      ...
145         --      f{-u2-} = 2     -- Exported decl
146         --
147         -- The second exported decl must 'get' the name 'f', so we
148         -- have to put 'f' in the avoids list before we get to the first
149         -- decl.  tidyTopId then does a no-op on exported binders.
150         ; let   prs           = pcs_PRS pcs
151                 orig_ns       = prsOrig prs
152
153                 init_tidy_env = (orig_ns, initTidyOccEnv avoids, emptyVarEnv)
154                 avoids        = [getOccName bndr | bndr <- bindersOfBinds binds_in,
155                                                    isGlobalName (idName bndr)]
156
157         ; let ((orig_ns', occ_env, subst_env), tidy_binds) 
158                         = mapAccumL (tidyTopBind mod ext_ids cg_info_env) 
159                                     init_tidy_env binds_in
160
161         ; let tidy_rules = tidyIdRules (occ_env,subst_env) ext_rules
162
163         ; let prs' = prs { prsOrig = orig_ns' }
164               pcs' = pcs { pcs_PRS = prs' }
165
166         ; let final_ids  = [ id | bind <- tidy_binds
167                            , id <- bindersOf bind
168                            , isGlobalName (idName id)]
169
170                 -- Dfuns are local Ids that might have
171                 -- changed their unique during tidying
172         ; let lookup_dfun_id id = lookupVarEnv subst_env id `orElse` 
173                                   pprPanic "lookup_dfun_id" (ppr id)
174
175
176         ; let tidy_type_env = mkFinalTypeEnv env_tc final_ids
177               tidy_dfun_ids = map lookup_dfun_id insts_tc
178
179         ; let tidy_details = ModDetails { md_types = tidy_type_env,
180                                           md_rules = tidy_rules,
181                                           md_insts = tidy_dfun_ids,
182                                           md_binds = tidy_binds }
183
184         ; endPass dflags "Tidy Core" Opt_D_dump_simpl tidy_binds
185         ; dumpIfSet_core dflags Opt_D_dump_simpl
186                 "Tidy Core Rules"
187                 (vcat (map pprIdCoreRule tidy_rules))
188
189         ; return (pcs', tidy_details)
190         }
191
192 tidyCoreExpr :: CoreExpr -> IO CoreExpr
193 tidyCoreExpr expr = return (tidyExpr emptyTidyEnv expr)
194 \end{code}
195
196
197 %************************************************************************
198 %*                                                                      *
199 \subsection{Write a new interface file}
200 %*                                                                      *
201 %************************************************************************
202
203 \begin{code}
204 mkFinalTypeEnv :: TypeEnv       -- From typechecker
205                -> [Id]          -- Final Ids
206                -> TypeEnv
207
208 mkFinalTypeEnv type_env final_ids
209   = extendTypeEnvList (filterNameEnv keep_it type_env)
210                       (map AnId final_ids)
211   where
212         -- The competed type environment is gotten from
213         --      a) keeping the types and classes
214         --      b) removing all Ids, 
215         --      c) adding Ids with correct IdInfo, including unfoldings,
216         --              gotten from the bindings
217         -- From (c) we keep only those Ids with Global names;
218         --          the CoreTidy pass makes sure these are all and only
219         --          the externally-accessible ones
220         -- This truncates the type environment to include only the 
221         -- exported Ids and things needed from them, which saves space
222         --
223         -- However, we do keep things like constructors, which should not appear 
224         -- in interface files, because they are needed by importing modules when
225         -- using the compilation manager
226
227         -- We keep "hasNoBinding" Ids, notably constructor workers, 
228         -- because they won't appear in the bindings from which final_ids are derived!
229     keep_it (AnId id) = hasNoBinding id -- Remove all Ids except constructor workers
230     keep_it other     = True            -- Keep all TyCons and Classes
231 \end{code}
232
233 \begin{code}
234 findExternalRules :: [CoreBind]
235                   -> [IdCoreRule] -- Orphan rules
236                   -> IdEnv a      -- Ids that are exported, so we need their rules
237                   -> [IdCoreRule]
238   -- The complete rules are gotten by combining
239   --    a) the orphan rules
240   --    b) rules embedded in the top-level Ids
241 findExternalRules binds orphan_rules ext_ids
242   | opt_OmitInterfacePragmas = []
243   | otherwise
244   = orphan_rules ++ local_rules
245   where
246     local_rules  = [ (id, rule)
247                    | id <- bindersOfBinds binds,
248                      id `elemVarEnv` ext_ids,
249                      rule <- rulesRules (idSpecialisation id),
250                      not (isBuiltinRule rule)
251                         -- We can't print builtin rules in interface files
252                         -- Since they are built in, an importing module
253                         -- will have access to them anyway
254                  ]
255 \end{code}
256
257 %************************************************************************
258 %*                                                                      *
259 \subsection{Step 1: finding externals}
260 %*                                                                      * 
261 %************************************************************************
262
263 \begin{code}
264 findExternalSet :: [CoreBind] -> [IdCoreRule]
265                 -> IdEnv Bool   -- In domain => external
266                                 -- Range = True <=> show unfolding
267         -- Step 1 from the notes above
268 findExternalSet binds orphan_rules
269   = foldr find init_needed binds
270   where
271     orphan_rule_ids :: IdSet
272     orphan_rule_ids = unionVarSets [ ruleSomeFreeVars isLocalId rule 
273                                    | (_, rule) <- orphan_rules]
274     init_needed :: IdEnv Bool
275     init_needed = mapUFM (\_ -> False) orphan_rule_ids
276         -- The mapUFM is a bit cheesy.  It is a cheap way
277         -- to turn the set of orphan_rule_ids, which we use to initialise
278         -- the sweep, into a mapping saying 'don't expose unfolding'    
279         -- (When we come to the binding site we may change our mind, of course.)
280
281     find (NonRec id rhs) needed
282         | need_id needed id = addExternal (id,rhs) needed
283         | otherwise         = needed
284     find (Rec prs) needed   = find_prs prs needed
285
286         -- For a recursive group we have to look for a fixed point
287     find_prs prs needed 
288         | null needed_prs = needed
289         | otherwise       = find_prs other_prs new_needed
290         where
291           (needed_prs, other_prs) = partition (need_pr needed) prs
292           new_needed = foldr addExternal needed needed_prs
293
294         -- The 'needed' set contains the Ids that are needed by earlier
295         -- interface file emissions.  If the Id isn't in this set, and isn't
296         -- exported, there's no need to emit anything
297     need_id needed_set id       = id `elemVarEnv` needed_set || isExportedId id 
298     need_pr needed_set (id,rhs) = need_id needed_set id
299
300 addExternal :: (Id,CoreExpr) -> IdEnv Bool -> IdEnv Bool
301 -- The Id is needed; extend the needed set
302 -- with it and its dependents (free vars etc)
303 addExternal (id,rhs) needed
304   = extendVarEnv (foldVarSet add_occ needed new_needed_ids)
305                  id show_unfold
306   where
307     add_occ id needed = extendVarEnv needed id False
308         -- "False" because we don't know we need the Id's unfolding
309         -- We'll override it later when we find the binding site
310
311     new_needed_ids | opt_OmitInterfacePragmas = emptyVarSet
312                    | otherwise                = worker_ids      `unionVarSet`
313                                                 unfold_ids      `unionVarSet`
314                                                 spec_ids
315
316     idinfo         = idInfo id
317     dont_inline    = isNeverActive (inlinePragInfo idinfo)
318     loop_breaker   = isLoopBreaker (occInfo idinfo)
319     bottoming_fn   = isBottomingSig (newStrictnessInfo idinfo `orElse` topSig)
320     spec_ids       = rulesRhsFreeVars (specInfo idinfo)
321     worker_info    = workerInfo idinfo
322
323         -- Stuff to do with the Id's unfolding
324         -- The simplifier has put an up-to-date unfolding
325         -- in the IdInfo, but the RHS will do just as well
326     unfolding    = unfoldingInfo idinfo
327     rhs_is_small = not (neverUnfold unfolding)
328
329         -- We leave the unfolding there even if there is a worker
330         -- In GHCI the unfolding is used by importers
331         -- When writing an interface file, we omit the unfolding 
332         -- if there is a worker
333     show_unfold = not bottoming_fn       &&     -- Not necessary
334                   not dont_inline        &&
335                   not loop_breaker       &&
336                   rhs_is_small           &&     -- Small enough
337                   okToUnfoldInHiFile rhs        -- No casms etc
338
339     unfold_ids | show_unfold = exprSomeFreeVars isLocalId rhs
340                | otherwise   = emptyVarSet
341
342     worker_ids = case worker_info of
343                    HasWorker work_id _ -> unitVarSet work_id
344                    otherwise           -> emptyVarSet
345 \end{code}
346
347
348 %************************************************************************
349 %*                                                                      *
350 \subsection{Step 2: top-level tidying}
351 %*                                                                      *
352 %************************************************************************
353
354
355 \begin{code}
356 type TopTidyEnv = (NameSupply, TidyOccEnv, VarEnv Var)
357
358 -- TopTidyEnv: when tidying we need to know
359 --   * ns: The NameSupply, containing a unique supply and any pre-ordained Names.  
360 --        These may have arisen because the
361 --        renamer read in an interface file mentioning M.$wf, say,
362 --        and assigned it unique r77.  If, on this compilation, we've
363 --        invented an Id whose name is $wf (but with a different unique)
364 --        we want to rename it to have unique r77, so that we can do easy
365 --        comparisons with stuff from the interface file
366 --
367 --   * occ_env: The TidyOccEnv, which tells us which local occurrences 
368 --     are 'used'
369 --
370 --   * subst_env: A Var->Var mapping that substitutes the new Var for the old
371 \end{code}
372
373
374 \begin{code}
375 tidyTopBind :: Module
376             -> IdEnv Bool       -- Domain = Ids that should be external
377                                 -- True <=> their unfolding is external too
378             -> CgInfoEnv
379             -> TopTidyEnv -> CoreBind
380             -> (TopTidyEnv, CoreBind)
381
382 tidyTopBind mod ext_ids cg_info_env top_tidy_env (NonRec bndr rhs)
383   = ((orig,occ,subst) , NonRec bndr' rhs')
384   where
385     ((orig,occ,subst), bndr')
386          = tidyTopBinder mod ext_ids cg_info_env rec_tidy_env rhs' top_tidy_env bndr
387     rec_tidy_env = (occ,subst)
388     rhs' = tidyExpr rec_tidy_env rhs
389
390 tidyTopBind mod ext_ids cg_info_env top_tidy_env (Rec prs)
391   = (final_env, Rec prs')
392   where
393     (final_env@(_,occ,subst), prs') = mapAccumL do_one top_tidy_env prs
394     rec_tidy_env = (occ,subst)
395
396     do_one top_tidy_env (bndr,rhs) 
397         = ((orig,occ,subst), (bndr',rhs'))
398         where
399         ((orig,occ,subst), bndr')
400            = tidyTopBinder mod ext_ids cg_info_env 
401                 rec_tidy_env rhs' top_tidy_env bndr
402
403         rhs' = tidyExpr rec_tidy_env rhs
404
405 tidyTopBinder :: Module -> IdEnv Bool
406               -> CgInfoEnv
407               -> TidyEnv -> CoreExpr
408                         -- The TidyEnv is used to tidy the IdInfo
409                         -- The expr is the already-tided RHS
410                         -- Both are knot-tied: don't look at them!
411               -> TopTidyEnv -> Id -> (TopTidyEnv, Id)
412   -- NB: tidyTopBinder doesn't affect the unique supply
413
414 tidyTopBinder mod ext_ids cg_info_env tidy_env rhs
415               env@(ns2, occ_env2, subst_env2) id
416
417   | isDataConWrapId id  -- Don't tidy constructor wrappers
418   = (env, id)           -- The Id is stored in the TyCon, so it would be bad
419                         -- if anything changed
420
421 -- HACK ALERT: we *do* tidy record selectors.  Reason: they mention error
422 -- messages, which may be floated out:
423 --      x_field pt = case pt of
424 --                      Rect x y -> y
425 --                      Pol _ _  -> error "buggle wuggle"
426 -- The error message will be floated out so we'll get
427 --      lvl5 = error "buggle wuggle"
428 --      x_field pt = case pt of
429 --                      Rect x y -> y
430 --                      Pol _ _  -> lvl5
431 --
432 -- When this happens, it's vital that the Id exposed to importing modules
433 -- (by ghci) mentions lvl5 in its unfolding, not the un-tidied version.
434 -- 
435 -- What about the Id in the TyCon?  It probably shouldn't be in the TyCon at
436 -- all, but in any case it will have the error message inline so it won't matter.
437
438
439   | otherwise
440         -- This function is the heart of Step 2
441         -- The second env is the one to use for the IdInfo
442         -- It's necessary because when we are dealing with a recursive
443         -- group, a variable late in the group might be mentioned
444         -- in the IdInfo of one early in the group
445
446         -- The rhs is already tidied
447         
448   = ((orig_env', occ_env', subst_env'), id')
449   where
450     (orig_env', occ_env', name') = tidyTopName mod ns2 occ_env2
451                                                is_external
452                                                (idName id)
453     ty'     = tidyTopType (idType id)
454     cg_info = lookupCgInfo cg_info_env name'
455     idinfo' = tidyIdInfo tidy_env is_external unfold_info cg_info id
456
457     id' | isGlobalId id = mkGlobalId (globalIdDetails id) name' ty' idinfo'
458         | otherwise     = mkVanillaGlobal                 name' ty' idinfo'
459         -- The test ensures that record selectors (which must be tidied; see above)
460         -- retain their details.  If it's forgotten, importing modules get confused.
461
462     subst_env' = extendVarEnv subst_env2 id id'
463
464     maybe_external = lookupVarEnv ext_ids id
465     is_external    = isJust maybe_external
466
467     -- Expose an unfolding if ext_ids tells us to
468     show_unfold = maybe_external `orElse` False
469     unfold_info | show_unfold = mkTopUnfolding rhs
470                 | otherwise   = noUnfolding
471
472
473 tidyIdInfo tidy_env is_external unfold_info cg_info id
474   | opt_OmitInterfacePragmas || not is_external
475         -- No IdInfo if the Id isn't external, or if we don't have -O
476   = vanillaIdInfo 
477         `setCgInfo`            cg_info
478         `setNewStrictnessInfo` newStrictnessInfo core_idinfo
479         -- Keep strictness; it's used by CorePrep
480
481   | otherwise
482   =  vanillaIdInfo 
483         `setCgInfo`            cg_info
484         `setNewStrictnessInfo` newStrictnessInfo core_idinfo
485         `setInlinePragInfo`    inlinePragInfo core_idinfo
486         `setUnfoldingInfo`     unfold_info
487         `setWorkerInfo`        tidyWorker tidy_env (workerInfo core_idinfo)
488         -- NB: we throw away the Rules
489         -- They have already been extracted by findExternalRules
490   where
491     core_idinfo = idInfo id
492
493
494 -- This is where we set names to local/global based on whether they really are 
495 -- externally visible (see comment at the top of this module).  If the name
496 -- was previously local, we have to give it a unique occurrence name if
497 -- we intend to globalise it.
498 tidyTopName mod ns occ_env external name
499   | global && internal = (ns, occ_env, localiseName name)
500
501   | global && external = (ns, occ_env, name)
502         -- Global names are assumed to have been allocated by the renamer,
503         -- so they already have the "right" unique
504         -- And it's a system-wide unique too
505
506   | local  && internal = (ns { nsUniqs = us2 }, occ_env', unique_name)
507         -- Even local, internal names must get a unique occurrence, because
508         -- if we do -split-objs we globalise the name later, in the code generator
509         --
510         -- Similarly, we must make sure it has a system-wide Unique, because
511         -- the byte-code generator builds a system-wide Name->BCO symbol table
512
513   | local  && external = case lookupFM ns_names key of
514                            Just orig -> (ns,                                        occ_env', orig)
515                            Nothing   -> (ns { nsUniqs = us2, nsNames = ns_names' }, occ_env', global_name)
516         -- If we want to globalise a currently-local name, check
517         -- whether we have already assigned a unique for it.
518         -- If so, use it; if not, extend the table
519
520   where
521     global           = isGlobalName name
522     local            = not global
523     internal         = not external
524
525     (occ_env', occ') = tidyOccName occ_env (nameOccName name)
526     key              = (moduleName mod, occ')
527     ns_names         = nsNames ns
528     ns_uniqs         = nsUniqs ns
529     (us1, us2)       = splitUniqSupply ns_uniqs
530     unique_name      = setNameUnique (setNameOcc name occ') (uniqFromSupply us1)
531     global_name      = globaliseName unique_name mod
532     ns_names'        = addToFM ns_names key global_name
533
534
535 ------------  Worker  --------------
536 tidyWorker tidy_env (HasWorker work_id wrap_arity) 
537   = HasWorker (tidyVarOcc tidy_env work_id) wrap_arity
538 tidyWorker tidy_env other
539   = NoWorker
540
541 ------------  Rules  --------------
542 tidyIdRules :: TidyEnv -> [IdCoreRule] -> [IdCoreRule]
543 tidyIdRules env [] = []
544 tidyIdRules env ((fn,rule) : rules)
545   = tidyRule env rule           =: \ rule ->
546     tidyIdRules env rules       =: \ rules ->
547      ((tidyVarOcc env fn, rule) : rules)
548
549 tidyRule :: TidyEnv -> CoreRule -> CoreRule
550 tidyRule env rule@(BuiltinRule _ _) = rule
551 tidyRule env (Rule name act vars tpl_args rhs)
552   = tidyBndrs env vars                  =: \ (env', vars) ->
553     map (tidyExpr env') tpl_args        =: \ tpl_args ->
554      (Rule name act vars tpl_args (tidyExpr env' rhs))
555 \end{code}
556
557 %************************************************************************
558 %*                                                                      *
559 \subsection{Step 2: inner tidying
560 %*                                                                      *
561 %************************************************************************
562
563 \begin{code}
564 tidyBind :: TidyEnv
565          -> CoreBind
566          ->  (TidyEnv, CoreBind)
567
568 tidyBind env (NonRec bndr rhs)
569   = tidyLetBndr env (bndr,rhs)          =: \ (env', bndr') ->
570     (env', NonRec bndr' (tidyExpr env' rhs))
571
572 tidyBind env (Rec prs)
573   = mapAccumL tidyLetBndr env prs       =: \ (env', bndrs') ->
574     map (tidyExpr env') (map snd prs)   =: \ rhss' ->
575     (env', Rec (zip bndrs' rhss'))
576
577
578 tidyExpr env (Var v)    =  Var (tidyVarOcc env v)
579 tidyExpr env (Type ty)  =  Type (tidyType env ty)
580 tidyExpr env (Lit lit)  =  Lit lit
581 tidyExpr env (App f a)  =  App (tidyExpr env f) (tidyExpr env a)
582 tidyExpr env (Note n e) =  Note (tidyNote env n) (tidyExpr env e)
583
584 tidyExpr env (Let b e) 
585   = tidyBind env b      =: \ (env', b') ->
586     Let b' (tidyExpr env' e)
587
588 tidyExpr env (Case e b alts)
589   = tidyBndr env b      =: \ (env', b) ->
590     Case (tidyExpr env e) b (map (tidyAlt env') alts)
591
592 tidyExpr env (Lam b e)
593   = tidyBndr env b      =: \ (env', b) ->
594     Lam b (tidyExpr env' e)
595
596
597 tidyAlt env (con, vs, rhs)
598   = tidyBndrs env vs    =: \ (env', vs) ->
599     (con, vs, tidyExpr env' rhs)
600
601 tidyNote env (Coerce t1 t2)  = Coerce (tidyType env t1) (tidyType env t2)
602 tidyNote env note            = note
603 \end{code}
604
605
606 %************************************************************************
607 %*                                                                      *
608 \subsection{Tidying up non-top-level binders}
609 %*                                                                      *
610 %************************************************************************
611
612 \begin{code}
613 tidyVarOcc (_, var_env) v = case lookupVarEnv var_env v of
614                                   Just v' -> v'
615                                   Nothing -> v
616
617 -- tidyBndr is used for lambda and case binders
618 tidyBndr :: TidyEnv -> Var -> (TidyEnv, Var)
619 tidyBndr env var
620   | isTyVar var = tidyTyVarBndr env var
621   | otherwise   = tidyIdBndr env var
622
623 tidyBndrs :: TidyEnv -> [Var] -> (TidyEnv, [Var])
624 tidyBndrs env vars = mapAccumL tidyBndr env vars
625
626 tidyLetBndr :: TidyEnv -> (Id, CoreExpr) -> (TidyEnv, Var)
627 -- Used for local (non-top-level) let(rec)s
628 tidyLetBndr env (id,rhs) 
629   = ((tidy_env,new_var_env), final_id)
630   where
631     ((tidy_env,var_env), new_id) = tidyIdBndr env id
632
633         -- We need to keep around any interesting strictness and demand info
634         -- because later on we may need to use it when converting to A-normal form.
635         -- eg.
636         --      f (g x),  where f is strict in its argument, will be converted
637         --      into  case (g x) of z -> f z  by CorePrep, but only if f still
638         --      has its strictness info.
639         --
640         -- Similarly for the demand info - on a let binder, this tells 
641         -- CorePrep to turn the let into a case.
642     final_id
643         | totally_boring_info = new_id
644         | otherwise = new_id `setIdNewDemandInfo` dmd_info
645                              `setIdNewStrictness` fromJust maybe_new_strictness
646
647     -- override the env we get back from tidyId with the new IdInfo
648     -- so it gets propagated to the usage sites.
649     new_var_env = extendVarEnv var_env id final_id
650
651     dmd_info             = idNewDemandInfo id
652     maybe_new_strictness = idNewStrictness_maybe id
653     totally_boring_info  = isNothing maybe_new_strictness && not (isStrictDmd dmd_info) 
654
655 tidyIdBndr :: TidyEnv -> Id -> (TidyEnv, Id)
656 tidyIdBndr env@(tidy_env, var_env) id
657   =     -- Non-top-level variables
658     let 
659         -- Give the Id a fresh print-name, *and* rename its type
660         -- The SrcLoc isn't important now, 
661         -- though we could extract it from the Id
662         -- 
663         -- All local Ids now have the same IdInfo, which should save some
664         -- space.
665         (tidy_env', occ') = tidyOccName tidy_env (getOccName id)
666         ty'               = tidyType env (idType id)
667         id'               = mkUserLocal occ' (idUnique id) ty' noSrcLoc
668         var_env'          = extendVarEnv var_env id id'
669     in
670      ((tidy_env', var_env'), id')
671 \end{code}
672
673 \begin{code}
674 m =: k = m `seq` k m
675 \end{code}