2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 %************************************************************************
6 \section[OccurAnal]{Occurrence analysis pass}
8 %************************************************************************
10 The occurrence analyser re-typechecks a core expression, returning a new
11 core expression with (hopefully) improved usage information.
15 occurAnalyseBinds, occurAnalyseExpr, occurAnalyseGlobalExpr
18 #include "HsVersions.h"
21 import CmdLineOpts ( opt_D_dump_occur_anal, SimplifierSwitch(..) )
23 import CoreUtils ( idSpecVars )
24 import Digraph ( stronglyConnCompR, SCC(..) )
25 import Id ( idWantsToBeINLINEd, addNoInlinePragma, nukeNoInlinePragma,
26 omitIfaceSigForId, isSpecPragmaId, getIdSpecialisation,
28 emptyIdSet, unionIdSets, mkIdSet,
32 IdEnv, nullIdEnv, unitIdEnv, combineIdEnvs,
33 delOneFromIdEnv, delManyFromIdEnv, isNullIdEnv,
34 mapIdEnv, lookupIdEnv, elemIdEnv, addOneToIdEnv
36 import SpecEnv ( isEmptySpecEnv )
37 import Name ( isExported, isLocallyDefined )
38 import Type ( splitFunTy_maybe, splitForAllTys )
39 import Maybes ( maybeToBool )
42 import UniqFM ( keysUFM )
43 import Util ( zipWithEqual )
48 %************************************************************************
50 \subsection[OccurAnal-main]{Counting occurrences: main function}
52 %************************************************************************
54 Here's the externally-callable interface:
58 :: [CoreBinding] -- input
59 -> (SimplifierSwitch -> Bool)
60 -> [SimplifiableCoreBinding] -- output
62 occurAnalyseBinds binds simplifier_sw_chkr
63 | opt_D_dump_occur_anal = pprTrace "OccurAnal:"
64 (pprGenericBindings binds')
68 (_, _, binds') = occAnalTop initial_env binds
70 initial_env = OccEnv (simplifier_sw_chkr IgnoreINLINEPragma)
71 (\id in_scope -> isLocallyDefined id) -- Anything local is interesting
72 emptyIdSet -- Not actually used
77 occurAnalyseExpr :: (Id -> Bool) -- Tells if a variable is interesting
79 -> (IdEnv BinderInfo, -- Occ info for interesting free vars
82 occurAnalyseExpr interesting expr
83 = occAnal initial_env expr
85 initial_env = OccEnv False {- Do not ignore INLINE Pragma -}
86 (\id locals -> interesting id || elementOfIdSet id locals)
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)
97 %************************************************************************
99 \subsection{Top level stuff}
101 %************************************************************************
103 In @occAnalTop@ we do indirection-shorting. That is, if we have this:
109 where exp is exported, and loc is not, then we replace it with this:
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.
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:
126 x_exported1 = x_local
127 x_exported2 = x_local
131 x_exported2 = x_exported1
134 We rely on prior eta reduction to simplify things like
136 x_exported = /\ tyvars -> x_local tyvars
140 Hence,there's a possibility of leaving unchanged something like this:
143 x_exported1 = x_local Int
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.
153 occAnalTop :: OccEnv -- What's in scope
155 -> (IdEnv BinderInfo, -- Occurrence info
156 IdEnv Id, -- Indirection elimination info
157 [SimplifiableCoreBinding]
160 occAnalTop env [] = (emptyDetails, nullIdEnv, [])
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
168 occAnalTop env (NonRec exported_id (Var local_id) : binds)
169 | isExported exported_id && -- Only if this is exported
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!
175 not (isExported local_id) && -- Only if this one is not itself exported,
176 -- since the transformation will nuke it
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
186 -- Here, we'll make a local, non-exported, defn for MkT, and without the
187 -- above condition we'll transform it to:
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.
196 not (maybeToBool (lookupIdEnv ind_env local_id))
197 -- Only if not already substituted for
199 = -- Aha! An indirection; let's eliminate it!
200 (scope_usage, ind_env', binds')
202 (scope_usage, ind_env, binds') = occAnalTop env binds
203 ind_env' = addOneToIdEnv ind_env local_id exported_id
206 occAnalTop env (bind : binds)
207 = (final_usage, ind_env, new_binds ++ binds')
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
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
218 | or [id `elemIdEnv` ind_env | (id,_) <- pairs] = Rec (concat (map zap pairs))
222 zap pair@(bndr,rhs) = case lookupIdEnv ind_env bndr of
224 Just exported_id -> [(bndr, Var exported_id),
229 %************************************************************************
231 \subsection[OccurAnal-main]{Counting occurrences: main function}
233 %************************************************************************
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)
245 occAnalBind :: OccEnv
247 -> UsageDetails -- Usage details of scope
248 -> (UsageDetails, -- Of the whole let(rec)
249 [SimplifiableCoreBinding])
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'])
256 | otherwise -- Not mentioned, so drop dead code
260 binder' = nukeNoInlinePragma binder
261 (rhs_usage, rhs') = occAnalRhs env binder' rhs
262 (final_body_usage, tagged_binder) = tagBinder body_usage binder'
265 Dropping dead code for recursive bindings is done in a very simple way:
267 the entire set of bindings is dropped if none of its binders are
268 mentioned in its body; otherwise none are.
270 This seems to miss an obvious improvement.
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
301 occAnalBind env (Rec pairs) body_usage
302 = foldr (_scc_ "occAnalBind.dofinal" do_final_bind) (body_usage, []) sccs
304 pp_item (_, bndr, _) = ppr bndr
306 binders = map fst pairs
307 new_env = env `addNewCands` binders
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
315 sccs :: [SCC (Node Details1)]
316 sccs = _scc_ "occAnalBind.scc" stronglyConnCompR edges
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
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"
339 ---- stuff to "re-constitute" bindings from dependency-analysis info ------
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)
346 = (body_usage, binds_so_far) -- Dead code
348 total_usage = combineUsageDetails body_usage rhs_usage
349 (combined_usage, tagged_bndr) = tagBinder total_usage bndr
350 new_bind = NonRec tagged_bndr rhs'
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)
357 = (body_usage, binds_so_far) -- Dead code
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)
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)
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
373 a) in a better order,
374 b) with some of the Ids having a IMustNotBeINLINEd pragma
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.
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.
385 Here's a case that bit me:
393 Re-ordering doesn't change the order of bindings, but there was no loop-breaker.
395 My solution was to make a=b bindings record b as Many, rather like INLINE bindings.
396 Perhaps something cleverer would suffice.
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
402 letrec f = \x -> let z = f x' in ...
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
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.
423 -> SCC (Node Details2)
425 -- Sorted into a plausible order. Enough of the Ids have
426 -- dontINLINE pragmas that there are no loops left.
428 -- Non-recursive case
429 reOrderRec env (AcyclicSCC (bind, _, _)) = [bind]
431 -- Common case of simple self-recursion
432 reOrderRec env (CyclicSCC [bind])
433 = [((addNoInlinePragma bndr, occ_info), rhs)]
435 (((bndr, occ_info), rhs), _, _) = bind
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))
442 [((addNoInlinePragma bndr, occ_info), rhs)]
445 (chosen_pair, unchosen) = choose_loop_breaker binds
446 ((bndr,occ_info), rhs) = chosen_pair
448 -- Choosing the loop breaker; heursitic
449 choose_loop_breaker (bind@(details, _, _) : rest)
452 = (chosen, bind : unchosen) -- Don't pick it
453 | otherwise -- Pick it
456 (chosen, unchosen) = choose_loop_breaker rest
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
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
472 -- rec f = \ x -> case d of (p,q,r) -> p x
473 -- g = \ x -> case d of (p,q,r) -> q x
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.
480 not_fun_ty ty = not (maybeToBool (splitFunTy_maybe rho_ty))
482 (_, rho_ty) = splitForAllTys ty
485 var_rhs (Var v) = True
486 var_rhs other_rhs = False
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.
496 [March 97] We do the same for atomic RHSs. Reason: see notes with reOrderRec.
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.
506 -> Id -> CoreExpr -- Binder and rhs
507 -> (UsageDetails, SimplifiableCoreExpr)
509 occAnalRhs env id (Var v)
511 = (unitIdEnv v (markMany (funOccurrence 0)), Var v)
514 = (emptyDetails, Var v)
516 occAnalRhs env id rhs
518 = (mapIdEnv markMany total_usage, rhs')
521 = (total_usage, rhs')
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
536 -> (UsageDetails, -- Gives info only about the "interesting" Ids
537 SimplifiableCoreExpr)
541 = (unitIdEnv v (funOccurrence 0), Var v)
544 = (emptyDetails, Var v)
546 occAnal env (Lit lit) = (emptyDetails, Lit lit)
547 occAnal env (Prim op args) = (occAnalArgs env args, Prim op args)
550 We regard variables that occur as constructor arguments as "dangerousToDup":
554 f x = let y = expensive x in
556 (case z of {(p,q)->q}, case z of {(p,q)->q})
559 We feel free to duplicate the WHNF (True,y), but that means
560 that y may be duplicated thereby.
562 If we aren't careful we duplicate the (expensive x) call!
563 Constructors are rather like lambdas in this way.
566 occAnal env (Con con args)
567 = (mapIdEnv markDangerousToDup (occAnalArgs env args),
570 occAnal env (Note note@(SCC cc) body)
571 = (mapIdEnv markInsideSCC usage, Note note body')
573 (usage, body') = occAnal env body
575 occAnal env (Note note body)
576 = (usage, Note note body')
578 (usage, body') = occAnal env body
580 occAnal env (App fun arg)
581 = (fun_usage `combineUsageDetails` arg_usage, App fun' arg)
583 (fun_usage, fun') = occAnal env fun
584 arg_usage = occAnalArg env arg
586 -- For value lambdas we do a special hack. Consider
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
594 occAnal env expr@(Lam (ValBinder binder) body)
595 = (mapIdEnv markDangerousToDup final_usage,
596 foldr ( \v b -> Lam (ValBinder v) b) body' tagged_binders)
598 (binders,body) = collectValBinders expr
599 (body_usage, body') = occAnal (env `addNewCands` binders) body
600 (final_usage, tagged_binders) = tagBinders body_usage binders
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') }
608 -- (body_usage, body') = occAnal env body
610 occAnal env (Case scrut alts)
611 = case occAnalAlts env alts of { (alts_usage, alts') ->
612 case occAnal env scrut of { (scrut_usage, scrut') ->
614 det = scrut_usage `combineUsageDetails` alts_usage
616 if isNullIdEnv det then
617 (det, Case scrut' alts')
619 (det, Case scrut' alts') }}
621 (scrut_usage `combineUsageDetails` alts_usage,
624 (scrut_usage, scrut') = occAnal env scrut
625 (alts_usage, alts') = occAnalAlts env alts
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)
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
641 occAnalAlts env (AlgAlts alts deflt)
642 = (foldr combineAltsUsageDetails deflt_usage alts_usage,
643 -- Note: combine*Alts*UsageDetails...
644 AlgAlts alts' deflt')
646 (alts_usage, alts') = unzip (map do_alt alts)
647 (deflt_usage, deflt') = occAnalDeflt env deflt
649 do_alt (con, args, rhs)
650 = (final_usage, (con, tagged_args, rhs'))
652 new_env = env `addNewCands` args
653 (rhs_usage, rhs') = occAnal new_env rhs
654 (final_usage, tagged_args) = tagBinders rhs_usage args
656 occAnalAlts env (PrimAlts alts deflt)
657 = (foldr combineAltsUsageDetails deflt_usage alts_usage,
658 -- Note: combine*Alts*UsageDetails...
659 PrimAlts alts' deflt')
661 (alts_usage, alts') = unzip (map do_alt alts)
662 (deflt_usage, deflt') = occAnalDeflt env deflt
665 = (rhs_usage, (lit, rhs'))
667 (rhs_usage, rhs') = occAnal env rhs
669 occAnalDeflt env NoDefault = (emptyDetails, NoDefault)
671 occAnalDeflt env (BindDefault binder rhs)
672 = (final_usage, BindDefault tagged_binder rhs')
674 new_env = env `addNewCand` binder
675 (rhs_usage, rhs') = occAnal new_env rhs
676 (final_usage, tagged_binder) = tagBinder rhs_usage binder
683 occAnalArgs :: OccEnv -> [CoreArg] -> UsageDetails
685 occAnalArgs env atoms
686 = foldr do_one_atom emptyDetails atoms
688 do_one_atom (VarArg v) usage
689 | isCandidate env v = addOneOcc usage v (argOccurrence 0)
691 do_one_atom other_arg usage = usage
694 occAnalArg :: OccEnv -> CoreArg -> UsageDetails
696 occAnalArg env (VarArg v)
697 | isCandidate env v = unitDetails v (argOccurrence 0)
698 | otherwise = emptyDetails
699 occAnalArg _ _ = emptyDetails
703 %************************************************************************
705 \subsection[OccurAnal-types]{Data types}
707 %************************************************************************
712 Bool -- IgnoreINLINEPragma flag
713 -- False <=> OK to use INLINEPragma information
714 -- True <=> ignore INLINEPragma information
716 (Id -> IdSet -> Bool) -- Tells whether an Id occurrence is interesting,
717 -- given the set of in-scope variables
719 IdSet -- In-scope Ids
722 addNewCands :: OccEnv -> [Id] -> OccEnv
723 addNewCands (OccEnv ip ifun cands) ids
724 = OccEnv ip ifun (cands `unionIdSets` mkIdSet ids)
726 addNewCand :: OccEnv -> Id -> OccEnv
727 addNewCand (OccEnv ip ifun cands) id
728 = OccEnv ip ifun (addOneToIdSet cands id)
730 isCandidate :: OccEnv -> Id -> Bool
731 isCandidate (OccEnv _ ifun cands) id = ifun id cands
733 inlineMe :: OccEnv -> Id -> Bool
735 = {- See comments with simplIdWantsToBeINLINEd in SimplUtils.lhs
736 not ignore_inline_prag &&
738 idWantsToBeINLINEd id
741 type UsageDetails = IdEnv BinderInfo -- A finite map from ids to their usage
743 combineUsageDetails, combineAltsUsageDetails
744 :: UsageDetails -> UsageDetails -> UsageDetails
746 combineUsageDetails usage1 usage2
747 = combineIdEnvs addBinderInfo usage1 usage2
749 combineAltsUsageDetails usage1 usage2
750 = combineIdEnvs orBinderInfo usage1 usage2
752 addOneOcc :: UsageDetails -> Id -> BinderInfo -> UsageDetails
753 addOneOcc usage id info
754 = combineIdEnvs addBinderInfo usage (unitIdEnv id info)
755 -- ToDo: make this more efficient
757 emptyDetails = (nullIdEnv :: UsageDetails)
759 unitDetails id info = (unitIdEnv id info :: UsageDetails)
761 tagBinders :: UsageDetails -- Of scope
763 -> (UsageDetails, -- Details with binders removed
764 [(Id,BinderInfo)]) -- Tagged binders
766 tagBinders usage binders =
768 usage' = usage `delManyFromIdEnv` binders
769 uss = [ (binder, usage_of usage binder) | binder <- binders ]
771 if isNullIdEnv usage' then
776 = (usage `delManyFromIdEnv` binders,
777 [ (binder, usage_of usage binder) | binder <- binders ]
780 tagBinder :: UsageDetails -- Of scope
782 -> (UsageDetails, -- Details with binders removed
783 (Id,BinderInfo)) -- Tagged binders
785 tagBinder usage binder =
787 usage' = usage `delOneFromIdEnv` binder
788 us = usage_of usage binder
790 if isNullIdEnv usage' then -- Bogus test to force evaluation.
791 (usage', (binder, us))
793 (usage', (binder, us))
795 if isDeadOcc us then -- Ditto
801 usage_of usage binder
802 | isExported binder || isSpecPragmaId binder
803 = noBinderInfo -- Visible-elsewhere things count as many
805 = case (lookupIdEnv usage binder) of
806 Nothing -> deadOccurrence
809 isNeeded env usage binder = not (isDeadOcc (usage_of usage binder))