2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
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,
16 markBinderInsideLambda
19 #include "HsVersions.h"
22 import CmdLineOpts ( SimplifierSwitch(..) )
24 import CoreUtils ( exprIsTrivial, idSpecVars )
25 import Const ( Con(..), Literal(..) )
26 import Id ( idWantsToBeINLINEd, isSpecPragmaId,
27 getInlinePragma, setInlinePragma,
32 import IdInfo ( InlinePragInfo(..), OccInfo(..) )
33 import SpecEnv ( isEmptySpecEnv )
38 import PrelInfo ( noRepStrIds, noRepIntegerIds )
39 import Name ( isExported, isLocallyDefined )
40 import Type ( splitFunTy_maybe, splitForAllTys )
41 import Maybes ( maybeToBool )
42 import Digraph ( stronglyConnCompR, SCC(..) )
44 import UniqFM ( keysUFM )
45 import Util ( zipWithEqual, mapAndUnzip )
50 %************************************************************************
52 \subsection[OccurAnal-main]{Counting occurrences: main function}
54 %************************************************************************
56 Here's the externally-callable interface:
60 :: (SimplifierSwitch -> Bool)
64 occurAnalyseBinds simplifier_sw_chkr binds
67 (_, _, binds') = occAnalTop initial_env binds
69 initial_env = OccEnv (simplifier_sw_chkr IgnoreINLINEPragma)
70 (\id -> isLocallyDefined id) -- Anything local is interesting
76 occurAnalyseExpr :: (Id -> Bool) -- Tells if a variable is interesting
78 -> (IdEnv BinderInfo, -- Occ info for interesting free vars
81 occurAnalyseExpr interesting expr
82 = occAnal initial_env expr
84 initial_env = OccEnv False {- Do not ignore INLINE Pragma -}
88 occurAnalyseGlobalExpr :: CoreExpr -> CoreExpr
89 occurAnalyseGlobalExpr expr
90 = -- Top level expr, so no interesting free vars, and
91 -- discard occurence info returned
92 snd (occurAnalyseExpr (\_ -> False) expr)
96 %************************************************************************
98 \subsection{Top level stuff}
100 %************************************************************************
102 In @occAnalTop@ we do indirection-shorting. That is, if we have this:
108 where exp is exported, and loc is not, then we replace it with this:
114 Without this we never get rid of the exp = loc thing.
115 This save a gratuitous jump
116 (from \tr{x_exported} to \tr{x_local}), and makes strictness
117 information propagate better.
118 This used to happen in the final phase, but its tidier to do it here.
121 If more than one exported thing is equal to a local thing (i.e., the
122 local thing really is shared), then we do one only:
125 x_exported1 = x_local
126 x_exported2 = x_local
130 x_exported2 = x_exported1
133 We rely on prior eta reduction to simplify things like
135 x_exported = /\ tyvars -> x_local tyvars
139 Hence,there's a possibility of leaving unchanged something like this:
142 x_exported1 = x_local Int
144 By the time we've thrown away the types in STG land this
145 could be eliminated. But I don't think it's very common
146 and it's dangerous to do this fiddling in STG land
147 because we might elminate a binding that's mentioned in the
148 unfolding for something.
152 occAnalTop :: OccEnv -- What's in scope
154 -> (IdEnv BinderInfo, -- Occurrence info
155 IdEnv Id, -- Indirection elimination info
159 occAnalTop env [] = (emptyDetails, emptyVarEnv, [])
161 -- Special case for eliminating indirections
162 -- Note: it's a shortcoming that this only works for
163 -- non-recursive bindings. Elminating indirections
164 -- makes perfect sense for recursive bindings too, but
165 -- it's more complicated to implement, so I haven't done so
167 occAnalTop env (bind : binds)
169 NonRec exported_id (Var local_id) | shortMeOut ind_env exported_id local_id
170 -> -- Aha! An indirection; let's eliminate it!
171 (scope_usage, ind_env', binds')
173 ind_env' = extendVarEnv ind_env local_id exported_id
175 other -> -- Ho ho! The normal case
176 (final_usage, ind_env, new_binds ++ binds')
178 (final_usage, new_binds) = occAnalBind env (zap_bind bind) scope_usage
180 new_env = env `addNewCands` (bindersOf bind)
181 (scope_usage, ind_env, binds') = occAnalTop new_env binds
183 -- Deal with any indirections
184 zap_bind (NonRec bndr rhs)
185 | bndr `elemVarEnv` ind_env = Rec (zap (bndr,rhs))
186 -- The Rec isn't strictly necessary, but it's convenient
188 | or [id `elemVarEnv` ind_env | (id,_) <- pairs] = Rec (concat (map zap pairs))
192 zap pair@(bndr,rhs) = case lookupVarEnv ind_env bndr of
194 Just exported_id -> [(bndr, Var exported_id),
197 shortMeOut ind_env exported_id local_id
198 = isExported exported_id && -- Only if this is exported
200 isLocallyDefined local_id && -- Only if this one is defined in this
201 -- module, so that we *can* change its
202 -- binding to be the exported thing!
204 not (isExported local_id) && -- Only if this one is not itself exported,
205 -- since the transformation will nuke it
207 not (omitIfaceSigForId local_id) && -- Don't do the transformation if rhs_id is
208 -- something like a constructor, whose
209 -- definition is implicitly exported and
210 -- which must not vanish.
211 -- To illustrate the preceding check consider
215 -- Here, we'll make a local, non-exported, defn for MkT, and without the
216 -- above condition we'll transform it to:
219 -- This is bad because mkT will get the IdDetails of MkT, and won't
220 -- be exported. Also the code generator won't make a definition for
221 -- the MkT constructor.
222 -- Slightly gruesome, this.
225 not (local_id `elemVarEnv` ind_env) -- Only if not already substituted for
229 %************************************************************************
231 \subsection[OccurAnal-main]{Counting occurrences: main function}
233 %************************************************************************
239 type IdWithOccInfo = Id -- An Id with fresh PragmaInfo attached
241 type Node details = (details, Int, [Int]) -- The Ints are gotten from the Unique,
242 -- which is gotten from the Id.
243 type Details1 = (Id, UsageDetails, CoreExpr)
244 type Details2 = (IdWithOccInfo, CoreExpr)
247 occAnalBind :: OccEnv
249 -> UsageDetails -- Usage details of scope
250 -> (UsageDetails, -- Of the whole let(rec)
253 occAnalBind env (NonRec binder rhs) body_usage
254 | not (binder `usedIn` body_usage) -- It's not mentioned
257 | otherwise -- It's mentioned in the body
258 = (final_body_usage `combineUsageDetails` rhs_usage,
259 [NonRec tagged_binder rhs'])
262 (final_body_usage, tagged_binder) = tagBinder body_usage binder
263 (rhs_usage, rhs') = occAnalRhs env binder rhs
266 Dropping dead code for recursive bindings is done in a very simple way:
268 the entire set of bindings is dropped if none of its binders are
269 mentioned in its body; otherwise none are.
271 This seems to miss an obvious improvement.
286 Now @f@ is unused. But dependency analysis will sort this out into a
287 @letrec@ for @g@ and a @let@ for @f@, and then @f@ will get dropped.
288 It isn't easy to do a perfect job in one blow. Consider
302 occAnalBind env (Rec pairs) body_usage
303 = foldr (_scc_ "occAnalBind.dofinal" do_final_bind) (body_usage, []) sccs
305 pp_item (_, bndr, _) = ppr bndr
307 binders = map fst pairs
308 new_env = env `addNewCands` binders
310 analysed_pairs :: [Details1]
311 analysed_pairs = [ (bndr, rhs_usage, rhs')
312 | (bndr, rhs) <- pairs,
313 let (rhs_usage, rhs') = occAnalRhs new_env bndr rhs
316 sccs :: [SCC (Node Details1)]
317 sccs = _scc_ "occAnalBind.scc" stronglyConnCompR edges
320 ---- stuff for dependency analysis of binds -------------------------------
321 edges :: [Node Details1]
322 edges = _scc_ "occAnalBind.assoc"
323 [ (details, IBOX(u2i (idUnique id)), edges_from rhs_usage)
324 | details@(id, rhs_usage, rhs) <- analysed_pairs
327 -- (a -> b) means a mentions b
328 -- Given the usage details (a UFM that gives occ info for each free var of
329 -- the RHS) we can get the list of free vars -- or rather their Int keys --
330 -- by just extracting the keys from the finite map. Grimy, but fast.
331 -- Previously we had this:
332 -- [ bndr | bndr <- bndrs,
333 -- maybeToBool (lookupVarEnv rhs_usage bndr)]
334 -- which has n**2 cost, and this meant that edges_from alone
335 -- consumed 10% of total runtime!
336 edges_from :: UsageDetails -> [Int]
337 edges_from rhs_usage = _scc_ "occAnalBind.edges_from"
340 ---- stuff to "re-constitute" bindings from dependency-analysis info ------
343 do_final_bind (AcyclicSCC ((bndr, rhs_usage, rhs'), _, _)) (body_usage, binds_so_far)
344 | not (bndr `usedIn` body_usage)
345 = (body_usage, binds_so_far) -- Dead code
347 = (combined_usage, new_bind : binds_so_far)
349 total_usage = combineUsageDetails body_usage rhs_usage
350 (combined_usage, tagged_bndr) = tagBinder total_usage bndr
351 new_bind = NonRec tagged_bndr rhs'
354 do_final_bind (CyclicSCC cycle) (body_usage, binds_so_far)
355 | not (any (`usedIn` body_usage) bndrs) -- NB: look at body_usage, not total_usage
356 = (body_usage, binds_so_far) -- Dead code
358 = (combined_usage, final_bind:binds_so_far)
360 details = [details | (details, _, _) <- cycle]
361 bndrs = [bndr | (bndr, _, _) <- details]
362 rhs_usages = [rhs_usage | (_, rhs_usage, _) <- details]
363 total_usage = foldr combineUsageDetails body_usage rhs_usages
364 (combined_usage, tagged_bndrs) = tagBinders total_usage bndrs
365 final_bind = Rec (reOrderRec env new_cycle)
367 new_cycle = CyclicSCC (zipWithEqual "occAnalBind" mk_new_bind tagged_bndrs cycle)
368 mk_new_bind tagged_bndr ((_, _, rhs'), key, keys) = ((tagged_bndr, rhs'), key, keys)
371 @reOrderRec@ is applied to the list of (binder,rhs) pairs for a cyclic
372 strongly connected component (there's guaranteed to be a cycle). It returns the
374 a) in a better order,
375 b) with some of the Ids having a IMustNotBeINLINEd pragma
377 The "no-inline" Ids are sufficient to break all cycles in the SCC. This means
378 that the simplifier can guarantee not to loop provided it never records an inlining
379 for these no-inline guys.
381 Furthermore, the order of the binds is such that if we neglect dependencies
382 on the no-inline Ids then the binds are topologically sorted. This means
383 that the simplifier will generally do a good job if it works from top bottom,
384 recording inlinings for any Ids which aren't marked as "no-inline" as it goes.
387 [June 98: I don't understand the following paragraphs, and I've
388 changed the a=b case again so that it isn't a special case any more.]
390 Here's a case that bit me:
398 Re-ordering doesn't change the order of bindings, but there was no loop-breaker.
400 My solution was to make a=b bindings record b as Many, rather like INLINE bindings.
401 Perhaps something cleverer would suffice.
404 You might think that you can prevent non-termination simply by making
405 sure that we simplify a recursive binding's RHS in an environment that
406 simply clones the recursive Id. But no. Consider
408 letrec f = \x -> let z = f x' in ...
415 We bind n to its *simplified* RHS, we then *re-simplify* it when
416 we inline n. Then we may well inline f; and then the same thing
419 I don't think it's possible to prevent non-termination by environment
420 manipulation in this way. Apart from anything else, successive
421 iterations of the simplifier may unroll recursive loops in cases like
422 that above. The idea of beaking every recursive loop with an
423 IMustNotBeINLINEd pragma is much much better.
429 -> SCC (Node Details2)
431 -- Sorted into a plausible order. Enough of the Ids have
432 -- dontINLINE pragmas that there are no loops left.
434 -- Non-recursive case
435 reOrderRec env (AcyclicSCC (bind, _, _)) = [bind]
437 -- Common case of simple self-recursion
438 reOrderRec env (CyclicSCC [bind])
439 = [(setInlinePragma tagged_bndr IAmALoopBreaker, rhs)]
441 ((tagged_bndr, rhs), _, _) = bind
443 reOrderRec env (CyclicSCC (bind : binds))
444 = -- Choose a loop breaker, mark it no-inline,
445 -- do SCC analysis on the rest, and recursively sort them out
446 concat (map (reOrderRec env) (stronglyConnCompR unchosen))
448 [(setInlinePragma tagged_bndr IAmALoopBreaker, rhs)]
451 (chosen_pair, unchosen) = choose_loop_breaker bind (score bind) [] binds
452 (tagged_bndr, rhs) = chosen_pair
454 -- This loop looks for the bind with the lowest score
455 -- to pick as the loop breaker. The rest accumulate in
456 choose_loop_breaker (details,_,_) loop_sc acc []
457 = (details, acc) -- Done
459 choose_loop_breaker loop_bind loop_sc acc (bind : binds)
460 | sc < loop_sc -- Lower score so pick this new one
461 = choose_loop_breaker bind sc (loop_bind : acc) binds
463 | otherwise -- No lower so don't pick it
464 = choose_loop_breaker loop_bind loop_sc (bind : acc) binds
468 score :: Node Details2 -> Int -- Higher score => less likely to be picked as loop breaker
469 score ((bndr, rhs), _, _)
470 | exprIsTrivial rhs &&
471 not (isExported bndr) = 3 -- Practically certain to be inlined
472 | inlineCandidate bndr = 3 -- Likely to be inlined
473 | not_fun_ty (idType bndr) = 2 -- Data types help with cases
474 | not (isEmptySpecEnv (getIdSpecialisation bndr)) = 1
475 -- Avoid things with a SpecEnv; we'd like
476 -- to take advantage of the SpecEnv in the subsequent bindings
479 inlineCandidate :: Id -> Bool
481 = case getInlinePragma id of
482 IWantToBeINLINEd -> True
483 IMustBeINLINEd -> True
484 ICanSafelyBeINLINEd _ _ -> True
487 -- Real example (the Enum Ordering instance from PrelBase):
488 -- rec f = \ x -> case d of (p,q,r) -> p x
489 -- g = \ x -> case d of (p,q,r) -> q x
492 -- Here, f and g occur just once; but we can't inline them into d.
493 -- On the other hand we *could* simplify those case expressions if
494 -- we didn't stupidly choose d as the loop breaker.
495 -- But we won't because constructor args are marked "Many".
497 not_fun_ty ty = not (maybeToBool (splitFunTy_maybe rho_ty))
499 (_, rho_ty) = splitForAllTys ty
502 @occAnalRhs@ deals with the question of bindings where the Id is marked
503 by an INLINE pragma. For these we record that anything which occurs
504 in its RHS occurs many times. This pessimistically assumes that ths
505 inlined binder also occurs many times in its scope, but if it doesn't
506 we'll catch it next time round. At worst this costs an extra simplifier pass.
507 ToDo: try using the occurrence info for the inline'd binder.
509 [March 97] We do the same for atomic RHSs. Reason: see notes with reOrderRec.
510 [June 98, SLPJ] I've undone this change; I don't understand it. See notes with reOrderRec.
512 [March 98] A new wrinkle is that if the binder has specialisations inside
513 it then we count the specialised Ids as "extra rhs's". That way
514 the "parent" keeps the specialised "children" alive. If the parent
515 dies (because it isn't referenced any more), then the children will
516 die too unless they are already referenced directly.
520 -> Id -> CoreExpr -- Binder and rhs
521 -> (UsageDetails, CoreExpr)
523 {- DELETED SLPJ June 98: seems quite bogus to me
524 occAnalRhs env id (Var v)
526 = (unitVarEnv v (markMany (funOccurrence 0)), Var v)
529 = (emptyDetails, Var v)
532 occAnalRhs env id rhs
533 | idWantsToBeINLINEd id
534 = (mapVarEnv markMany total_usage, rhs')
537 = (total_usage, rhs')
540 (rhs_usage, rhs') = occAnal env rhs
541 lazy_rhs_usage = mapVarEnv markLazy rhs_usage
542 total_usage = foldVarSet add lazy_rhs_usage spec_ids
543 add v u = addOneOcc u v noBinderInfo -- Give a non-committal binder info
544 -- (i.e manyOcc) because many copies
545 -- of the specialised thing can appear
546 spec_ids = idSpecVars id
556 -> (UsageDetails, -- Gives info only about the "interesting" Ids
559 occAnal env (Type t) = (emptyDetails, Type t)
562 | isCandidate env v = (unitVarEnv v funOccZero, Var v)
563 | otherwise = (emptyDetails, Var v)
566 We regard variables that occur as constructor arguments as "dangerousToDup":
570 f x = let y = expensive x in
572 (case z of {(p,q)->q}, case z of {(p,q)->q})
575 We feel free to duplicate the WHNF (True,y), but that means
576 that y may be duplicated thereby.
578 If we aren't careful we duplicate the (expensive x) call!
579 Constructors are rather like lambdas in this way.
582 -- For NoRep literals we have to report an occurrence of
583 -- the things which tidyCore will later add, so that when
584 -- we are compiling the very module in which those thin-air Ids
585 -- are defined we have them in scope!
586 occAnal env expr@(Con (Literal lit) args)
587 = ASSERT( null args )
588 (mk_lit_uds lit, expr)
590 mk_lit_uds (NoRepStr _ _) = try noRepStrIds
591 mk_lit_uds (NoRepInteger _ _) = try noRepIntegerIds
592 mk_lit_uds lit = emptyDetails
594 try vs = foldr add emptyDetails vs
595 add v uds | isCandidate env v = extendVarEnv uds v funOccZero
598 occAnal env (Con con args)
599 = case mapAndUnzip (occAnal env) args of { (arg_uds_s, args') ->
601 arg_uds = foldr combineUsageDetails emptyDetails arg_uds_s
603 -- We mark the free vars of the argument of a constructor as "many"
604 -- This means that nothing gets inlined into a constructor argument
605 -- position, which is what we want. Typically those constructor
606 -- arguments are just variables, or trivial expressions.
607 final_arg_uds = case con of
608 DataCon _ -> mapVarEnv markMany arg_uds
611 (final_arg_uds, Con con args')
616 occAnal env (Note note@(SCC cc) body)
617 = case occAnal env body of { (usage, body') ->
618 (mapVarEnv markInsideSCC usage, Note note body')
621 occAnal env (Note note body)
622 = case occAnal env body of { (usage, body') ->
623 (usage, Note note body')
628 occAnal env (App fun arg)
629 = case occAnal env fun of { (fun_usage, fun') ->
630 case occAnal env arg of { (arg_usage, arg') ->
631 (fun_usage `combineUsageDetails` mapVarEnv markLazy arg_usage, App fun' arg')
634 -- Ignore type variables altogether
635 -- (a) occurrences inside type lambdas only not marked as InsideLam
636 -- (b) type variables not in environment
638 occAnal env expr@(Lam x body) | isTyVar x
639 = case occAnal env body of { (body_usage, body') ->
640 (body_usage, Lam x body')
643 -- For value lambdas we do a special hack. Consider
645 -- If we did nothing, x is used inside the \y, so would be marked
646 -- as dangerous to dup. But in the common case where the abstraction
647 -- is applied to two arguments this is over-pessimistic.
648 -- So instead, we just mark each binder with its occurrence
649 -- info in the *body* of the multiple lambda.
650 -- Then, the simplifier is careful when partially applying lambdas.
652 occAnal env expr@(Lam _ _)
653 = case occAnal (env `addNewCands` binders) body of { (body_usage, body') ->
655 (final_usage, tagged_binders) = tagBinders body_usage binders
657 (mapVarEnv markInsideLam final_usage,
658 mkLams tagged_binders body') }
660 (binders, body) = collectBinders expr
663 occAnal env (Case scrut bndr alts)
664 = case mapAndUnzip (occAnalAlt alt_env) alts of { (alts_usage_s, alts') ->
665 case occAnal env scrut of { (scrut_usage, scrut') ->
667 alts_usage = foldr1 combineAltsUsageDetails alts_usage_s
668 (alts_usage1, tagged_bndr) = tagBinder alts_usage bndr
669 total_usage = scrut_usage `combineUsageDetails` alts_usage1
671 total_usage `seq` (total_usage, Case scrut' tagged_bndr alts') }}
673 alt_env = env `addNewCand` bndr
675 occAnal env (Let bind body)
676 = case occAnal new_env body of { (body_usage, body') ->
677 case occAnalBind env bind body_usage of { (final_usage, new_binds) ->
678 (final_usage, mkLets new_binds body') }}
680 new_env = env `addNewCands` (bindersOf bind)
686 occAnalAlt env (con, bndrs, rhs)
687 = case occAnal (env `addNewCands` bndrs) rhs of { (rhs_usage, rhs') ->
689 (final_usage, tagged_bndrs) = tagBinders rhs_usage bndrs
691 (final_usage, (con, tagged_bndrs, rhs')) }
695 %************************************************************************
697 \subsection[OccurAnal-types]{Data types}
699 %************************************************************************
704 Bool -- IgnoreINLINEPragma flag
705 -- False <=> OK to use INLINEPragma information
706 -- True <=> ignore INLINEPragma information
708 (Id -> Bool) -- Tells whether an Id occurrence is interesting,
709 -- given the set of in-scope variables
711 IdSet -- In-scope Ids
714 addNewCands :: OccEnv -> [Id] -> OccEnv
715 addNewCands (OccEnv ip ifun cands) ids
716 = OccEnv ip ifun (cands `unionVarSet` mkVarSet ids)
718 addNewCand :: OccEnv -> Id -> OccEnv
719 addNewCand (OccEnv ip ifun cands) id
720 = OccEnv ip ifun (extendVarSet cands id)
722 isCandidate :: OccEnv -> Id -> Bool
723 isCandidate (OccEnv _ ifun cands) id = id `elemVarSet` cands || ifun id
726 type UsageDetails = IdEnv BinderInfo -- A finite map from ids to their usage
728 combineUsageDetails, combineAltsUsageDetails
729 :: UsageDetails -> UsageDetails -> UsageDetails
731 combineUsageDetails usage1 usage2
732 = plusVarEnv_C addBinderInfo usage1 usage2
734 combineAltsUsageDetails usage1 usage2
735 = plusVarEnv_C orBinderInfo usage1 usage2
737 addOneOcc :: UsageDetails -> Id -> BinderInfo -> UsageDetails
738 addOneOcc usage id info
739 = plusVarEnv_C addBinderInfo usage (unitVarEnv id info)
740 -- ToDo: make this more efficient
742 emptyDetails = (emptyVarEnv :: UsageDetails)
744 unitDetails id info = (unitVarEnv id info :: UsageDetails)
746 usedIn :: Id -> UsageDetails -> Bool
747 v `usedIn` details = isExported v
748 || v `elemVarEnv` details
751 tagBinders :: UsageDetails -- Of scope
753 -> (UsageDetails, -- Details with binders removed
754 [IdWithOccInfo]) -- Tagged binders
756 tagBinders usage binders
758 usage' = usage `delVarEnvList` binders
759 uss = map (setBinderPrag usage) binders
761 usage' `seq` (usage', uss)
763 tagBinder :: UsageDetails -- Of scope
765 -> (UsageDetails, -- Details with binders removed
766 IdWithOccInfo) -- Tagged binders
768 tagBinder usage binder
770 usage' = usage `delVarEnv` binder
771 binder' = setBinderPrag usage binder
773 usage' `seq` (usage', binder')
776 setBinderPrag :: UsageDetails -> CoreBndr -> CoreBndr
777 setBinderPrag usage bndr
783 NoInlinePragInfo -> new_bndr
784 IAmDead -> new_bndr -- The next three are annotations
785 ICanSafelyBeINLINEd _ _ -> new_bndr -- from the previous iteration of
786 IAmALoopBreaker -> new_bndr -- the occurrence analyser
788 IAmASpecPragmaId -> bndr -- Don't ever overwrite or drop these as dead
790 other | its_now_dead -> new_bndr -- Overwrite the others iff it's now dead
794 old_prag = getInlinePragma bndr
795 new_bndr = setInlinePragma bndr new_prag
797 its_now_dead = case new_prag of
801 new_prag = occInfoToInlinePrag occ_info
804 | isExported bndr = noBinderInfo
805 -- Don't use local usage info for visible-elsewhere things
806 -- But NB that we do set NoInlinePragma for exported things
807 -- thereby nuking any IAmALoopBreaker from a previous pass.
809 | otherwise = case lookupVarEnv usage bndr of
810 Nothing -> deadOccurrence
813 markBinderInsideLambda :: CoreBndr -> CoreBndr
814 markBinderInsideLambda bndr
819 = case getInlinePragma bndr of
820 ICanSafelyBeINLINEd not_in_lam nalts
821 -> bndr `setInlinePragma` ICanSafelyBeINLINEd InsideLam nalts
824 funOccZero = funOccurrence 0