[project @ 1998-04-30 19:08:56 by sof]
[ghc-hetmet.git] / ghc / compiler / simplCore / OccurAnal.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 %************************************************************************
5 %*                                                                      *
6 \section[OccurAnal]{Occurrence analysis pass}
7 %*                                                                      *
8 %************************************************************************
9
10 The occurrence analyser re-typechecks a core expression, returning a new
11 core expression with (hopefully) improved usage information.
12
13 \begin{code}
14 module OccurAnal (
15         occurAnalyseBinds, occurAnalyseExpr, occurAnalyseGlobalExpr
16     ) where
17
18 #include "HsVersions.h"
19
20 import BinderInfo
21 import CmdLineOpts      ( opt_D_dump_occur_anal, SimplifierSwitch(..) )
22 import CoreSyn
23 import CoreUtils        ( idSpecVars )
24 import Digraph          ( stronglyConnCompR, SCC(..) )
25 import Id               ( idWantsToBeINLINEd, addNoInlinePragma, nukeNoInlinePragma,
26                           omitIfaceSigForId, isSpecPragmaId, getIdSpecialisation,
27                           idType, idUnique, Id,
28                           emptyIdSet, unionIdSets, mkIdSet,
29                           elementOfIdSet,
30                           addOneToIdSet, IdSet,
31
32                           IdEnv, nullIdEnv, unitIdEnv, combineIdEnvs,
33                           delOneFromIdEnv, delManyFromIdEnv, isNullIdEnv, 
34                           mapIdEnv, lookupIdEnv, elemIdEnv, addOneToIdEnv
35                         )
36 import SpecEnv          ( isEmptySpecEnv )
37 import Name             ( isExported, isLocallyDefined )
38 import Type             ( splitFunTy_maybe, splitForAllTys )
39 import Maybes           ( maybeToBool )
40 import PprCore
41 import Unique           ( u2i )
42 import UniqFM           ( keysUFM )  
43 import Util             ( zipWithEqual )
44 import Outputable
45 \end{code}
46
47
48 %************************************************************************
49 %*                                                                      *
50 \subsection[OccurAnal-main]{Counting occurrences: main function}
51 %*                                                                      *
52 %************************************************************************
53
54 Here's the externally-callable interface:
55
56 \begin{code}
57 occurAnalyseBinds
58         :: [CoreBinding]                -- input
59         -> (SimplifierSwitch -> Bool)
60         -> [SimplifiableCoreBinding]    -- output
61
62 occurAnalyseBinds binds simplifier_sw_chkr
63   | opt_D_dump_occur_anal = pprTrace "OccurAnal:"
64                                      (pprGenericBindings binds')
65                                      binds'
66   | otherwise             = binds'
67   where
68     (_, _, binds') = occAnalTop initial_env binds
69
70     initial_env = OccEnv (simplifier_sw_chkr IgnoreINLINEPragma)
71                          (\id in_scope -> isLocallyDefined id)  -- Anything local is interesting
72                          emptyIdSet                             -- Not actually used
73 \end{code}
74
75
76 \begin{code}
77 occurAnalyseExpr :: (Id -> Bool)        -- Tells if a variable is interesting
78                  -> CoreExpr
79                  -> (IdEnv BinderInfo,  -- Occ info for interesting free vars
80                      SimplifiableCoreExpr)
81
82 occurAnalyseExpr interesting expr
83   = occAnal initial_env expr
84   where
85     initial_env = OccEnv False {- Do not ignore INLINE Pragma -}
86                          (\id locals -> interesting id || elementOfIdSet id locals)
87                          emptyIdSet
88
89 occurAnalyseGlobalExpr :: CoreExpr -> SimplifiableCoreExpr
90 occurAnalyseGlobalExpr expr
91   =     -- Top level expr, so no interesting free vars, and
92         -- discard occurence info returned
93     snd (occurAnalyseExpr (\_ -> False) expr)
94 \end{code}
95
96
97 %************************************************************************
98 %*                                                                      *
99 \subsection{Top level stuff}
100 %*                                                                      *
101 %************************************************************************
102
103 In @occAnalTop@ we do indirection-shorting.  That is, if we have this:
104
105         loc = <expression>
106         ...
107         exp = loc
108
109 where exp is exported, and loc is not, then we replace it with this:
110
111         loc = exp
112         exp = <expression>
113         ...
114
115 Without this we never get rid of the exp = loc thing.
116 This save a gratuitous jump
117 (from \tr{x_exported} to \tr{x_local}), and makes strictness
118 information propagate better.
119 This used to happen in the final phase, but its tidier to do it here.
120
121
122 If more than one exported thing is equal to a local thing (i.e., the
123 local thing really is shared), then we do one only:
124 \begin{verbatim}
125         x_local = ....
126         x_exported1 = x_local
127         x_exported2 = x_local
128 ==>
129         x_exported1 = ....
130
131         x_exported2 = x_exported1
132 \end{verbatim}
133
134 We rely on prior eta reduction to simplify things like
135 \begin{verbatim}
136         x_exported = /\ tyvars -> x_local tyvars
137 ==>
138         x_exported = x_local
139 \end{verbatim}
140 Hence,there's a possibility of leaving unchanged something like this:
141 \begin{verbatim}
142         x_local = ....
143         x_exported1 = x_local Int
144 \end{verbatim}
145 By the time we've thrown away the types in STG land this 
146 could be eliminated.  But I don't think it's very common
147 and it's dangerous to do this fiddling in STG land 
148 because we might elminate a binding that's mentioned in the
149 unfolding for something.
150
151
152 \begin{code}
153 occAnalTop :: OccEnv                    -- What's in scope
154            -> [CoreBinding]
155            -> (IdEnv BinderInfo,        -- Occurrence info
156                IdEnv Id,                -- Indirection elimination info
157                [SimplifiableCoreBinding]
158               )
159
160 occAnalTop env [] = (emptyDetails, nullIdEnv, [])
161
162 -- Special case for eliminating indirections
163 --   Note: it's a shortcoming that this only works for
164 --         non-recursive bindings.  Elminating indirections
165 --         makes perfect sense for recursive bindings too, but
166 --         it's more complicated to implement, so I haven't done so
167
168 occAnalTop env (NonRec exported_id (Var local_id) : binds)
169   | isExported exported_id &&           -- Only if this is exported
170
171     isLocallyDefined local_id &&        -- Only if this one is defined in this
172                                         --      module, so that we *can* change its
173                                         --      binding to be the exported thing!
174
175     not (isExported local_id) &&        -- Only if this one is not itself exported,
176                                         --      since the transformation will nuke it
177
178     not (omitIfaceSigForId local_id) && -- Don't do the transformation if rhs_id is
179                                         --      something like a constructor, whose 
180                                         --      definition is implicitly exported and 
181                                         --      which must not vanish.
182                 -- To illustrate the preceding check consider
183                 --      data T = MkT Int
184                 --      mkT = MkT
185                 --      f x = MkT (x+1)
186                 -- Here, we'll make a local, non-exported, defn for MkT, and without the
187                 -- above condition we'll transform it to:
188                 --      mkT = \x. MkT [x]
189                 --      f = \y. mkT (y+1)
190                 -- This is bad because mkT will get the IdDetails of MkT, and won't
191                 -- be exported.  Also the code generator won't make a definition for
192                 -- the MkT constructor.
193                 -- Slightly gruesome, this.
194
195
196     not (maybeToBool (lookupIdEnv ind_env local_id))
197                                         -- Only if not already substituted for
198     
199   =     -- Aha!  An indirection; let's eliminate it!
200     (scope_usage, ind_env', binds')
201   where
202     (scope_usage, ind_env, binds') = occAnalTop env binds
203     ind_env' = addOneToIdEnv ind_env local_id exported_id
204
205 -- The normal case
206 occAnalTop env (bind : binds)
207   = (final_usage, ind_env, new_binds ++ binds')
208   where
209     new_env                        = env `addNewCands` (bindersOf bind)
210     (scope_usage, ind_env, binds') = occAnalTop new_env binds
211     (final_usage, new_binds)       = occAnalBind env (zap_bind bind) scope_usage
212
213         -- Deal with any indirections
214     zap_bind (NonRec bndr rhs) 
215         | bndr `elemIdEnv` ind_env                      = Rec (zap (bndr,rhs))
216                 -- The Rec isn't strictly necessary, but it's convenient
217     zap_bind (Rec pairs)
218         | or [id `elemIdEnv` ind_env | (id,_) <- pairs] = Rec (concat (map zap pairs))
219
220     zap_bind bind = bind
221
222     zap pair@(bndr,rhs) = case lookupIdEnv ind_env bndr of
223                             Nothing          -> [pair]
224                             Just exported_id -> [(bndr, Var exported_id),
225                                                  (exported_id, rhs)]
226 \end{code}
227
228
229 %************************************************************************
230 %*                                                                      *
231 \subsection[OccurAnal-main]{Counting occurrences: main function}
232 %*                                                                      *
233 %************************************************************************
234
235 Bindings
236 ~~~~~~~~
237
238 \begin{code}
239 type Node details = (details, Int, [Int])       -- The Ints are gotten from the Unique,
240                                                 -- which is gotten from the Id.
241 type Details1     = (Id, UsageDetails, SimplifiableCoreExpr)
242 type Details2     = ((Id, BinderInfo), SimplifiableCoreExpr)
243
244
245 occAnalBind :: OccEnv
246             -> CoreBinding
247             -> UsageDetails             -- Usage details of scope
248             -> (UsageDetails,           -- Of the whole let(rec)
249                 [SimplifiableCoreBinding])
250
251 occAnalBind env (NonRec binder rhs) body_usage
252   | isNeeded env body_usage binder              -- It's mentioned in body
253   = (final_body_usage `combineUsageDetails` rhs_usage,
254      [NonRec tagged_binder rhs'])
255
256   | otherwise                   -- Not mentioned, so drop dead code
257   = (body_usage, [])
258
259   where
260     binder'                           = nukeNoInlinePragma binder
261     (rhs_usage, rhs')                 = occAnalRhs env binder' rhs
262     (final_body_usage, tagged_binder) = tagBinder body_usage binder'
263 \end{code}
264
265 Dropping dead code for recursive bindings is done in a very simple way:
266
267         the entire set of bindings is dropped if none of its binders are
268         mentioned in its body; otherwise none are.
269
270 This seems to miss an obvious improvement.
271 @
272         letrec  f = ...g...
273                 g = ...f...
274         in
275         ...g...
276
277 ===>
278
279         letrec f = ...g...
280                g = ...(...g...)...
281         in
282         ...g...
283 @
284
285 Now @f@ is unused. But dependency analysis will sort this out into a
286 @letrec@ for @g@ and a @let@ for @f@, and then @f@ will get dropped.
287 It isn't easy to do a perfect job in one blow.  Consider
288
289 @
290         letrec f = ...g...
291                g = ...h...
292                h = ...k...
293                k = ...m...
294                m = ...m...
295         in
296         ...m...
297 @
298
299
300 \begin{code}
301 occAnalBind env (Rec pairs) body_usage
302   = foldr (_scc_ "occAnalBind.dofinal" do_final_bind) (body_usage, []) sccs
303   where
304     pp_item (_, bndr, _)     = ppr bndr
305
306     binders = map fst pairs
307     new_env = env `addNewCands` binders
308
309     analysed_pairs :: [Details1]
310     analysed_pairs  = [ (nukeNoInlinePragma bndr, rhs_usage, rhs')
311                       | (bndr, rhs) <- pairs,
312                         let (rhs_usage, rhs') = occAnalRhs new_env bndr rhs
313                       ]
314
315     sccs :: [SCC (Node Details1)]
316     sccs = _scc_ "occAnalBind.scc" stronglyConnCompR edges
317
318
319     ---- stuff for dependency analysis of binds -------------------------------
320     edges :: [Node Details1]
321     edges = _scc_ "occAnalBind.assoc"
322             [ (details, IBOX(u2i (idUnique id)), edges_from rhs_usage)
323             | details@(id, rhs_usage, rhs) <- analysed_pairs
324             ]
325
326         -- (a -> b) means a mentions b
327         -- Given the usage details (a UFM that gives occ info for each free var of
328         -- the RHS) we can get the list of free vars -- or rather their Int keys --
329         -- by just extracting the keys from the finite map.  Grimy, but fast.
330         -- Previously we had this:
331         --      [ bndr | bndr <- bndrs,
332         --               maybeToBool (lookupIdEnv rhs_usage bndr)]
333         -- which has n**2 cost, and this meant that edges_from alone 
334         -- consumed 10% of total runtime!
335     edges_from :: UsageDetails -> [Int]
336     edges_from rhs_usage = _scc_ "occAnalBind.edges_from"
337                            keysUFM rhs_usage
338
339     ---- stuff to "re-constitute" bindings from dependency-analysis info ------
340
341         -- Non-recursive SCC
342     do_final_bind (AcyclicSCC ((bndr, rhs_usage, rhs'), _, _)) (body_usage, binds_so_far)
343       | isNeeded env body_usage bndr
344       = (combined_usage, new_bind : binds_so_far)       
345       | otherwise
346       = (body_usage, binds_so_far)                      -- Dead code
347       where
348         total_usage                   = combineUsageDetails body_usage rhs_usage
349         (combined_usage, tagged_bndr) = tagBinder total_usage bndr
350         new_bind                      = NonRec tagged_bndr rhs'
351
352         -- Recursive SCC
353     do_final_bind (CyclicSCC cycle) (body_usage, binds_so_far)
354       | any (isNeeded env body_usage) bndrs
355       = (combined_usage, final_bind:binds_so_far)
356       | otherwise
357       = (body_usage, binds_so_far)                      -- Dead code
358       where
359         details                          = [details   | (details, _, _) <- cycle]
360         bndrs                            = [bndr      | (bndr, _, _)      <- details]
361         rhs_usages                       = [rhs_usage | (_, rhs_usage, _) <- details]
362         total_usage                      = foldr combineUsageDetails body_usage rhs_usages
363         (combined_usage, tagged_binders) = tagBinders total_usage bndrs
364         final_bind                       = Rec (reOrderRec env new_cycle)
365
366         new_cycle = CyclicSCC (zipWithEqual "occAnalBind" mk_new_bind tagged_binders cycle)
367         mk_new_bind (bndr, occ_info) ((_, _, rhs'), key, keys) = (((bndr, occ_info), rhs'), key, keys)
368 \end{code}
369
370 @reOrderRec@ is applied to the list of (binder,rhs) pairs for a cyclic
371 strongly connected component (there's guaranteed to be a cycle).  It returns the
372 same pairs, but 
373         a) in a better order,
374         b) with some of the Ids having a IMustNotBeINLINEd pragma
375
376 The "no-inline" Ids are sufficient to break all cycles in the SCC.  This means
377 that the simplifier can guarantee not to loop provided it never records an inlining
378 for these no-inline guys.
379
380 Furthermore, the order of the binds is such that if we neglect dependencies
381 on the no-inline Ids then the binds are topologically sorted.  This means
382 that the simplifier will generally do a good job if it works from top bottom,
383 recording inlinings for any Ids which aren't marked as "no-inline" as it goes.
384
385 Here's a case that bit me:
386
387         letrec
388                 a = b
389                 b = \x. BIG
390         in
391         ...a...a...a....
392
393 Re-ordering doesn't change the order of bindings, but there was no loop-breaker.
394
395 My solution was to make a=b bindings record b as Many, rather like INLINE bindings.
396 Perhaps something cleverer would suffice.
397
398 You might think that you can prevent non-termination simply by making
399 sure that we simplify a recursive binding's RHS in an environment that
400 simply clones the recursive Id.  But no.  Consider
401
402                 letrec f = \x -> let z = f x' in ...
403
404                 in
405                 let n = f y
406                 in
407                 case n of { ... }
408
409 We bind n to its *simplified* RHS, we then *re-simplify* it when
410 we inline n.  Then we may well inline f; and then the same thing
411 happens with z!
412
413 I don't think it's possible to prevent non-termination by environment
414 manipulation in this way.  Apart from anything else, successive
415 iterations of the simplifier may unroll recursive loops in cases like
416 that above.  The idea of beaking every recursive loop with an
417 IMustNotBeINLINEd pragma is much much better.
418
419
420 \begin{code}
421 reOrderRec
422         :: OccEnv
423         -> SCC (Node Details2)
424         -> [Details2]
425                         -- Sorted into a plausible order.  Enough of the Ids have
426                         --      dontINLINE pragmas that there are no loops left.
427
428         -- Non-recursive case
429 reOrderRec env (AcyclicSCC (bind, _, _)) = [bind]
430
431         -- Common case of simple self-recursion
432 reOrderRec env (CyclicSCC [bind])
433   = [((addNoInlinePragma bndr, occ_info), rhs)]
434   where
435     (((bndr, occ_info), rhs), _, _) = bind
436
437 reOrderRec env (CyclicSCC binds)
438   =     -- Choose a loop breaker, mark it no-inline,
439         -- do SCC analysis on the rest, and recursively sort them out
440     concat (map (reOrderRec env) (stronglyConnCompR unchosen))
441     ++ 
442     [((addNoInlinePragma bndr, occ_info), rhs)]
443
444   where
445     (chosen_pair, unchosen) = choose_loop_breaker binds
446     ((bndr,occ_info), rhs)  = chosen_pair
447
448         -- Choosing the loop breaker; heursitic
449     choose_loop_breaker (bind@(details, _, _) : rest)
450         |  not (null rest) &&
451            bad_choice details
452         =  (chosen, bind : unchosen)    -- Don't pick it
453         | otherwise                     -- Pick it
454         = (details,rest)
455         where
456           (chosen, unchosen) = choose_loop_breaker rest
457
458     bad_choice ((bndr, occ_info), rhs)
459         =    var_rhs rhs                -- Dont pick var RHS
460           || inlineMe env bndr          -- Dont pick INLINE thing
461           || isOneFunOcc occ_info       -- Dont pick single-occ thing
462           || not_fun_ty (idType bndr)   -- Dont pick data-ty thing
463           || not (isEmptySpecEnv (getIdSpecialisation bndr))
464                 -- Avoid things with a SpecEnv; we'd like
465                 -- to take advantage of the SpecEnv in the subsuequent bindings
466
467         -- isOneFunOcc looks for one textual occurrence, whether inside lambda or whatever.
468         -- We stick to just FunOccs because if we're not going to be able
469         -- to inline the thing on this round it might be better to pick
470         -- this one as the loop breaker.  Real example (the Enum Ordering instance
471         -- from PrelBase):
472         --      rec     f = \ x -> case d of (p,q,r) -> p x
473         --              g = \ x -> case d of (p,q,r) -> q x
474         --              d = (v, f, g)
475         --
476         -- Here, f and g occur just once; but we can't inline them into d.
477         -- On the other hand we *could* simplify those case expressions if
478         -- we didn't stupidly choose d as the loop breaker.
479
480     not_fun_ty ty = not (maybeToBool (splitFunTy_maybe rho_ty))
481                   where
482                     (_, rho_ty) = splitForAllTys ty
483
484         -- A variable RHS
485     var_rhs (Var v)   = True
486     var_rhs other_rhs = False
487 \end{code}
488
489 @occAnalRhs@ deals with the question of bindings where the Id is marked
490 by an INLINE pragma.  For these we record that anything which occurs
491 in its RHS occurs many times.  This pessimistically assumes that ths
492 inlined binder also occurs many times in its scope, but if it doesn't
493 we'll catch it next time round.  At worst this costs an extra simplifier pass.
494 ToDo: try using the occurrence info for the inline'd binder.
495
496 [March 97] We do the same for atomic RHSs.  Reason: see notes with reOrderRec.
497
498 [March 98] A new wrinkle is that if the binder has specialisations inside
499 it then we count the specialised Ids as "extra rhs's".  That way
500 the "parent" keeps the specialised "children" alive.  If the parent
501 dies (because it isn't referenced any more), then the children will
502 die too unless they are already referenced directly.
503
504 \begin{code}
505 occAnalRhs :: OccEnv
506            -> Id -> CoreExpr    -- Binder and rhs
507            -> (UsageDetails, SimplifiableCoreExpr)
508
509 occAnalRhs env id (Var v)
510   | isCandidate env v
511   = (unitIdEnv v (markMany (funOccurrence 0)), Var v)
512
513   | otherwise
514   = (emptyDetails, Var v)
515
516 occAnalRhs env id rhs
517   | inlineMe env id
518   = (mapIdEnv markMany total_usage, rhs')
519
520   | otherwise
521   = (total_usage, rhs')
522
523   where
524     (rhs_usage, rhs') = occAnal env rhs
525     total_usage = foldr add rhs_usage (idSpecVars id)
526     add v u     = addOneOcc u v noBinderInfo    -- Give a non-committal binder info
527                                                 -- (i.e manyOcc) because many copies
528                                                 -- of the specialised thing can appear
529 \end{code}
530
531 Expressions
532 ~~~~~~~~~~~
533 \begin{code}
534 occAnal :: OccEnv
535         -> CoreExpr
536         -> (UsageDetails,       -- Gives info only about the "interesting" Ids
537             SimplifiableCoreExpr)
538
539 occAnal env (Var v)
540   | isCandidate env v
541   = (unitIdEnv v (funOccurrence 0), Var v)
542
543   | otherwise
544   = (emptyDetails, Var v)
545
546 occAnal env (Lit lit)      = (emptyDetails, Lit lit)
547 occAnal env (Prim op args) = (occAnalArgs env args, Prim op args)
548 \end{code}
549
550 We regard variables that occur as constructor arguments as "dangerousToDup":
551
552 \begin{verbatim}
553 module A where
554 f x = let y = expensive x in 
555       let z = (True,y) in 
556       (case z of {(p,q)->q}, case z of {(p,q)->q})
557 \end{verbatim}
558
559 We feel free to duplicate the WHNF (True,y), but that means
560 that y may be duplicated thereby.
561
562 If we aren't careful we duplicate the (expensive x) call!
563 Constructors are rather like lambdas in this way.
564
565 \begin{code}
566 occAnal env (Con con args)
567   = (mapIdEnv markDangerousToDup (occAnalArgs env args), 
568      Con con args)
569
570 occAnal env (Note note@(SCC cc) body)
571   = (mapIdEnv markInsideSCC usage, Note note body')
572   where
573     (usage, body') = occAnal env body
574
575 occAnal env (Note note body)
576   = (usage, Note note body')
577   where
578     (usage, body') = occAnal env body
579
580 occAnal env (App fun arg)
581   = (fun_usage `combineUsageDetails` arg_usage, App fun' arg)
582   where
583     (fun_usage, fun') = occAnal    env fun
584     arg_usage         = occAnalArg env arg
585
586 -- For value lambdas we do a special hack.  Consider
587 --      (\x. \y. ...x...)
588 -- If we did nothing, x is used inside the \y, so would be marked
589 -- as dangerous to dup.  But in the common case where the abstraction
590 -- is applied to two arguments this is over-pessimistic.
591 -- So instead we don't take account of the \y when dealing with x's usage;
592 -- instead, the simplifier is careful when partially applying lambdas
593
594 occAnal env expr@(Lam (ValBinder binder) body)
595   = (mapIdEnv markDangerousToDup final_usage,
596      foldr ( \v b -> Lam (ValBinder v) b) body' tagged_binders)
597   where
598     (binders,body)                = collectValBinders expr
599     (body_usage, body')           = occAnal (env `addNewCands` binders) body
600     (final_usage, tagged_binders) = tagBinders body_usage binders
601
602 -- ANDY: WE MUST THINK ABOUT THIS! (ToDo)
603 occAnal env (Lam (TyBinder tyvar) body)
604   = case occAnal env body of { (body_usage, body') ->
605      (mapIdEnv markDangerousToDup body_usage,
606       Lam (TyBinder tyvar) body') }
607 --  where
608 --    (body_usage, body') = occAnal env body
609
610 occAnal env (Case scrut alts)
611   = case occAnalAlts env alts of { (alts_usage, alts')   -> 
612      case occAnal env scrut   of { (scrut_usage, scrut') ->
613        let
614         det = scrut_usage `combineUsageDetails` alts_usage
615        in
616        if isNullIdEnv det then
617           (det, Case scrut' alts')
618        else
619           (det, Case scrut' alts') }}
620 {-
621        (scrut_usage `combineUsageDetails` alts_usage,
622         Case scrut' alts')
623   where
624     (scrut_usage, scrut') = occAnal env scrut
625     (alts_usage, alts')   = occAnalAlts env alts
626 -}
627
628 occAnal env (Let bind body)
629   = case occAnal new_env body            of { (body_usage, body') ->
630     case occAnalBind env bind body_usage of { (final_usage, new_binds) ->
631        (final_usage, foldr Let body' new_binds) }} -- mkCoLet* wants Core... (sigh)
632   where
633     new_env                  = env `addNewCands` (bindersOf bind)
634 --    (body_usage, body')      = occAnal new_env body
635 --    (final_usage, new_binds) = occAnalBind env bind body_usage
636 \end{code}
637
638 Case alternatives
639 ~~~~~~~~~~~~~~~~~
640 \begin{code}
641 occAnalAlts env (AlgAlts alts deflt)
642   = (foldr combineAltsUsageDetails deflt_usage alts_usage,
643         -- Note: combine*Alts*UsageDetails...
644      AlgAlts alts' deflt')
645   where
646     (alts_usage,  alts')  = unzip (map do_alt alts)
647     (deflt_usage, deflt') = occAnalDeflt env deflt
648
649     do_alt (con, args, rhs)
650       = (final_usage, (con, tagged_args, rhs'))
651       where
652         new_env            = env `addNewCands` args
653         (rhs_usage, rhs')          = occAnal new_env rhs
654         (final_usage, tagged_args) = tagBinders rhs_usage args
655
656 occAnalAlts env (PrimAlts alts deflt)
657   = (foldr combineAltsUsageDetails deflt_usage alts_usage,
658         -- Note: combine*Alts*UsageDetails...
659      PrimAlts alts' deflt')
660   where
661     (alts_usage, alts')   = unzip (map do_alt alts)
662     (deflt_usage, deflt') = occAnalDeflt env deflt
663
664     do_alt (lit, rhs)
665       = (rhs_usage, (lit, rhs'))
666       where
667         (rhs_usage, rhs') = occAnal env rhs
668
669 occAnalDeflt env NoDefault = (emptyDetails, NoDefault)
670
671 occAnalDeflt env (BindDefault binder rhs)
672   = (final_usage, BindDefault tagged_binder rhs')
673   where
674     new_env                      = env `addNewCand` binder
675     (rhs_usage, rhs')            = occAnal new_env rhs
676     (final_usage, tagged_binder) = tagBinder rhs_usage binder
677 \end{code}
678
679
680 Atoms
681 ~~~~~
682 \begin{code}
683 occAnalArgs :: OccEnv -> [CoreArg] -> UsageDetails
684
685 occAnalArgs env atoms
686   = foldr do_one_atom emptyDetails atoms
687   where
688     do_one_atom (VarArg v) usage
689         | isCandidate env v = addOneOcc usage v (argOccurrence 0)
690         | otherwise         = usage
691     do_one_atom other_arg  usage = usage
692
693
694 occAnalArg  :: OccEnv -> CoreArg -> UsageDetails
695
696 occAnalArg env (VarArg v)
697   | isCandidate env v = unitDetails v (argOccurrence 0)
698   | otherwise         = emptyDetails
699 occAnalArg _   _      = emptyDetails
700 \end{code}
701
702
703 %************************************************************************
704 %*                                                                      *
705 \subsection[OccurAnal-types]{Data types}
706 %*                                                                      *
707 %************************************************************************
708
709 \begin{code}
710 data OccEnv =
711   OccEnv
712     Bool        -- IgnoreINLINEPragma flag
713                 -- False <=> OK to use INLINEPragma information
714                 -- True  <=> ignore INLINEPragma information
715
716     (Id -> IdSet -> Bool)       -- Tells whether an Id occurrence is interesting,
717                                 -- given the set of in-scope variables
718
719     IdSet       -- In-scope Ids
720
721
722 addNewCands :: OccEnv -> [Id] -> OccEnv
723 addNewCands (OccEnv ip ifun cands) ids
724   = OccEnv ip ifun (cands `unionIdSets` mkIdSet ids)
725
726 addNewCand :: OccEnv -> Id -> OccEnv
727 addNewCand (OccEnv ip ifun cands) id
728   = OccEnv ip ifun (addOneToIdSet cands id)
729
730 isCandidate :: OccEnv -> Id -> Bool
731 isCandidate (OccEnv _ ifun cands) id = ifun id cands
732
733 inlineMe :: OccEnv -> Id -> Bool
734 inlineMe env id
735   = {-  See comments with simplIdWantsToBeINLINEd in SimplUtils.lhs 
736         not ignore_inline_prag && 
737     -}
738     idWantsToBeINLINEd id
739
740
741 type UsageDetails = IdEnv BinderInfo    -- A finite map from ids to their usage
742
743 combineUsageDetails, combineAltsUsageDetails
744         :: UsageDetails -> UsageDetails -> UsageDetails
745
746 combineUsageDetails usage1 usage2
747   = combineIdEnvs addBinderInfo usage1 usage2
748
749 combineAltsUsageDetails usage1 usage2
750   = combineIdEnvs orBinderInfo usage1 usage2
751
752 addOneOcc :: UsageDetails -> Id -> BinderInfo -> UsageDetails
753 addOneOcc usage id info
754   = combineIdEnvs addBinderInfo usage (unitIdEnv id info)
755         -- ToDo: make this more efficient
756
757 emptyDetails = (nullIdEnv :: UsageDetails)
758
759 unitDetails id info = (unitIdEnv id info :: UsageDetails)
760
761 tagBinders :: UsageDetails          -- Of scope
762            -> [Id]                  -- Binders
763            -> (UsageDetails,        -- Details with binders removed
764               [(Id,BinderInfo)])    -- Tagged binders
765
766 tagBinders usage binders =
767  let
768   usage' = usage `delManyFromIdEnv` binders
769   uss    = [ (binder, usage_of usage binder) | binder <- binders ]
770  in
771  if isNullIdEnv usage' then
772     (usage', uss)
773  else
774     (usage', uss)
775 {-
776   = (usage `delManyFromIdEnv` binders,
777      [ (binder, usage_of usage binder) | binder <- binders ]
778     )
779 -}
780 tagBinder :: UsageDetails           -- Of scope
781           -> Id                     -- Binders
782           -> (UsageDetails,         -- Details with binders removed
783               (Id,BinderInfo))      -- Tagged binders
784
785 tagBinder usage binder =
786  let
787    usage'  = usage `delOneFromIdEnv` binder
788    us      = usage_of usage binder 
789    cont =
790     if isNullIdEnv usage' then  -- Bogus test to force evaluation.
791        (usage', (binder, us))
792     else
793        (usage', (binder, us))
794  in
795  if isDeadOcc us then           -- Ditto 
796         cont
797  else 
798         cont
799
800
801 usage_of usage binder
802   | isExported binder || isSpecPragmaId binder
803   = noBinderInfo        -- Visible-elsewhere things count as many
804   | otherwise
805   = case (lookupIdEnv usage binder) of
806       Nothing   -> deadOccurrence
807       Just info -> info
808
809 isNeeded env usage binder = not (isDeadOcc (usage_of usage binder))
810 \end{code}
811
812