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 Digraph ( stronglyConnCompR, SCC(..) )
24 import Id ( idWantsToBeINLINEd, addNoInlinePragma, nukeNoInlinePragma,
27 emptyIdSet, unionIdSets, mkIdSet,
31 IdEnv, nullIdEnv, unitIdEnv, combineIdEnvs,
32 delOneFromIdEnv, delManyFromIdEnv, isNullIdEnv,
33 mapIdEnv, lookupIdEnv, elemIdEnv, addOneToIdEnv
35 import Specialise ( idSpecVars )
36 import Name ( isExported, isLocallyDefined )
37 import Type ( splitFunTy_maybe, splitForAllTys )
38 import Maybes ( maybeToBool )
41 import UniqFM ( keysUFM )
42 import Util ( zipWithEqual )
47 %************************************************************************
49 \subsection[OccurAnal-main]{Counting occurrences: main function}
51 %************************************************************************
53 Here's the externally-callable interface:
57 :: [CoreBinding] -- input
58 -> (SimplifierSwitch -> Bool)
59 -> [SimplifiableCoreBinding] -- output
61 occurAnalyseBinds binds simplifier_sw_chkr
62 | opt_D_dump_occur_anal = pprTrace "OccurAnal:"
63 (pprGenericBindings binds')
67 (_, _, binds') = occAnalTop initial_env binds
69 initial_env = OccEnv (simplifier_sw_chkr IgnoreINLINEPragma)
70 (\id in_scope -> isLocallyDefined id) -- Anything local is interesting
71 emptyIdSet -- Not actually used
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 -}
85 (\id locals -> interesting id || elementOfIdSet id locals)
88 occurAnalyseGlobalExpr :: CoreExpr -> SimplifiableCoreExpr
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
156 [SimplifiableCoreBinding]
159 occAnalTop env [] = (emptyDetails, nullIdEnv, [])
161 -- Special case for eliminating indirections
162 occAnalTop env (NonRec exported_id (Var local_id) : binds)
163 | isExported exported_id && -- Only if this is exported
165 isLocallyDefined local_id && -- Only if this one is defined in this
166 -- module, so that we *can* change its
167 -- binding to be the exported thing!
169 not (isExported local_id) && -- Only if this one is not itself exported,
170 -- since the transformation will nuke it
172 not (omitIfaceSigForId local_id) && -- Don't do the transformation if rhs_id is
173 -- something like a constructor, whose
174 -- definition is implicitly exported and
175 -- which must not vanish.
176 -- To illustrate the preceding check consider
180 -- Here, we'll make a local, non-exported, defn for MkT, and without the
181 -- above condition we'll transform it to:
184 -- This is bad because mkT will get the IdDetails of MkT, and won't
185 -- be exported. Also the code generator won't make a definition for
186 -- the MkT constructor.
187 -- Slightly gruesome, this.
190 not (maybeToBool (lookupIdEnv ind_env local_id))
191 -- Only if not already substituted for
193 = -- Aha! An indirection; let's eliminate it!
194 (scope_usage, ind_env', binds')
196 (scope_usage, ind_env, binds') = occAnalTop env binds
197 ind_env' = addOneToIdEnv ind_env local_id exported_id
200 occAnalTop env (bind : binds)
201 = (final_usage, ind_env, new_binds ++ binds')
203 new_env = env `addNewCands` (bindersOf bind)
204 (scope_usage, ind_env, binds') = occAnalTop new_env binds
205 (final_usage, new_binds) = occAnalBind env (zap_bind bind) scope_usage
207 -- Deal with any indirections
208 zap_bind (NonRec bndr rhs)
209 | bndr `elemIdEnv` ind_env = Rec (zap (bndr,rhs))
210 -- The Rec isn't strictly necessary, but it's convenient
212 | or [id `elemIdEnv` ind_env | (id,_) <- pairs] = Rec (concat (map zap pairs))
216 zap pair@(bndr,rhs) = case lookupIdEnv ind_env bndr of
218 Just exported_id -> [(bndr, Var exported_id),
223 %************************************************************************
225 \subsection[OccurAnal-main]{Counting occurrences: main function}
227 %************************************************************************
233 type Node details = (details, Int, [Int]) -- The Ints are gotten from the Unique,
234 -- which is gotten from the Id.
235 type Details1 = (Id, UsageDetails, SimplifiableCoreExpr)
236 type Details2 = ((Id, BinderInfo), SimplifiableCoreExpr)
239 occAnalBind :: OccEnv
241 -> UsageDetails -- Usage details of scope
242 -> (UsageDetails, -- Of the whole let(rec)
243 [SimplifiableCoreBinding])
245 occAnalBind env (NonRec binder rhs) body_usage
246 | isNeeded env body_usage binder -- It's mentioned in body
247 = (final_body_usage `combineUsageDetails` rhs_usage,
248 [NonRec tagged_binder rhs'])
250 | otherwise -- Not mentioned, so drop dead code
254 binder' = nukeNoInlinePragma binder
255 (rhs_usage, rhs') = occAnalRhs env binder' rhs
256 (final_body_usage, tagged_binder) = tagBinder body_usage binder'
259 Dropping dead code for recursive bindings is done in a very simple way:
261 the entire set of bindings is dropped if none of its binders are
262 mentioned in its body; otherwise none are.
264 This seems to miss an obvious improvement.
279 Now @f@ is unused. But dependency analysis will sort this out into a
280 @letrec@ for @g@ and a @let@ for @f@, and then @f@ will get dropped.
281 It isn't easy to do a perfect job in one blow. Consider
295 occAnalBind env (Rec pairs) body_usage
296 = foldr (_scc_ "occAnalBind.dofinal" do_final_bind) (body_usage, []) sccs
298 pp_item (_, bndr, _) = ppr bndr
300 binders = map fst pairs
301 new_env = env `addNewCands` binders
303 analysed_pairs :: [Details1]
304 analysed_pairs = [ (nukeNoInlinePragma bndr, rhs_usage, rhs')
305 | (bndr, rhs) <- pairs,
306 let (rhs_usage, rhs') = occAnalRhs new_env bndr rhs
309 sccs :: [SCC (Node Details1)]
310 sccs = _scc_ "occAnalBind.scc" stronglyConnCompR edges
313 ---- stuff for dependency analysis of binds -------------------------------
314 edges :: [Node Details1]
315 edges = _scc_ "occAnalBind.assoc"
316 [ (details, IBOX(u2i (idUnique id)), edges_from rhs_usage)
317 | details@(id, rhs_usage, rhs) <- analysed_pairs
320 -- (a -> b) means a mentions b
321 -- Given the usage details (a UFM that gives occ info for each free var of
322 -- the RHS) we can get the list of free vars -- or rather their Int keys --
323 -- by just extracting the keys from the finite map. Grimy, but fast.
324 -- Previously we had this:
325 -- [ bndr | bndr <- bndrs,
326 -- maybeToBool (lookupIdEnv rhs_usage bndr)]
327 -- which has n**2 cost, and this meant that edges_from alone
328 -- consumed 10% of total runtime!
329 edges_from :: UsageDetails -> [Int]
330 edges_from rhs_usage = _scc_ "occAnalBind.edges_from"
333 ---- stuff to "re-constitute" bindings from dependency-analysis info ------
336 do_final_bind (AcyclicSCC ((bndr, rhs_usage, rhs'), _, _)) (body_usage, binds_so_far)
337 | isNeeded env body_usage bndr
338 = (combined_usage, new_bind : binds_so_far)
340 = (body_usage, binds_so_far) -- Dead code
342 total_usage = combineUsageDetails body_usage rhs_usage
343 (combined_usage, tagged_bndr) = tagBinder total_usage bndr
344 new_bind = NonRec tagged_bndr rhs'
347 do_final_bind (CyclicSCC cycle) (body_usage, binds_so_far)
348 | any (isNeeded env body_usage) bndrs
349 = (combined_usage, final_bind:binds_so_far)
351 = (body_usage, binds_so_far) -- Dead code
353 details = [details | (details, _, _) <- cycle]
354 bndrs = [bndr | (bndr, _, _) <- details]
355 rhs_usages = [rhs_usage | (_, rhs_usage, _) <- details]
356 total_usage = foldr combineUsageDetails body_usage rhs_usages
357 (combined_usage, tagged_binders) = tagBinders total_usage bndrs
358 final_bind = Rec (reOrderRec env new_cycle)
360 new_cycle = CyclicSCC (zipWithEqual "occAnalBind" mk_new_bind tagged_binders cycle)
361 mk_new_bind (bndr, occ_info) ((_, _, rhs'), key, keys) = (((bndr, occ_info), rhs'), key, keys)
364 @reOrderRec@ is applied to the list of (binder,rhs) pairs for a cyclic
365 strongly connected component (there's guaranteed to be a cycle). It returns the
367 a) in a better order,
368 b) with some of the Ids having a IMustNotBeINLINEd pragma
370 The "no-inline" Ids are sufficient to break all cycles in the SCC. This means
371 that the simplifier can guarantee not to loop provided it never records an inlining
372 for these no-inline guys.
374 Furthermore, the order of the binds is such that if we neglect dependencies
375 on the no-inline Ids then the binds are topologically sorted. This means
376 that the simplifier will generally do a good job if it works from top bottom,
377 recording inlinings for any Ids which aren't marked as "no-inline" as it goes.
379 Here's a case that bit me:
387 Re-ordering doesn't change the order of bindings, but there was no loop-breaker.
389 My solution was to make a=b bindings record b as Many, rather like INLINE bindings.
390 Perhaps something cleverer would suffice.
392 You might think that you can prevent non-termination simply by making
393 sure that we simplify a recursive binding's RHS in an environment that
394 simply clones the recursive Id. But no. Consider
396 letrec f = \x -> let z = f x' in ...
403 We bind n to its *simplified* RHS, we then *re-simplify* it when
404 we inline n. Then we may well inline f; and then the same thing
407 I don't think it's possible to prevent non-termination by environment
408 manipulation in this way. Apart from anything else, successive
409 iterations of the simplifier may unroll recursive loops in cases like
410 that above. The idea of beaking every recursive loop with an
411 IMustNotBeINLINEd pragma is much much better.
417 -> SCC (Node Details2)
419 -- Sorted into a plausible order. Enough of the Ids have
420 -- dontINLINE pragmas that there are no loops left.
422 -- Non-recursive case
423 reOrderRec env (AcyclicSCC (bind, _, _)) = [bind]
425 -- Common case of simple self-recursion
426 reOrderRec env (CyclicSCC [bind])
427 = [((addNoInlinePragma bndr, occ_info), rhs)]
429 (((bndr, occ_info), rhs), _, _) = bind
431 reOrderRec env (CyclicSCC binds)
432 = -- Choose a loop breaker, mark it no-inline,
433 -- do SCC analysis on the rest, and recursively sort them out
434 concat (map (reOrderRec env) (stronglyConnCompR unchosen))
436 [((addNoInlinePragma bndr, occ_info), rhs)]
439 (chosen_pair, unchosen) = choose_loop_breaker binds
440 ((bndr,occ_info), rhs) = chosen_pair
442 -- Choosing the loop breaker; heursitic
443 choose_loop_breaker (bind@(details, _, _) : rest)
446 = (chosen, bind : unchosen) -- Don't pick it
447 | otherwise -- Pick it
450 (chosen, unchosen) = choose_loop_breaker rest
452 bad_choice ((bndr, occ_info), rhs)
453 = var_rhs rhs -- Dont pick var RHS
454 || inlineMe env bndr -- Dont pick INLINE thing
455 || isOneFunOcc occ_info -- Dont pick single-occ thing
456 || not_fun_ty (idType bndr) -- Dont pick data-ty thing
458 -- isOneFunOcc looks for one textual occurrence, whether inside lambda or whatever.
459 -- We stick to just FunOccs because if we're not going to be able
460 -- to inline the thing on this round it might be better to pick
461 -- this one as the loop breaker. Real example (the Enum Ordering instance
463 -- rec f = \ x -> case d of (p,q,r) -> p x
464 -- g = \ x -> case d of (p,q,r) -> q x
467 -- Here, f and g occur just once; but we can't inline them into d.
468 -- On the other hand we *could* simplify those case expressions if
469 -- we didn't stupidly choose d as the loop breaker.
471 not_fun_ty ty = not (maybeToBool (splitFunTy_maybe rho_ty))
473 (_, rho_ty) = splitForAllTys ty
476 var_rhs (Var v) = True
477 var_rhs other_rhs = False
480 @occAnalRhs@ deals with the question of bindings where the Id is marked
481 by an INLINE pragma. For these we record that anything which occurs
482 in its RHS occurs many times. This pessimistically assumes that ths
483 inlined binder also occurs many times in its scope, but if it doesn't
484 we'll catch it next time round. At worst this costs an extra simplifier pass.
485 ToDo: try using the occurrence info for the inline'd binder.
487 [March 97] We do the same for atomic RHSs. Reason: see notes with reOrderRec.
489 [March 98] A new wrinkle is that if the binder has specialisations inside
490 it then we count the specialised Ids as "extra rhs's". That way
491 the "parent" keeps the specialised "children" alive. If the parent
492 dies (because it isn't referenced any more), then the children will
493 die too unless they are already referenced directly.
497 -> Id -> CoreExpr -- Binder and rhs
498 -> (UsageDetails, SimplifiableCoreExpr)
500 occAnalRhs env id (Var v)
502 = (unitIdEnv v (markMany (funOccurrence 0)), Var v)
505 = (emptyDetails, Var v)
507 occAnalRhs env id rhs
509 = (mapIdEnv markMany total_usage, rhs')
512 = (total_usage, rhs')
515 (rhs_usage, rhs') = occAnal env rhs
516 total_usage = foldr add rhs_usage (idSpecVars id)
517 add v u = addOneOcc u v noBinderInfo -- Give a non-committal binder info
518 -- (i.e manyOcc) because many copies
519 -- of the specialised thing can appear
527 -> (UsageDetails, -- Gives info only about the "interesting" Ids
528 SimplifiableCoreExpr)
532 = (unitIdEnv v (funOccurrence 0), Var v)
535 = (emptyDetails, Var v)
537 occAnal env (Lit lit) = (emptyDetails, Lit lit)
538 occAnal env (Prim op args) = (occAnalArgs env args, Prim op args)
541 We regard variables that occur as constructor arguments as "dangerousToDup":
545 f x = let y = expensive x in
547 (case z of {(p,q)->q}, case z of {(p,q)->q})
550 We feel free to duplicate the WHNF (True,y), but that means
551 that y may be duplicated thereby.
553 If we aren't careful we duplicate the (expensive x) call!
554 Constructors are rather like lambdas in this way.
557 occAnal env (Con con args) = (mapIdEnv markDangerousToDup (occAnalArgs env args),
560 occAnal env (SCC cc body)
561 = (mapIdEnv markInsideSCC usage, SCC cc body')
563 (usage, body') = occAnal env body
565 occAnal env (Coerce c ty body)
566 = (usage, Coerce c ty body')
568 (usage, body') = occAnal env body
570 occAnal env (App fun arg)
571 = (fun_usage `combineUsageDetails` arg_usage, App fun' arg)
573 (fun_usage, fun') = occAnal env fun
574 arg_usage = occAnalArg env arg
576 -- For value lambdas we do a special hack. Consider
578 -- If we did nothing, x is used inside the \y, so would be marked
579 -- as dangerous to dup. But in the common case where the abstraction
580 -- is applied to two arguments this is over-pessimistic.
581 -- So instead we don't take account of the \y when dealing with x's usage;
582 -- instead, the simplifier is careful when partially applying lambdas
584 occAnal env expr@(Lam (ValBinder binder) body)
585 = (mapIdEnv markDangerousToDup final_usage,
586 foldr ( \v b -> Lam (ValBinder v) b) body' tagged_binders)
588 (binders,body) = collectValBinders expr
589 (body_usage, body') = occAnal (env `addNewCands` binders) body
590 (final_usage, tagged_binders) = tagBinders body_usage binders
592 -- ANDY: WE MUST THINK ABOUT THIS! (ToDo)
593 occAnal env (Lam (TyBinder tyvar) body)
594 = case occAnal env body of { (body_usage, body') ->
595 (mapIdEnv markDangerousToDup body_usage,
596 Lam (TyBinder tyvar) body') }
598 -- (body_usage, body') = occAnal env body
600 occAnal env (Case scrut alts)
601 = case occAnalAlts env alts of { (alts_usage, alts') ->
602 case occAnal env scrut of { (scrut_usage, scrut') ->
604 det = scrut_usage `combineUsageDetails` alts_usage
606 if isNullIdEnv det then
607 (det, Case scrut' alts')
609 (det, Case scrut' alts') }}
611 (scrut_usage `combineUsageDetails` alts_usage,
614 (scrut_usage, scrut') = occAnal env scrut
615 (alts_usage, alts') = occAnalAlts env alts
618 occAnal env (Let bind body)
619 = case occAnal new_env body of { (body_usage, body') ->
620 case occAnalBind env bind body_usage of { (final_usage, new_binds) ->
621 (final_usage, foldr Let body' new_binds) }} -- mkCoLet* wants Core... (sigh)
623 new_env = env `addNewCands` (bindersOf bind)
624 -- (body_usage, body') = occAnal new_env body
625 -- (final_usage, new_binds) = occAnalBind env bind body_usage
631 occAnalAlts env (AlgAlts alts deflt)
632 = (foldr combineAltsUsageDetails deflt_usage alts_usage,
633 -- Note: combine*Alts*UsageDetails...
634 AlgAlts alts' deflt')
636 (alts_usage, alts') = unzip (map do_alt alts)
637 (deflt_usage, deflt') = occAnalDeflt env deflt
639 do_alt (con, args, rhs)
640 = (final_usage, (con, tagged_args, rhs'))
642 new_env = env `addNewCands` args
643 (rhs_usage, rhs') = occAnal new_env rhs
644 (final_usage, tagged_args) = tagBinders rhs_usage args
646 occAnalAlts env (PrimAlts alts deflt)
647 = (foldr combineAltsUsageDetails deflt_usage alts_usage,
648 -- Note: combine*Alts*UsageDetails...
649 PrimAlts alts' deflt')
651 (alts_usage, alts') = unzip (map do_alt alts)
652 (deflt_usage, deflt') = occAnalDeflt env deflt
655 = (rhs_usage, (lit, rhs'))
657 (rhs_usage, rhs') = occAnal env rhs
659 occAnalDeflt env NoDefault = (emptyDetails, NoDefault)
661 occAnalDeflt env (BindDefault binder rhs)
662 = (final_usage, BindDefault tagged_binder rhs')
664 new_env = env `addNewCand` binder
665 (rhs_usage, rhs') = occAnal new_env rhs
666 (final_usage, tagged_binder) = tagBinder rhs_usage binder
673 occAnalArgs :: OccEnv -> [CoreArg] -> UsageDetails
675 occAnalArgs env atoms
676 = foldr do_one_atom emptyDetails atoms
678 do_one_atom (VarArg v) usage
679 | isCandidate env v = addOneOcc usage v (argOccurrence 0)
681 do_one_atom other_arg usage = usage
684 occAnalArg :: OccEnv -> CoreArg -> UsageDetails
686 occAnalArg env (VarArg v)
687 | isCandidate env v = unitDetails v (argOccurrence 0)
688 | otherwise = emptyDetails
689 occAnalArg _ _ = emptyDetails
693 %************************************************************************
695 \subsection[OccurAnal-types]{Data types}
697 %************************************************************************
702 Bool -- IgnoreINLINEPragma flag
703 -- False <=> OK to use INLINEPragma information
704 -- True <=> ignore INLINEPragma information
706 (Id -> IdSet -> Bool) -- Tells whether an Id occurrence is interesting,
707 -- given the set of in-scope variables
709 IdSet -- In-scope Ids
712 addNewCands :: OccEnv -> [Id] -> OccEnv
713 addNewCands (OccEnv ip ifun cands) ids
714 = OccEnv ip ifun (cands `unionIdSets` mkIdSet ids)
716 addNewCand :: OccEnv -> Id -> OccEnv
717 addNewCand (OccEnv ip ifun cands) id
718 = OccEnv ip ifun (addOneToIdSet cands id)
720 isCandidate :: OccEnv -> Id -> Bool
721 isCandidate (OccEnv _ ifun cands) id = ifun id cands
723 inlineMe :: OccEnv -> Id -> Bool
725 = {- See comments with simplIdWantsToBeINLINEd in SimplUtils.lhs
726 not ignore_inline_prag &&
728 idWantsToBeINLINEd id
731 type UsageDetails = IdEnv BinderInfo -- A finite map from ids to their usage
733 combineUsageDetails, combineAltsUsageDetails
734 :: UsageDetails -> UsageDetails -> UsageDetails
736 combineUsageDetails usage1 usage2
737 = combineIdEnvs addBinderInfo usage1 usage2
739 combineAltsUsageDetails usage1 usage2
740 = combineIdEnvs orBinderInfo usage1 usage2
742 addOneOcc :: UsageDetails -> Id -> BinderInfo -> UsageDetails
743 addOneOcc usage id info
744 = combineIdEnvs addBinderInfo usage (unitIdEnv id info)
745 -- ToDo: make this more efficient
747 emptyDetails = (nullIdEnv :: UsageDetails)
749 unitDetails id info = (unitIdEnv id info :: UsageDetails)
751 tagBinders :: UsageDetails -- Of scope
753 -> (UsageDetails, -- Details with binders removed
754 [(Id,BinderInfo)]) -- Tagged binders
756 tagBinders usage binders =
758 usage' = usage `delManyFromIdEnv` binders
759 uss = [ (binder, usage_of usage binder) | binder <- binders ]
761 if isNullIdEnv usage' then
766 = (usage `delManyFromIdEnv` binders,
767 [ (binder, usage_of usage binder) | binder <- binders ]
770 tagBinder :: UsageDetails -- Of scope
772 -> (UsageDetails, -- Details with binders removed
773 (Id,BinderInfo)) -- Tagged binders
775 tagBinder usage binder =
777 usage' = usage `delOneFromIdEnv` binder
778 us = usage_of usage binder
780 if isNullIdEnv usage' then -- Bogus test to force evaluation.
781 (usage', (binder, us))
783 (usage', (binder, us))
785 if isDeadOcc us then -- Ditto
791 usage_of usage binder
793 = noBinderInfo -- Visible-elsewhere things count as many
795 = case (lookupIdEnv usage binder) of
796 Nothing -> deadOccurrence
799 isNeeded env usage binder = not (isDeadOcc (usage_of usage binder))