[project @ 2000-12-07 08:18:18 by simonpj]
[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, 
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 CoreUtils        ( exprArity )
18 import CoreFVs          ( ruleSomeFreeVars, exprSomeFreeVars )
19 import CoreLint         ( showPass, endPass )
20 import VarEnv
21 import VarSet
22 import Var              ( Id, Var )
23 import Id               ( idType, idInfo, idName, isExportedId,
24                           mkId, isLocalId, omitIfaceSigForId
25                         ) 
26 import IdInfo           ( IdInfo, mkIdInfo, vanillaIdInfo,
27                           IdFlavour(..), flavourInfo, ppFlavourInfo,
28                           specInfo, setSpecInfo, 
29                           cprInfo, setCprInfo, 
30                           inlinePragInfo, setInlinePragInfo, isNeverInlinePrag,
31                           strictnessInfo, setStrictnessInfo, 
32                           isBottomingStrictness,
33                           unfoldingInfo, setUnfoldingInfo, 
34                           occInfo, isLoopBreaker,
35                           workerInfo, setWorkerInfo, WorkerInfo(..),
36                           ArityInfo(..), setArityInfo
37                         )
38 import Name             ( getOccName, nameOccName, globaliseName, setNameOcc, 
39                           localiseName, mkLocalName, isGlobalName
40                         )
41 import OccName          ( TidyOccEnv, initTidyOccEnv, tidyOccName )
42 import Type             ( tidyTopType, tidyType, tidyTyVar )
43 import Module           ( Module, moduleName )
44 import HscTypes         ( PersistentCompilerState( pcs_PRS ), PersistentRenamerState( prsOrig ),
45                           OrigNameEnv( origNames ), OrigNameNameEnv
46                         )
47 import UniqSupply
48 import FiniteMap        ( lookupFM, addToFM )
49 import Maybes           ( maybeToBool, orElse )
50 import ErrUtils         ( showPass )
51 import SrcLoc           ( noSrcLoc )
52 import UniqFM           ( mapUFM )
53 import Outputable
54 import List             ( partition )
55 import Util             ( mapAccumL )
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   - Make all external Ids have Global names and vice versa
90     This is used by the code generator to decide whether
91     to make the label externally visible
92
93   - Give external ids a "tidy" occurrence name.  This means
94     we can print them in interface files without confusing 
95     "x" (unique 5) with "x" (unique 10).
96   
97   - Give external Ids the same Unique as they had before
98     if the name is in the renamer's name cache
99   
100   - Clone all local Ids.  This means that Tidy Core has the property
101     that all Ids are unique, rather than the weaker guarantee of
102     no clashes which the simplifier provides.
103
104   - Give the Id its final IdInfo; in ptic, 
105         * Its flavour becomes ConstantId, reflecting the fact that
106           from now on we regard it as a constant, not local, Id
107         * its unfolding, if it should have one
108                 
109 Finally, substitute these new top-level binders consistently
110 throughout, including in unfoldings.  We also tidy binders in
111 RHSs, so that they print nicely in interfaces.
112
113 \begin{code}
114 tidyCorePgm :: DynFlags -> Module
115             -> PersistentCompilerState
116             -> [CoreBind] -> [IdCoreRule]
117             -> IO (PersistentCompilerState, [CoreBind], [IdCoreRule])
118 tidyCorePgm dflags mod pcs binds_in orphans_in
119   = do  { showPass dflags "Tidy Core"
120
121         ; let ext_ids = findExternalSet binds_in orphans_in
122
123         ; us <- mkSplitUniqSupply 't' -- for "tidy"
124
125         ; let ((us1, orig_env', occ_env, subst_env), binds_out) 
126                         = mapAccumL (tidyTopBind mod ext_ids) 
127                                     (init_tidy_env us) binds_in
128
129         ; let (orphans_out, _) 
130                    = initUs us1 (tidyIdRules (occ_env,subst_env) orphans_in)
131
132         ; let prs' = prs { prsOrig = orig { origNames = orig_env' } }
133               pcs' = pcs { pcs_PRS = prs' }
134
135         ; endPass dflags "Tidy Core" Opt_D_dump_simpl binds_out
136
137         ; return (pcs', binds_out, orphans_out)
138         }
139   where
140         -- We also make sure to avoid any exported binders.  Consider
141         --      f{-u1-} = 1     -- Local decl
142         --      ...
143         --      f{-u2-} = 2     -- Exported decl
144         --
145         -- The second exported decl must 'get' the name 'f', so we
146         -- have to put 'f' in the avoids list before we get to the first
147         -- decl.  tidyTopId then does a no-op on exported binders.
148     prs              = pcs_PRS pcs
149     orig             = prsOrig prs
150     orig_env         = origNames orig
151
152     init_tidy_env us = (us, orig_env, initTidyOccEnv avoids, emptyVarEnv)
153     avoids           = [getOccName bndr | bndr <- bindersOfBinds binds_in,
154                                        isGlobalName (idName bndr)]
155 \end{code}
156
157
158 %************************************************************************
159 %*                                                                      *
160 \subsection{Step 1: finding externals}
161 %*                                                                      * 
162 %************************************************************************
163
164 \begin{code}
165 findExternalSet :: [CoreBind] -> [IdCoreRule]
166                 -> IdEnv Bool   -- True <=> show unfolding
167         -- Step 1 from the notes above
168 findExternalSet binds orphan_rules
169   = foldr find init_needed binds
170   where
171     orphan_rule_ids :: IdSet
172     orphan_rule_ids = unionVarSets [ ruleSomeFreeVars isIdAndLocal rule 
173                                    | (_, rule) <- orphan_rules]
174     init_needed :: IdEnv Bool
175     init_needed = mapUFM (\_ -> False) orphan_rule_ids
176         -- The mapUFM is a bit cheesy.  It is a cheap way
177         -- to turn the set of orphan_rule_ids, which we use to initialise
178         -- the sweep, into a mapping saying 'don't expose unfolding'    
179         -- (When we come to the binding site we may change our mind, of course.)
180
181     find (NonRec id rhs) needed
182         | need_id needed id = addExternal (id,rhs) needed
183         | otherwise         = needed
184     find (Rec prs) needed   = find_prs prs needed
185
186         -- For a recursive group we have to look for a fixed point
187     find_prs prs needed 
188         | null needed_prs = needed
189         | otherwise       = find_prs other_prs new_needed
190         where
191           (needed_prs, other_prs) = partition (need_pr needed) prs
192           new_needed = foldr addExternal needed needed_prs
193
194         -- The 'needed' set contains the Ids that are needed by earlier
195         -- interface file emissions.  If the Id isn't in this set, and isn't
196         -- exported, there's no need to emit anything
197     need_id needed_set id       = id `elemVarEnv` needed_set || isExportedId id 
198     need_pr needed_set (id,rhs) = need_id needed_set id
199
200 isIdAndLocal id = isId id && isLocalId id
201
202 addExternal :: (Id,CoreExpr) -> IdEnv Bool -> IdEnv Bool
203 -- The Id is needed; extend the needed set
204 -- with it and its dependents (free vars etc)
205 addExternal (id,rhs) needed
206   = extendVarEnv (foldVarSet add_occ needed new_needed_ids)
207                  id show_unfold
208   where
209     add_occ id needed = extendVarEnv needed id False
210         -- "False" because we don't know we need the Id's unfolding
211         -- We'll override it later when we find the binding site
212
213     new_needed_ids | opt_OmitInterfacePragmas = emptyVarSet
214                    | otherwise                = worker_ids      `unionVarSet`
215                                                 unfold_ids      `unionVarSet`
216                                                 spec_ids
217
218     idinfo         = idInfo id
219     dont_inline    = isNeverInlinePrag (inlinePragInfo idinfo)
220     loop_breaker   = isLoopBreaker (occInfo idinfo)
221     bottoming_fn   = isBottomingStrictness (strictnessInfo idinfo)
222     spec_ids       = rulesRhsFreeVars (specInfo idinfo)
223     worker_info    = workerInfo idinfo
224
225         -- Stuff to do with the Id's unfolding
226         -- The simplifier has put an up-to-date unfolding
227         -- in the IdInfo, but the RHS will do just as well
228     unfolding    = unfoldingInfo idinfo
229     rhs_is_small = not (neverUnfold unfolding)
230
231         -- We leave the unfolding there even if there is a worker
232         -- In GHCI the unfolding is used by importers
233         -- When writing an interface file, we omit the unfolding 
234         -- if there is a worker
235     show_unfold = not bottoming_fn       &&     -- Not necessary
236                   not dont_inline        &&
237                   not loop_breaker       &&
238                   rhs_is_small           &&     -- Small enough
239                   okToUnfoldInHiFile rhs        -- No casms etc
240
241     unfold_ids | show_unfold = exprSomeFreeVars isIdAndLocal rhs
242                | otherwise   = emptyVarSet
243
244     worker_ids = case worker_info of
245                    HasWorker work_id _ -> unitVarSet work_id
246                    otherwise           -> emptyVarSet
247 \end{code}
248
249
250 %************************************************************************
251 %*                                                                      *
252 \subsection{Step 2: top-level tidying}
253 %*                                                                      *
254 %************************************************************************
255
256
257 \begin{code}
258 type TopTidyEnv = (UniqSupply, OrigNameNameEnv, TidyOccEnv, VarEnv Var)
259
260 -- TopTidyEnv: when tidying we need to know
261 --   * orig_env: Any pre-ordained Names.  These may have arisen because the
262 --        renamer read in an interface file mentioning M.$wf, say,
263 --        and assigned it unique r77.  If, on this compilation, we've
264 --        invented an Id whose name is $wf (but with a different unique)
265 --        we want to rename it to have unique r77, so that we can do easy
266 --        comparisons with stuff from the interface file
267 --
268 --   * occ_env: The TidyOccEnv, which tells us which local occurrences 
269 --     are 'used'
270 --
271 --   * subst_env: A Var->Var mapping that substitutes the new Var for the old
272 --
273 --   * uniqsuppy: so we can clone any Ids with non-preordained names.
274 --
275 \end{code}
276
277
278 \begin{code}
279 tidyTopBind :: Module
280             -> IdEnv Bool       -- Domain = Ids that should be external
281                                 -- True <=> their unfolding is external too
282             -> TopTidyEnv -> CoreBind
283             -> (TopTidyEnv, CoreBind)
284
285 tidyTopBind mod ext_ids env (NonRec bndr rhs)
286   = ((us2,orig,occ,subst) , NonRec bndr' rhs')
287   where
288     tidy_env                      = (occ,subst)
289     ((us1,orig,occ,subst), bndr') = tidyTopBinder mod ext_ids tidy_env rhs' env bndr
290     (rhs',us2)                    = initUs us1 (tidyExpr tidy_env rhs)
291
292 tidyTopBind mod ext_ids env (Rec prs)
293   = (final_env, Rec prs')
294   where
295     (final_env@(_,_,occ,subst), prs') = mapAccumL do_one env prs
296     final_tidy_env = (occ,subst)
297
298     do_one env (bndr,rhs) 
299         = ((us',orig,occ,subst), (bndr',rhs'))
300         where
301         ((us,orig,occ,subst), bndr') = tidyTopBinder mod ext_ids final_tidy_env rhs' env bndr
302         (rhs', us')                  = initUs us (tidyExpr final_tidy_env rhs)
303
304 tidyTopBinder :: Module -> IdEnv Bool
305               -> TidyEnv -> CoreExpr    -- The TidyEnv is used to tidy the IdInfo
306                                         -- The expr is the already-tided RHS
307                                         -- Both are knot-tied: don't look at them!
308               -> TopTidyEnv -> Id -> (TopTidyEnv, Id)
309 tidyTopBinder mod ext_ids tidy_env rhs 
310               env@(us, orig_env2, occ_env2, subst_env2) id
311
312   | omitIfaceSigForId id        -- Don't mess with constructors, 
313   = (env, id)                   -- record selectors, and the like
314
315   | otherwise
316         -- This function is the heart of Step 2
317         -- The second env is the one to use for the IdInfo
318         -- It's necessary because when we are dealing with a recursive
319         -- group, a variable late in the group might be mentioned
320         -- in the IdInfo of one early in the group
321
322         -- The rhs is already tidied
323         
324   = ((us_r, orig_env', occ_env', subst_env'), id')
325   where
326     (us_l, us_r)    = splitUniqSupply us
327
328     (orig_env', occ_env', name') = tidyTopName mod orig_env2 occ_env2
329                                                is_external
330                                                (idName id)
331     ty'             = tidyTopType (idType id)
332     idinfo'         = tidyIdInfo us_l tidy_env
333                          is_external unfold_info arity_info id
334
335     id'        = mkId name' ty' idinfo'
336     subst_env' = extendVarEnv subst_env2 id id'
337
338     maybe_external = lookupVarEnv ext_ids id
339     is_external    = maybeToBool maybe_external
340
341     -- Expose an unfolding if ext_ids tells us to
342     show_unfold = maybe_external `orElse` False
343     unfold_info | show_unfold = mkTopUnfolding rhs
344                 | otherwise   = noUnfolding
345
346     arity_info = exprArity rhs
347
348
349 tidyIdInfo us tidy_env is_external unfold_info arity_info id
350   | opt_OmitInterfacePragmas || not is_external
351         -- No IdInfo if the Id isn't external, or if we don't have -O
352   = mkIdInfo new_flavour 
353         `setStrictnessInfo` strictnessInfo core_idinfo
354         `setArityInfo`      ArityExactly arity_info
355         -- Keep strictness and arity info; it's used by the code generator
356
357   | otherwise
358   =  let (rules', _) = initUs us (tidyRules tidy_env (specInfo core_idinfo))
359      in
360      mkIdInfo new_flavour
361         `setCprInfo`        cprInfo core_idinfo
362         `setStrictnessInfo` strictnessInfo core_idinfo
363         `setInlinePragInfo` inlinePragInfo core_idinfo
364         `setUnfoldingInfo`  unfold_info
365         `setWorkerInfo`     tidyWorker tidy_env (workerInfo core_idinfo)
366         `setSpecInfo`       rules'
367         `setArityInfo`      ArityExactly arity_info
368                 -- this is the final IdInfo, it must agree with the
369                 -- code finally generated (i.e. NO more transformations
370                 -- after this!).
371   where
372     core_idinfo = idInfo id
373
374         -- A DFunId must stay a DFunId, so that we can gather the
375         -- DFunIds up later.  Other local things become ConstantIds.
376     new_flavour = case flavourInfo core_idinfo of
377                     VanillaId  -> ConstantId
378                     ExportedId -> ConstantId
379                     ConstantId -> ConstantId    -- e.g. Default methods
380                     DictFunId  -> DictFunId
381                     flavour    -> pprTrace "tidyIdInfo" (ppr id <+> ppFlavourInfo flavour)
382                                   flavour
383
384 -- This is where we set names to local/global based on whether they really are 
385 -- externally visible (see comment at the top of this module).  If the name
386 -- was previously local, we have to give it a unique occurrence name if
387 -- we intend to globalise it.
388 tidyTopName mod orig_env occ_env external name
389   | global && internal = (orig_env, occ_env, localiseName name)
390
391   | local  && internal = (orig_env, occ_env', setNameOcc name occ')
392         -- Even local, internal names must get a unique occurrence, because
393         -- if we do -split-objs we globalise the name later, n the code generator
394
395   | global && external = (orig_env, occ_env, name)
396         -- Global names are assumed to have been allocated by the renamer,
397         -- so they already have the "right" unique
398
399   | local  && external = case lookupFM orig_env key of
400                            Just orig -> (orig_env,                         occ_env', orig)
401                            Nothing   -> (addToFM orig_env key global_name, occ_env', global_name)
402         -- If we want to globalise a currently-local name, check
403         -- whether we have already assigned a unique for it.
404         -- If so, use it; if not, extend the table
405
406   where
407     (occ_env', occ') = tidyOccName occ_env (nameOccName name)
408     key              = (moduleName mod, occ')
409     global_name      = globaliseName (setNameOcc name occ') mod
410     global           = isGlobalName name
411     local            = not global
412     internal         = not external
413
414 tidyIdRules :: TidyEnv -> [IdCoreRule] -> UniqSM [IdCoreRule]
415 tidyIdRules env [] = returnUs []
416 tidyIdRules env ((fn,rule) : rules)
417   = tidyRule env rule           `thenUs` \ rule ->
418     tidyIdRules env rules       `thenUs` \ rules ->
419     returnUs ((tidyVarOcc env fn, rule) : rules)
420
421 tidyWorker tidy_env (HasWorker work_id wrap_arity) 
422   = HasWorker (tidyVarOcc tidy_env work_id) wrap_arity
423 tidyWorker tidy_env NoWorker
424   = NoWorker
425
426 tidyRules :: TidyEnv -> CoreRules -> UniqSM CoreRules
427 tidyRules env (Rules rules fvs) 
428   = mapUs (tidyRule env) rules          `thenUs` \ rules ->
429     returnUs (Rules rules (foldVarSet tidy_set_elem emptyVarSet fvs))
430   where
431     tidy_set_elem var new_set = extendVarSet new_set (tidyVarOcc env var)
432
433 tidyRule :: TidyEnv -> CoreRule -> UniqSM CoreRule
434 tidyRule env rule@(BuiltinRule _) = returnUs rule
435 tidyRule env (Rule name vars tpl_args rhs)
436   = tidyBndrs env vars                  `thenUs` \ (env', vars) ->
437     mapUs (tidyExpr env') tpl_args      `thenUs` \ tpl_args ->
438     tidyExpr env' rhs                   `thenUs` \ rhs ->
439     returnUs (Rule name vars tpl_args rhs)
440 \end{code}
441
442 %************************************************************************
443 %*                                                                      *
444 \subsection{Step 2: inner tidying
445 %*                                                                      *
446 %************************************************************************
447
448 \begin{code}
449 tidyBind :: TidyEnv
450          -> CoreBind
451          -> UniqSM (TidyEnv, CoreBind)
452 tidyBind env (NonRec bndr rhs)
453   = tidyBndrWithRhs env (bndr,rhs) `thenUs` \ (env', bndr') ->
454     tidyExpr env' rhs              `thenUs` \ rhs' ->
455     returnUs (env', NonRec bndr' rhs')
456
457 tidyBind env (Rec prs)
458   = mapAccumLUs tidyBndrWithRhs env prs         `thenUs` \ (env', bndrs') ->
459     mapUs (tidyExpr env') (map snd prs)         `thenUs` \ rhss' ->
460     returnUs (env', Rec (zip bndrs' rhss'))
461
462 tidyExpr env (Var v)   = returnUs (Var (tidyVarOcc env v))
463 tidyExpr env (Type ty) = returnUs (Type (tidyType env ty))
464 tidyExpr env (Lit lit) = returnUs (Lit lit)
465
466 tidyExpr env (App f a)
467   = tidyExpr env f              `thenUs` \ f ->
468     tidyExpr env a              `thenUs` \ a ->
469     returnUs (App f a)
470
471 tidyExpr env (Note n e)
472   = tidyExpr env e              `thenUs` \ e ->
473     returnUs (Note (tidyNote env n) e)
474
475 tidyExpr env (Let b e) 
476   = tidyBind env b              `thenUs` \ (env', b') ->
477     tidyExpr env' e             `thenUs` \ e ->
478     returnUs (Let b' e)
479
480 tidyExpr env (Case e b alts)
481   = tidyExpr env e              `thenUs` \ e ->
482     tidyBndr env b              `thenUs` \ (env', b) ->
483     mapUs (tidyAlt env') alts   `thenUs` \ alts ->
484     returnUs (Case e b alts)
485
486 tidyExpr env (Lam b e)
487   = tidyBndr env b              `thenUs` \ (env', b) ->
488     tidyExpr env' e             `thenUs` \ e ->
489     returnUs (Lam b e)
490
491
492 tidyAlt env (con, vs, rhs)
493   = tidyBndrs env vs            `thenUs` \ (env', vs) ->
494     tidyExpr env' rhs           `thenUs` \ rhs ->
495     returnUs (con, vs, rhs)
496
497 tidyNote env (Coerce t1 t2)  = Coerce (tidyType env t1) (tidyType env t2)
498 tidyNote env note            = note
499 \end{code}
500
501
502 %************************************************************************
503 %*                                                                      *
504 \subsection{Tidying up non-top-level binders}
505 %*                                                                      *
506 %************************************************************************
507
508 \begin{code}
509 tidyVarOcc (_, var_env) v = case lookupVarEnv var_env v of
510                                   Just v' -> v'
511                                   Nothing -> v
512
513 -- tidyBndr is used for lambda and case binders
514 tidyBndr :: TidyEnv -> Var -> UniqSM (TidyEnv, Var)
515 tidyBndr env var
516   | isTyVar var = returnUs (tidyTyVar env var)
517   | otherwise   = tidyId env var vanillaIdInfo
518
519 tidyBndrs :: TidyEnv -> [Var] -> UniqSM (TidyEnv, [Var])
520 tidyBndrs env vars = mapAccumLUs tidyBndr env vars
521
522 -- tidyBndrWithRhs is used for let binders
523 tidyBndrWithRhs :: TidyEnv -> (Var, CoreExpr) -> UniqSM (TidyEnv, Var)
524 tidyBndrWithRhs env (id,rhs)
525    = tidyId env id idinfo
526    where
527         idinfo = vanillaIdInfo `setArityInfo` ArityExactly (exprArity rhs)
528                         -- NB: This throws away the IdInfo of the Id, which we
529                         -- no longer need.  That means we don't need to
530                         -- run over it with env, nor renumber it.
531
532 tidyId :: TidyEnv -> Id -> IdInfo -> UniqSM (TidyEnv, Id)
533 tidyId env@(tidy_env, var_env) id idinfo
534   =     -- Non-top-level variables
535     getUniqueUs   `thenUs` \ uniq ->
536     let 
537         -- Give the Id a fresh print-name, *and* rename its type
538         -- The SrcLoc isn't important now, 
539         -- though we could extract it from the Id
540         name'             = mkLocalName uniq occ' noSrcLoc
541         (tidy_env', occ') = tidyOccName tidy_env (getOccName id)
542         ty'               = tidyType (tidy_env,var_env) (idType id)
543         id'               = mkId name' ty' idinfo
544         var_env'          = extendVarEnv var_env id id'
545     in
546     returnUs ((tidy_env', var_env'), id')
547 \end{code}