LLVM 22.0.0git
CGSCCPassManager.cpp
Go to the documentation of this file.
1//===- CGSCCPassManager.cpp - Managing & running CGSCC passes -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/ArrayRef.h"
12#include "llvm/ADT/STLExtras.h"
13#include "llvm/ADT/SetVector.h"
16#include "llvm/ADT/Statistic.h"
19#include "llvm/IR/Constant.h"
21#include "llvm/IR/Instruction.h"
22#include "llvm/IR/PassManager.h"
24#include "llvm/IR/ValueHandle.h"
28#include "llvm/Support/Debug.h"
31#include <cassert>
32#include <optional>
33
34#define DEBUG_TYPE "cgscc"
35
36using namespace llvm;
37
38STATISTIC(LargestCGSCC, "Number of functions in the largest SCC");
39
40// Explicit template instantiations and specialization definitions for core
41// template typedefs.
42namespace llvm {
44 "abort-on-max-devirt-iterations-reached",
45 cl::desc("Abort when the max iterations for devirtualization CGSCC repeat "
46 "pass is reached"));
47
49
50// Explicit instantiations for the core proxy templates.
52template class LLVM_EXPORT_TEMPLATE
56template class LLVM_EXPORT_TEMPLATE
60template class LLVM_EXPORT_TEMPLATE
62
63/// Explicitly specialize the pass manager run method to handle call graph
64/// updates.
65template <>
71 // Request PassInstrumentation from analysis manager, will use it to run
72 // instrumenting callbacks for the passes later.
75
77
78 // The SCC may be refined while we are running passes over it, so set up
79 // a pointer that we can update.
80 LazyCallGraph::SCC *C = &InitialC;
81
82 // Get Function analysis manager from its proxy.
85
86 for (auto &Pass : Passes) {
87 // Check the PassInstrumentation's BeforePass callbacks before running the
88 // pass, skip its execution completely if asked to (callback returns false).
89 if (!PI.runBeforePass(*Pass, *C))
90 continue;
91
92 LargestCGSCC.updateMax(C->size());
93
94 PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR);
95
96 // Update the SCC if necessary.
97 C = UR.UpdatedC ? UR.UpdatedC : C;
98 if (UR.UpdatedC) {
99 // If C is updated, also create a proxy and update FAM inside the result.
100 auto *ResultFAMCP =
102 ResultFAMCP->updateFAM(FAM);
103 }
104
105 // Intersect the final preserved analyses to compute the aggregate
106 // preserved set for this pass manager.
107 PA.intersect(PassPA);
108
109 // If the CGSCC pass wasn't able to provide a valid updated SCC, the
110 // current SCC may simply need to be skipped if invalid.
111 if (UR.InvalidatedSCCs.count(C)) {
113 LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
114 break;
115 }
116
117 // Check that we didn't miss any update scenario.
118 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
119
120 // Update the analysis manager as each pass runs and potentially
121 // invalidates analyses.
122 AM.invalidate(*C, PassPA);
123
124 PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
125 }
126
127 // Before we mark all of *this* SCC's analyses as preserved below, intersect
128 // this with the cross-SCC preserved analysis set. This is used to allow
129 // CGSCC passes to mutate ancestor SCCs and still trigger proper invalidation
130 // for them.
131 UR.CrossSCCPA.intersect(PA);
132
133 // Invalidation was handled after each pass in the above loop for the current
134 // SCC. Therefore, the remaining analysis results in the AnalysisManager are
135 // preserved. We mark this with a set so that we don't need to inspect each
136 // one individually.
137 PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
138
139 return PA;
140}
141
144 // Setup the CGSCC analysis manager from its proxy.
146 AM.getResult<CGSCCAnalysisManagerModuleProxy>(M).getManager();
147
148 // Get the call graph for this module.
150
151 // Get Function analysis manager from its proxy.
154
155 // We keep worklists to allow us to push more work onto the pass manager as
156 // the passes are run.
159
160 // Keep sets for invalidated SCCs that should be skipped when
161 // iterating off the worklists.
163
165 InlinedInternalEdges;
166
167 SmallVector<Function *, 4> DeadFunctions;
168
169 CGSCCUpdateResult UR = {CWorklist,
170 InvalidSCCSet,
171 nullptr,
173 InlinedInternalEdges,
174 DeadFunctions,
175 {}};
176
177 // Request PassInstrumentation from analysis manager, will use it to run
178 // instrumenting callbacks for the passes later.
180
182 CG.buildRefSCCs();
183 for (LazyCallGraph::RefSCC &RC :
185 assert(RCWorklist.empty() &&
186 "Should always start with an empty RefSCC worklist");
187 // The postorder_ref_sccs range we are walking is lazily constructed, so
188 // we only push the first one onto the worklist. The worklist allows us
189 // to capture *new* RefSCCs created during transformations.
190 //
191 // We really want to form RefSCCs lazily because that makes them cheaper
192 // to update as the program is simplified and allows us to have greater
193 // cache locality as forming a RefSCC touches all the parts of all the
194 // functions within that RefSCC.
195 //
196 // We also eagerly increment the iterator to the next position because
197 // the CGSCC passes below may delete the current RefSCC.
198 RCWorklist.insert(&RC);
199
200 do {
201 LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
202 assert(CWorklist.empty() &&
203 "Should always start with an empty SCC worklist");
204
205 LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
206 << "\n");
207
208 // The top of the worklist may *also* be the same SCC we just ran over
209 // (and invalidated for). Keep track of that last SCC we processed due
210 // to SCC update to avoid redundant processing when an SCC is both just
211 // updated itself and at the top of the worklist.
212 LazyCallGraph::SCC *LastUpdatedC = nullptr;
213
214 // Push the initial SCCs in reverse post-order as we'll pop off the
215 // back and so see this in post-order.
217 CWorklist.insert(&C);
218
219 do {
220 LazyCallGraph::SCC *C = CWorklist.pop_back_val();
221 // Due to call graph mutations, we may have invalid SCCs or SCCs from
222 // other RefSCCs in the worklist. The invalid ones are dead and the
223 // other RefSCCs should be queued above, so we just need to skip both
224 // scenarios here.
225 if (InvalidSCCSet.count(C)) {
226 LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n");
227 continue;
228 }
229 if (LastUpdatedC == C) {
230 LLVM_DEBUG(dbgs() << "Skipping redundant run on SCC: " << *C << "\n");
231 continue;
232 }
233 // We used to also check if the current SCC is part of the current
234 // RefSCC and bail if it wasn't, since it should be in RCWorklist.
235 // However, this can cause compile time explosions in some cases on
236 // modules with a huge RefSCC. If a non-trivial amount of SCCs in the
237 // huge RefSCC can become their own child RefSCC, we create one child
238 // RefSCC, bail on the current RefSCC, visit the child RefSCC, revisit
239 // the huge RefSCC, and repeat. By visiting all SCCs in the original
240 // RefSCC we create all the child RefSCCs in one pass of the RefSCC,
241 // rather one pass of the RefSCC creating one child RefSCC at a time.
242
243 // Ensure we can proxy analysis updates from the CGSCC analysis manager
244 // into the Function analysis manager by getting a proxy here.
245 // This also needs to update the FunctionAnalysisManager, as this may be
246 // the first time we see this SCC.
248 FAM);
249
250 // Each time we visit a new SCC pulled off the worklist,
251 // a transformation of a child SCC may have also modified this parent
252 // and invalidated analyses. So we invalidate using the update record's
253 // cross-SCC preserved set. This preserved set is intersected by any
254 // CGSCC pass that handles invalidation (primarily pass managers) prior
255 // to marking its SCC as preserved. That lets us track everything that
256 // might need invalidation across SCCs without excessive invalidations
257 // on a single SCC.
258 //
259 // This essentially allows SCC passes to freely invalidate analyses
260 // of any ancestor SCC. If this becomes detrimental to successfully
261 // caching analyses, we could force each SCC pass to manually
262 // invalidate the analyses for any SCCs other than themselves which
263 // are mutated. However, that seems to lose the robustness of the
264 // pass-manager driven invalidation scheme.
266
267 do {
268 // Check that we didn't miss any update scenario.
269 assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");
270 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
271
272 LastUpdatedC = UR.UpdatedC;
273 UR.UpdatedC = nullptr;
274
275 // Check the PassInstrumentation's BeforePass callbacks before
276 // running the pass, skip its execution completely if asked to
277 // (callback returns false).
279 continue;
280
281 PreservedAnalyses PassPA = Pass->run(*C, CGAM, CG, UR);
282
283 // Update the SCC and RefSCC if necessary.
284 C = UR.UpdatedC ? UR.UpdatedC : C;
285
286 if (UR.UpdatedC) {
287 // If we're updating the SCC, also update the FAM inside the proxy's
288 // result.
290 FAM);
291 }
292
293 // Intersect with the cross-SCC preserved set to capture any
294 // cross-SCC invalidation.
295 UR.CrossSCCPA.intersect(PassPA);
296 // Intersect the preserved set so that invalidation of module
297 // analyses will eventually occur when the module pass completes.
298 PA.intersect(PassPA);
299
300 // If the CGSCC pass wasn't able to provide a valid updated SCC,
301 // the current SCC may simply need to be skipped if invalid.
302 if (UR.InvalidatedSCCs.count(C)) {
304 LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
305 break;
306 }
307
308 // Check that we didn't miss any update scenario.
309 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
310
311 // We handle invalidating the CGSCC analysis manager's information
312 // for the (potentially updated) SCC here. Note that any other SCCs
313 // whose structure has changed should have been invalidated by
314 // whatever was updating the call graph. This SCC gets invalidated
315 // late as it contains the nodes that were actively being
316 // processed.
317 CGAM.invalidate(*C, PassPA);
318
319 PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
320
321 // The pass may have restructured the call graph and refined the
322 // current SCC and/or RefSCC. We need to update our current SCC and
323 // RefSCC pointers to follow these. Also, when the current SCC is
324 // refined, re-run the SCC pass over the newly refined SCC in order
325 // to observe the most precise SCC model available. This inherently
326 // cannot cycle excessively as it only happens when we split SCCs
327 // apart, at most converging on a DAG of single nodes.
328 // FIXME: If we ever start having RefSCC passes, we'll want to
329 // iterate there too.
330 if (UR.UpdatedC)
332 << "Re-running SCC passes after a refinement of the "
333 "current SCC: "
334 << *UR.UpdatedC << "\n");
335
336 // Note that both `C` and `RC` may at this point refer to deleted,
337 // invalid SCC and RefSCCs respectively. But we will short circuit
338 // the processing when we check them in the loop above.
339 } while (UR.UpdatedC);
340 } while (!CWorklist.empty());
341
342 // We only need to keep internal inlined edge information within
343 // a RefSCC, clear it to save on space and let the next time we visit
344 // any of these functions have a fresh start.
345 InlinedInternalEdges.clear();
346 } while (!RCWorklist.empty());
347 }
348
349 CG.removeDeadFunctions(DeadFunctions);
350 for (Function *DeadF : DeadFunctions)
351 DeadF->eraseFromParent();
352
353#if defined(EXPENSIVE_CHECKS)
354 // Verify that the call graph is still valid.
355 CG.verify();
356#endif
357
358 // By definition we preserve the call garph, all SCC analyses, and the
359 // analysis proxies by handling them above and in any nested pass managers.
360 PA.preserveSet<AllAnalysesOn<LazyCallGraph::SCC>>();
361 PA.preserve<LazyCallGraphAnalysis>();
362 PA.preserve<CGSCCAnalysisManagerModuleProxy>();
364 return PA;
365}
366
369 LazyCallGraph &CG,
370 CGSCCUpdateResult &UR) {
373 AM.getResult<PassInstrumentationAnalysis>(InitialC, CG);
374
375 // The SCC may be refined while we are running passes over it, so set up
376 // a pointer that we can update.
377 LazyCallGraph::SCC *C = &InitialC;
378
379 // Struct to track the counts of direct and indirect calls in each function
380 // of the SCC.
381 struct CallCount {
382 int Direct;
383 int Indirect;
384 };
385
386 // Put value handles on all of the indirect calls and return the number of
387 // direct calls for each function in the SCC.
388 auto ScanSCC = [](LazyCallGraph::SCC &C,
390 assert(CallHandles.empty() && "Must start with a clear set of handles.");
391
393 CallCount CountLocal = {0, 0};
394 for (LazyCallGraph::Node &N : C) {
395 CallCount &Count =
396 CallCounts.insert(std::make_pair(&N.getFunction(), CountLocal))
397 .first->second;
398 for (Instruction &I : instructions(N.getFunction()))
399 if (auto *CB = dyn_cast<CallBase>(&I)) {
400 if (CB->getCalledFunction()) {
401 ++Count.Direct;
402 } else {
403 ++Count.Indirect;
404 CallHandles.insert({CB, WeakTrackingVH(CB)});
405 }
406 }
407 }
408
409 return CallCounts;
410 };
411
412 UR.IndirectVHs.clear();
413 // Populate the initial call handles and get the initial call counts.
414 auto CallCounts = ScanSCC(*C, UR.IndirectVHs);
415
416 for (int Iteration = 0;; ++Iteration) {
418 continue;
419
420 PreservedAnalyses PassPA = Pass->run(*C, AM, CG, UR);
421
422 PA.intersect(PassPA);
423
424 // If the CGSCC pass wasn't able to provide a valid updated SCC, the
425 // current SCC may simply need to be skipped if invalid.
426 if (UR.InvalidatedSCCs.count(C)) {
428 LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
429 break;
430 }
431
432 // Update the analysis manager with each run and intersect the total set
433 // of preserved analyses so we're ready to iterate.
434 AM.invalidate(*C, PassPA);
435
436 PI.runAfterPass<LazyCallGraph::SCC>(*Pass, *C, PassPA);
437
438 // If the SCC structure has changed, bail immediately and let the outer
439 // CGSCC layer handle any iteration to reflect the refined structure.
440 if (UR.UpdatedC && UR.UpdatedC != C)
441 break;
442
443 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
444
445 // Check whether any of the handles were devirtualized.
446 bool Devirt = llvm::any_of(UR.IndirectVHs, [](auto &P) -> bool {
447 if (P.second) {
448 if (CallBase *CB = dyn_cast<CallBase>(P.second)) {
449 if (CB->getCalledFunction()) {
450 LLVM_DEBUG(dbgs() << "Found devirtualized call: " << *CB << "\n");
451 return true;
452 }
453 }
454 }
455 return false;
456 });
457
458 // Rescan to build up a new set of handles and count how many direct
459 // calls remain. If we decide to iterate, this also sets up the input to
460 // the next iteration.
461 UR.IndirectVHs.clear();
462 auto NewCallCounts = ScanSCC(*C, UR.IndirectVHs);
463
464 // If we haven't found an explicit devirtualization already see if we
465 // have decreased the number of indirect calls and increased the number
466 // of direct calls for any function in the SCC. This can be fooled by all
467 // manner of transformations such as DCE and other things, but seems to
468 // work well in practice.
469 if (!Devirt)
470 // Iterate over the keys in NewCallCounts, if Function also exists in
471 // CallCounts, make the check below.
472 for (auto &Pair : NewCallCounts) {
473 auto &CallCountNew = Pair.second;
474 auto CountIt = CallCounts.find(Pair.first);
475 if (CountIt != CallCounts.end()) {
476 const auto &CallCountOld = CountIt->second;
477 if (CallCountOld.Indirect > CallCountNew.Indirect &&
478 CallCountOld.Direct < CallCountNew.Direct) {
479 Devirt = true;
480 break;
481 }
482 }
483 }
484
485 if (!Devirt) {
486 break;
487 }
488
489 // Otherwise, if we've already hit our max, we're done.
490 if (Iteration >= MaxIterations) {
492 report_fatal_error("Max devirtualization iterations reached");
494 dbgs() << "Found another devirtualization after hitting the max "
495 "number of repetitions ("
496 << MaxIterations << ") on SCC: " << *C << "\n");
497 break;
498 }
499
501 dbgs() << "Repeating an SCC pass after finding a devirtualization in: "
502 << *C << "\n");
503
504 // Move over the new call counts in preparation for iterating.
505 CallCounts = std::move(NewCallCounts);
506 }
507
508 // Note that we don't add any preserved entries here unlike a more normal
509 // "pass manager" because we only handle invalidation *between* iterations,
510 // not after the last iteration.
511 return PA;
512}
513
516 LazyCallGraph &CG,
517 CGSCCUpdateResult &UR) {
518 // Setup the function analysis manager from its proxy.
520 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
521
523
524 // The SCC may get split while we are optimizing functions due to deleting
525 // edges. If this happens, the current SCC can shift, so keep track of
526 // a pointer we can overwrite.
527 LazyCallGraph::SCC *CurrentC = &C;
528
529 LLVM_DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n");
530
532 for (LazyCallGraph::Node *N : Nodes) {
533 // Skip nodes from other SCCs. These may have been split out during
534 // processing. We'll eventually visit those SCCs and pick up the nodes
535 // there.
536 if (CG.lookupSCC(*N) != CurrentC)
537 continue;
538
539 Function &F = N->getFunction();
540
542 continue;
543
545 if (!PI.runBeforePass<Function>(*Pass, F))
546 continue;
547
548 PreservedAnalyses PassPA = Pass->run(F, FAM);
549
550 // We know that the function pass couldn't have invalidated any other
551 // function's analyses (that's the contract of a function pass), so
552 // directly handle the function analysis manager's invalidation here.
553 FAM.invalidate(F, EagerlyInvalidate ? PreservedAnalyses::none() : PassPA);
554
555 PI.runAfterPass<Function>(*Pass, F, PassPA);
556
557 // Then intersect the preserved set so that invalidation of module
558 // analyses will eventually occur when the module pass completes.
559 PA.intersect(std::move(PassPA));
560
561 // If the call graph hasn't been preserved, update it based on this
562 // function pass. This may also update the current SCC to point to
563 // a smaller, more refined SCC.
564 auto PAC = PA.getChecker<LazyCallGraphAnalysis>();
565 if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
566 CurrentC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentC, *N,
567 AM, UR, FAM);
568 assert(CG.lookupSCC(*N) == CurrentC &&
569 "Current SCC not updated to the SCC containing the current node!");
570 }
571 }
572
573 // By definition we preserve the proxy. And we preserve all analyses on
574 // Functions. This precludes *any* invalidation of function analyses by the
575 // proxy, but that's OK because we've taken care to invalidate analyses in
576 // the function analysis manager incrementally above.
579
580 // We've also ensured that we updated the call graph along the way.
582
583 return PA;
584}
585
586bool CGSCCAnalysisManagerModuleProxy::Result::invalidate(
587 Module &M, const PreservedAnalyses &PA,
589 // If literally everything is preserved, we're done.
590 if (PA.areAllPreserved())
591 return false; // This is still a valid proxy.
592
593 // If this proxy or the call graph is going to be invalidated, we also need
594 // to clear all the keys coming from that analysis.
595 //
596 // We also directly invalidate the FAM's module proxy if necessary, and if
597 // that proxy isn't preserved we can't preserve this proxy either. We rely on
598 // it to handle module -> function analysis invalidation in the face of
599 // structural changes and so if it's unavailable we conservatively clear the
600 // entire SCC layer as well rather than trying to do invalidation ourselves.
602 if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>()) ||
603 Inv.invalidate<LazyCallGraphAnalysis>(M, PA) ||
605 InnerAM->clear();
606
607 // And the proxy itself should be marked as invalid so that we can observe
608 // the new call graph. This isn't strictly necessary because we cheat
609 // above, but is still useful.
610 return true;
611 }
612
613 // Directly check if the relevant set is preserved so we can short circuit
614 // invalidating SCCs below.
615 bool AreSCCAnalysesPreserved =
617
618 // Ok, we have a graph, so we can propagate the invalidation down into it.
619 G->buildRefSCCs();
620 for (auto &RC : G->postorder_ref_sccs())
621 for (auto &C : RC) {
622 std::optional<PreservedAnalyses> InnerPA;
623
624 // Check to see whether the preserved set needs to be adjusted based on
625 // module-level analysis invalidation triggering deferred invalidation
626 // for this SCC.
627 if (auto *OuterProxy =
628 InnerAM->getCachedResult<ModuleAnalysisManagerCGSCCProxy>(C))
629 for (const auto &OuterInvalidationPair :
630 OuterProxy->getOuterInvalidations()) {
631 AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first;
632 const auto &InnerAnalysisIDs = OuterInvalidationPair.second;
633 if (Inv.invalidate(OuterAnalysisID, M, PA)) {
634 if (!InnerPA)
635 InnerPA = PA;
636 for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs)
637 InnerPA->abandon(InnerAnalysisID);
638 }
639 }
640
641 // Check if we needed a custom PA set. If so we'll need to run the inner
642 // invalidation.
643 if (InnerPA) {
644 InnerAM->invalidate(C, *InnerPA);
645 continue;
646 }
647
648 // Otherwise we only need to do invalidation if the original PA set didn't
649 // preserve all SCC analyses.
650 if (!AreSCCAnalysesPreserved)
651 InnerAM->invalidate(C, PA);
652 }
653
654 // Return false to indicate that this result is still a valid proxy.
655 return false;
656}
657
658template <>
661 // Force the Function analysis manager to also be available so that it can
662 // be accessed in an SCC analysis and proxied onward to function passes.
663 // FIXME: It is pretty awkward to just drop the result here and assert that
664 // we can find it again later.
666
667 return Result(*InnerAM, AM.getResult<LazyCallGraphAnalysis>(M));
668}
669
670AnalysisKey FunctionAnalysisManagerCGSCCProxy::Key;
671
675 LazyCallGraph &CG) {
676 // Note: unconditionally getting checking that the proxy exists may get it at
677 // this point. There are cases when this is being run unnecessarily, but
678 // it is cheap and having the assertion in place is more valuable.
679 auto &MAMProxy = AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG);
680 Module &M = *C.begin()->getFunction().getParent();
681 bool ProxyExists =
682 MAMProxy.cachedResultExists<FunctionAnalysisManagerModuleProxy>(M);
683 assert(ProxyExists &&
684 "The CGSCC pass manager requires that the FAM module proxy is run "
685 "on the module prior to entering the CGSCC walk");
686 (void)ProxyExists;
687
688 // We just return an empty result. The caller will use the updateFAM interface
689 // to correctly register the relevant FunctionAnalysisManager based on the
690 // context in which this proxy is run.
691 return Result();
692}
693
697 // If literally everything is preserved, we're done.
698 if (PA.areAllPreserved())
699 return false; // This is still a valid proxy.
700
701 // All updates to preserve valid results are done below, so we don't need to
702 // invalidate this proxy.
703 //
704 // Note that in order to preserve this proxy, a module pass must ensure that
705 // the FAM has been completely updated to handle the deletion of functions.
706 // Specifically, any FAM-cached results for those functions need to have been
707 // forcibly cleared. When preserved, this proxy will only invalidate results
708 // cached on functions *still in the module* at the end of the module pass.
710 if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<LazyCallGraph::SCC>>()) {
711 for (LazyCallGraph::Node &N : C)
712 FAM->invalidate(N.getFunction(), PA);
713
714 return false;
715 }
716
717 // Directly check if the relevant set is preserved.
718 bool AreFunctionAnalysesPreserved =
720
721 // Now walk all the functions to see if any inner analysis invalidation is
722 // necessary.
723 for (LazyCallGraph::Node &N : C) {
724 Function &F = N.getFunction();
725 std::optional<PreservedAnalyses> FunctionPA;
726
727 // Check to see whether the preserved set needs to be pruned based on
728 // SCC-level analysis invalidation that triggers deferred invalidation
729 // registered with the outer analysis manager proxy for this function.
730 if (auto *OuterProxy =
732 for (const auto &OuterInvalidationPair :
733 OuterProxy->getOuterInvalidations()) {
734 AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first;
735 const auto &InnerAnalysisIDs = OuterInvalidationPair.second;
736 if (Inv.invalidate(OuterAnalysisID, C, PA)) {
737 if (!FunctionPA)
738 FunctionPA = PA;
739 for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs)
740 FunctionPA->abandon(InnerAnalysisID);
741 }
742 }
743
744 // Check if we needed a custom PA set, and if so we'll need to run the
745 // inner invalidation.
746 if (FunctionPA) {
747 FAM->invalidate(F, *FunctionPA);
748 continue;
749 }
750
751 // Otherwise we only need to do invalidation if the original PA set didn't
752 // preserve all function analyses.
753 if (!AreFunctionAnalysesPreserved)
754 FAM->invalidate(F, PA);
755 }
756
757 // Return false to indicate that this result is still a valid proxy.
758 return false;
759}
760
761} // end namespace llvm
762
763/// When a new SCC is created for the graph we first update the
764/// FunctionAnalysisManager in the Proxy's result.
765/// As there might be function analysis results cached for the functions now in
766/// that SCC, two forms of updates are required.
767///
768/// First, a proxy from the SCC to the FunctionAnalysisManager needs to be
769/// created so that any subsequent invalidation events to the SCC are
770/// propagated to the function analysis results cached for functions within it.
771///
772/// Second, if any of the functions within the SCC have analysis results with
773/// outer analysis dependencies, then those dependencies would point to the
774/// *wrong* SCC's analysis result. We forcibly invalidate the necessary
775/// function analyses so that they don't retain stale handles.
781
782 // Now walk the functions in this SCC and invalidate any function analysis
783 // results that might have outer dependencies on an SCC analysis.
784 for (LazyCallGraph::Node &N : C) {
785 Function &F = N.getFunction();
786
787 auto *OuterProxy =
789 if (!OuterProxy)
790 // No outer analyses were queried, nothing to do.
791 continue;
792
793 // Forcibly abandon all the inner analyses with dependencies, but
794 // invalidate nothing else.
795 auto PA = PreservedAnalyses::all();
796 for (const auto &OuterInvalidationPair :
797 OuterProxy->getOuterInvalidations()) {
798 const auto &InnerAnalysisIDs = OuterInvalidationPair.second;
799 for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs)
800 PA.abandon(InnerAnalysisID);
801 }
802
803 // Now invalidate anything we found.
804 FAM.invalidate(F, PA);
805 }
806}
807
808/// Helper function to update both the \c CGSCCAnalysisManager \p AM and the \c
809/// CGSCCPassManager's \c CGSCCUpdateResult \p UR based on a range of newly
810/// added SCCs.
811///
812/// The range of new SCCs must be in postorder already. The SCC they were split
813/// out of must be provided as \p C. The current node being mutated and
814/// triggering updates must be passed as \p N.
815///
816/// This function returns the SCC containing \p N. This will be either \p C if
817/// no new SCCs have been split out, or it will be the new SCC containing \p N.
818template <typename SCCRangeT>
819static LazyCallGraph::SCC *
820incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
823 using SCC = LazyCallGraph::SCC;
824
825 if (NewSCCRange.empty())
826 return C;
827
828 // Add the current SCC to the worklist as its shape has changed.
829 UR.CWorklist.insert(C);
830 LLVM_DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist:" << *C
831 << "\n");
832
833 SCC *OldC = C;
834
835 // Update the current SCC. Note that if we have new SCCs, this must actually
836 // change the SCC.
837 assert(C != &*NewSCCRange.begin() &&
838 "Cannot insert new SCCs without changing current SCC!");
839 C = &*NewSCCRange.begin();
840 assert(G.lookupSCC(N) == C && "Failed to update current SCC!");
841
842 // If we had a cached FAM proxy originally, we will want to create more of
843 // them for each SCC that was split off.
844 FunctionAnalysisManager *FAM = nullptr;
845 if (auto *FAMProxy =
847 FAM = &FAMProxy->getManager();
848
849 // We need to propagate an invalidation call to all but the newly current SCC
850 // because the outer pass manager won't do that for us after splitting them.
851 // FIXME: We should accept a PreservedAnalysis from the CG updater so that if
852 // there are preserved analysis we can avoid invalidating them here for
853 // split-off SCCs.
854 // We know however that this will preserve any FAM proxy so go ahead and mark
855 // that.
856 auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
858 AM.invalidate(*OldC, PA);
859
860 // Ensure the now-current SCC's function analyses are updated.
861 if (FAM)
863
864 for (SCC &NewC : llvm::reverse(llvm::drop_begin(NewSCCRange))) {
865 assert(C != &NewC && "No need to re-visit the current SCC!");
866 assert(OldC != &NewC && "Already handled the original SCC!");
867 UR.CWorklist.insert(&NewC);
868 LLVM_DEBUG(dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n");
869
870 // Ensure new SCCs' function analyses are updated.
871 if (FAM)
873
874 // Also propagate a normal invalidation to the new SCC as only the current
875 // will get one from the pass manager infrastructure.
876 AM.invalidate(NewC, PA);
877 }
878 return C;
879}
880
887 using SCC = LazyCallGraph::SCC;
888 using RefSCC = LazyCallGraph::RefSCC;
889
890 RefSCC &InitialRC = InitialC.getOuterRefSCC();
891 SCC *C = &InitialC;
892 RefSCC *RC = &InitialRC;
893 Function &F = N.getFunction();
894
895 // Walk the function body and build up the set of retained, promoted, and
896 // demoted edges.
899 SmallPtrSet<Node *, 16> RetainedEdges;
900 SmallSetVector<Node *, 4> PromotedRefTargets;
901 SmallSetVector<Node *, 4> DemotedCallTargets;
902 SmallSetVector<Node *, 4> NewCallEdges;
903 SmallSetVector<Node *, 4> NewRefEdges;
904
905 // First walk the function and handle all called functions. We do this first
906 // because if there is a single call edge, whether there are ref edges is
907 // irrelevant.
908 for (Instruction &I : instructions(F)) {
909 if (auto *CB = dyn_cast<CallBase>(&I)) {
910 if (Function *Callee = CB->getCalledFunction()) {
911 if (Visited.insert(Callee).second && !Callee->isDeclaration()) {
912 Node *CalleeN = G.lookup(*Callee);
913 assert(CalleeN &&
914 "Visited function should already have an associated node");
915 Edge *E = N->lookup(*CalleeN);
916 assert((E || !FunctionPass) &&
917 "No function transformations should introduce *new* "
918 "call edges! Any new calls should be modeled as "
919 "promoted existing ref edges!");
920 bool Inserted = RetainedEdges.insert(CalleeN).second;
921 (void)Inserted;
922 assert(Inserted && "We should never visit a function twice.");
923 if (!E)
924 NewCallEdges.insert(CalleeN);
925 else if (!E->isCall())
926 PromotedRefTargets.insert(CalleeN);
927 }
928 } else {
929 // We can miss devirtualization if an indirect call is created then
930 // promoted before updateCGAndAnalysisManagerForPass runs.
931 auto *Entry = UR.IndirectVHs.find(CB);
932 if (Entry == UR.IndirectVHs.end())
933 UR.IndirectVHs.insert({CB, WeakTrackingVH(CB)});
934 else if (!Entry->second)
935 Entry->second = WeakTrackingVH(CB);
936 }
937 }
938 }
939
940 // Now walk all references.
941 for (Instruction &I : instructions(F))
942 for (Value *Op : I.operand_values())
943 if (auto *OpC = dyn_cast<Constant>(Op))
944 if (Visited.insert(OpC).second)
945 Worklist.push_back(OpC);
946
947 auto VisitRef = [&](Function &Referee) {
948 Node *RefereeN = G.lookup(Referee);
949 assert(RefereeN &&
950 "Visited function should already have an associated node");
951 Edge *E = N->lookup(*RefereeN);
952 assert((E || !FunctionPass) &&
953 "No function transformations should introduce *new* ref "
954 "edges! Any new ref edges would require IPO which "
955 "function passes aren't allowed to do!");
956 bool Inserted = RetainedEdges.insert(RefereeN).second;
957 (void)Inserted;
958 assert(Inserted && "We should never visit a function twice.");
959 if (!E)
960 NewRefEdges.insert(RefereeN);
961 else if (E->isCall())
962 DemotedCallTargets.insert(RefereeN);
963 };
964 LazyCallGraph::visitReferences(Worklist, Visited, VisitRef);
965
966 // Handle new ref edges.
967 for (Node *RefTarget : NewRefEdges) {
968 SCC &TargetC = *G.lookupSCC(*RefTarget);
969 RefSCC &TargetRC = TargetC.getOuterRefSCC();
970 (void)TargetRC;
971 // TODO: This only allows trivial edges to be added for now.
972#ifdef EXPENSIVE_CHECKS
973 assert((RC == &TargetRC ||
974 RC->isAncestorOf(TargetRC)) && "New ref edge is not trivial!");
975#endif
976 RC->insertTrivialRefEdge(N, *RefTarget);
977 }
978
979 // Handle new call edges.
980 for (Node *CallTarget : NewCallEdges) {
981 SCC &TargetC = *G.lookupSCC(*CallTarget);
982 RefSCC &TargetRC = TargetC.getOuterRefSCC();
983 (void)TargetRC;
984 // TODO: This only allows trivial edges to be added for now.
985#ifdef EXPENSIVE_CHECKS
986 assert((RC == &TargetRC ||
987 RC->isAncestorOf(TargetRC)) && "New call edge is not trivial!");
988#endif
989 // Add a trivial ref edge to be promoted later on alongside
990 // PromotedRefTargets.
991 RC->insertTrivialRefEdge(N, *CallTarget);
992 }
993
994 // Include synthetic reference edges to known, defined lib functions.
995 for (auto *LibFn : G.getLibFunctions())
996 // While the list of lib functions doesn't have repeats, don't re-visit
997 // anything handled above.
998 if (!Visited.count(LibFn))
999 VisitRef(*LibFn);
1000
1001 // First remove all of the edges that are no longer present in this function.
1002 // The first step makes these edges uniformly ref edges and accumulates them
1003 // into a separate data structure so removal doesn't invalidate anything.
1004 SmallVector<Node *, 4> DeadTargets;
1005 for (Edge &E : *N) {
1006 if (RetainedEdges.count(&E.getNode()))
1007 continue;
1008
1009 SCC &TargetC = *G.lookupSCC(E.getNode());
1010 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1011 if (&TargetRC == RC && E.isCall()) {
1012 if (C != &TargetC) {
1013 // For separate SCCs this is trivial.
1014 RC->switchTrivialInternalEdgeToRef(N, E.getNode());
1015 } else {
1016 // Now update the call graph.
1017 C = incorporateNewSCCRange(RC->switchInternalEdgeToRef(N, E.getNode()),
1018 G, N, C, AM, UR);
1019 }
1020 }
1021
1022 // Now that this is ready for actual removal, put it into our list.
1023 DeadTargets.push_back(&E.getNode());
1024 }
1025 // Remove the easy cases quickly and actually pull them out of our list.
1026 llvm::erase_if(DeadTargets, [&](Node *TargetN) {
1027 SCC &TargetC = *G.lookupSCC(*TargetN);
1028 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1029
1030 // We can't trivially remove internal targets, so skip
1031 // those.
1032 if (&TargetRC == RC)
1033 return false;
1034
1035 LLVM_DEBUG(dbgs() << "Deleting outgoing edge from '" << N << "' to '"
1036 << *TargetN << "'\n");
1037 RC->removeOutgoingEdge(N, *TargetN);
1038 return true;
1039 });
1040
1041 // Next demote all the call edges that are now ref edges. This helps make
1042 // the SCCs small which should minimize the work below as we don't want to
1043 // form cycles that this would break.
1044 for (Node *RefTarget : DemotedCallTargets) {
1045 SCC &TargetC = *G.lookupSCC(*RefTarget);
1046 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1047
1048 // The easy case is when the target RefSCC is not this RefSCC. This is
1049 // only supported when the target RefSCC is a child of this RefSCC.
1050 if (&TargetRC != RC) {
1051#ifdef EXPENSIVE_CHECKS
1052 assert(RC->isAncestorOf(TargetRC) &&
1053 "Cannot potentially form RefSCC cycles here!");
1054#endif
1055 RC->switchOutgoingEdgeToRef(N, *RefTarget);
1056 LLVM_DEBUG(dbgs() << "Switch outgoing call edge to a ref edge from '" << N
1057 << "' to '" << *RefTarget << "'\n");
1058 continue;
1059 }
1060
1061 // We are switching an internal call edge to a ref edge. This may split up
1062 // some SCCs.
1063 if (C != &TargetC) {
1064 // For separate SCCs this is trivial.
1065 RC->switchTrivialInternalEdgeToRef(N, *RefTarget);
1066 continue;
1067 }
1068
1069 // Now update the call graph.
1070 C = incorporateNewSCCRange(RC->switchInternalEdgeToRef(N, *RefTarget), G, N,
1071 C, AM, UR);
1072 }
1073
1074 // We added a ref edge earlier for new call edges, promote those to call edges
1075 // alongside PromotedRefTargets.
1076 PromotedRefTargets.insert_range(NewCallEdges);
1077
1078 // Now promote ref edges into call edges.
1079 for (Node *CallTarget : PromotedRefTargets) {
1080 SCC &TargetC = *G.lookupSCC(*CallTarget);
1081 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1082
1083 // The easy case is when the target RefSCC is not this RefSCC. This is
1084 // only supported when the target RefSCC is a child of this RefSCC.
1085 if (&TargetRC != RC) {
1086#ifdef EXPENSIVE_CHECKS
1087 assert(RC->isAncestorOf(TargetRC) &&
1088 "Cannot potentially form RefSCC cycles here!");
1089#endif
1090 RC->switchOutgoingEdgeToCall(N, *CallTarget);
1091 LLVM_DEBUG(dbgs() << "Switch outgoing ref edge to a call edge from '" << N
1092 << "' to '" << *CallTarget << "'\n");
1093 continue;
1094 }
1095 LLVM_DEBUG(dbgs() << "Switch an internal ref edge to a call edge from '"
1096 << N << "' to '" << *CallTarget << "'\n");
1097
1098 // Otherwise we are switching an internal ref edge to a call edge. This
1099 // may merge away some SCCs, and we add those to the UpdateResult. We also
1100 // need to make sure to update the worklist in the event SCCs have moved
1101 // before the current one in the post-order sequence
1102 bool HasFunctionAnalysisProxy = false;
1103 auto InitialSCCIndex = RC->find(*C) - RC->begin();
1104 bool FormedCycle = RC->switchInternalEdgeToCall(
1105 N, *CallTarget, [&](ArrayRef<SCC *> MergedSCCs) {
1106 for (SCC *MergedC : MergedSCCs) {
1107 assert(MergedC != &TargetC && "Cannot merge away the target SCC!");
1108
1109 HasFunctionAnalysisProxy |=
1111 *MergedC) != nullptr;
1112
1113 // Mark that this SCC will no longer be valid.
1114 UR.InvalidatedSCCs.insert(MergedC);
1115
1116 // FIXME: We should really do a 'clear' here to forcibly release
1117 // memory, but we don't have a good way of doing that and
1118 // preserving the function analyses.
1119 auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
1120 PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1121 AM.invalidate(*MergedC, PA);
1122 }
1123 });
1124
1125 // If we formed a cycle by creating this call, we need to update more data
1126 // structures.
1127 if (FormedCycle) {
1128 C = &TargetC;
1129 assert(G.lookupSCC(N) == C && "Failed to update current SCC!");
1130
1131 // If one of the invalidated SCCs had a cached proxy to a function
1132 // analysis manager, we need to create a proxy in the new current SCC as
1133 // the invalidated SCCs had their functions moved.
1134 if (HasFunctionAnalysisProxy)
1136
1137 // Any analyses cached for this SCC are no longer precise as the shape
1138 // has changed by introducing this cycle. However, we have taken care to
1139 // update the proxies so it remains valide.
1140 auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
1141 PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
1142 AM.invalidate(*C, PA);
1143 }
1144 auto NewSCCIndex = RC->find(*C) - RC->begin();
1145 // If we have actually moved an SCC to be topologically "below" the current
1146 // one due to merging, we will need to revisit the current SCC after
1147 // visiting those moved SCCs.
1148 //
1149 // It is critical that we *do not* revisit the current SCC unless we
1150 // actually move SCCs in the process of merging because otherwise we may
1151 // form a cycle where an SCC is split apart, merged, split, merged and so
1152 // on infinitely.
1153 if (InitialSCCIndex < NewSCCIndex) {
1154 // Put our current SCC back onto the worklist as we'll visit other SCCs
1155 // that are now definitively ordered prior to the current one in the
1156 // post-order sequence, and may end up observing more precise context to
1157 // optimize the current SCC.
1158 UR.CWorklist.insert(C);
1159 LLVM_DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist: " << *C
1160 << "\n");
1161 // Enqueue in reverse order as we pop off the back of the worklist.
1162 for (SCC &MovedC : llvm::reverse(make_range(RC->begin() + InitialSCCIndex,
1163 RC->begin() + NewSCCIndex))) {
1164 UR.CWorklist.insert(&MovedC);
1165 LLVM_DEBUG(dbgs() << "Enqueuing a newly earlier in post-order SCC: "
1166 << MovedC << "\n");
1167 }
1168 }
1169 }
1170
1171 assert(!UR.InvalidatedSCCs.count(C) && "Invalidated the current SCC!");
1172 assert(&C->getOuterRefSCC() == RC && "Current SCC not in current RefSCC!");
1173
1174 // Record the current SCC for higher layers of the CGSCC pass manager now that
1175 // all the updates have been applied.
1176 if (C != &InitialC)
1177 UR.UpdatedC = C;
1178
1179 return *C;
1180}
1181
1186 return updateCGAndAnalysisManagerForPass(G, InitialC, N, AM, UR, FAM,
1187 /* FunctionPass */ true);
1188}
1193 return updateCGAndAnalysisManagerForPass(G, InitialC, N, AM, UR, FAM,
1194 /* FunctionPass */ false);
1195}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static LazyCallGraph::SCC & updateCGAndAnalysisManagerForPass(LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM, bool FunctionPass)
static LazyCallGraph::SCC * incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G, LazyCallGraph::Node &N, LazyCallGraph::SCC *C, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR)
Helper function to update both the CGSCCAnalysisManager AM and the CGSCCPassManager's CGSCCUpdateResu...
static void updateNewSCCFunctionAnalyses(LazyCallGraph::SCC &C, LazyCallGraph &G, CGSCCAnalysisManager &AM, FunctionAnalysisManager &FAM)
When a new SCC is created for the graph we first update the FunctionAnalysisManager in the Proxy's re...
This header provides classes for managing passes over SCCs of the call graph.
#define LLVM_EXPORT_TEMPLATE
Definition: Compiler.h:215
This header defines various interfaces for pass management in LLVM.
Implements a lazy call graph analysis and related passes for the new pass manager.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
#define P(N)
CGSCCAnalysisManager CGAM
Function const char * Passes
FunctionAnalysisManager FAM
Provides implementations for PassManager and AnalysisManager template methods.
This file provides a priority worklist.
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
#define LLVM_DEBUG(...)
Definition: Debug.h:119
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
Definition: Analysis.h:50
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:294
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Trigger the invalidation of some other analysis pass if not already handled and return whether it was...
Definition: PassManager.h:312
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:431
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
We need a specialized result for the CGSCCAnalysisManagerModuleProxy so it can have access to the cal...
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
Runs the function pass across every function in the module.
This class represents an Operation in the Expression.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
Runs the wrapped pass up to MaxIterations on the SCC, iterating whenever an indirect call is refined.
LLVM_ABI bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA, CGSCCAnalysisManager::Invalidator &Inv)
A proxy from a FunctionAnalysisManager to an SCC.
LLVM_ABI Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &)
Computes the FunctionAnalysisManager and stores it in the result proxy.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:585
Result run(IRUnitT &IR, AnalysisManager< IRUnitT, ExtraArgTs... > &AM, ExtraArgTs...)
Run the analysis pass and create our proxy result object.
Definition: PassManager.h:646
An analysis pass which computes the call graph for a module.
A class used to represent edges in the call graph.
A node in the call graph.
A RefSCC of the call graph.
An SCC of the call graph.
RefSCC & getOuterRefSCC() const
A lazily constructed view of the call graph of a module.
LLVM_ABI void buildRefSCCs()
static LLVM_ABI void visitReferences(SmallVectorImpl< Constant * > &Worklist, SmallPtrSetImpl< Constant * > &Visited, function_ref< void(Function &)> Callback)
Recursively visits the defined functions whose address is reachable from every constant in the Workli...
LLVM_ABI void removeDeadFunctions(ArrayRef< Function * > DeadFs)
Remove dead functions from the call graph.
SCC * lookupSCC(Node &N) const
Lookup a function's SCC in the graph.
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
void verify()
Verify that every RefSCC is valid.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Runs the CGSCC pass across every SCC in the module.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
Definition: PassManager.h:716
Pseudo-analysis pass that exposes the PassInstrumentation to pass managers.
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
void runAfterPassInvalidated(const PassT &Pass, const PreservedAnalyses &PA) const
AfterPassInvalidated instrumentation point - takes Pass instance that has just been executed.
void runAfterPass(const PassT &Pass, const IRUnitT &IR, const PreservedAnalyses &PA) const
AfterPass instrumentation point - takes Pass instance that has just been executed and constant refere...
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const
BeforePass instrumentation point - takes Pass instance to be executed and constant reference to IR it...
Manages a sequence of passes over a particular unit of IR.
Definition: PassManager.h:163
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:99
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:115
bool areAllPreserved() const
Test whether all analyses are preserved (and none are abandoned).
Definition: Analysis.h:292
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition: Analysis.h:171
bool allAnalysesInSetPreserved() const
Directly test whether a set of analyses is preserved.
Definition: Analysis.h:300
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition: Analysis.h:151
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
Definition: Analysis.h:193
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition: Analysis.h:132
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition: Analysis.h:275
bool empty() const
Determine if the PriorityWorklist is empty or not.
bool insert(const T &X)
Insert a new element into the PriorityWorklist.
void insert_range(Range &&R)
Definition: SetVector.h:193
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition: DenseSet.h:283
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:470
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
LLVM Value Representation.
Definition: Value.h:75
Value handle that is nullable, but tries to track the Value.
Definition: ValueHandle.h:205
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
LLVM_ABI LazyCallGraph::SCC & updateCGAndAnalysisManagerForFunctionPass(LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
Helper to update the call graph after running a function pass.
LLVM_ABI LazyCallGraph::SCC & updateCGAndAnalysisManagerForCGSCCPass(LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM)
Helper to update the call graph after running a CGSCC pass.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:663
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1751
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:2139
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition: iterator.h:363
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition: MIRParser.h:39
static cl::opt< bool > AbortOnMaxDevirtIterationsReached("abort-on-max-devirt-iterations-reached", cl::desc("Abort when the max iterations for devirtualization CGSCC repeat " "pass is reached"))
#define N
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:29
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
SmallMapVector< Value *, WeakTrackingVH, 16 > IndirectVHs
Weak VHs to keep track of indirect calls for the purposes of detecting devirtualization.
SmallPriorityWorklist< LazyCallGraph::SCC *, 1 > & CWorklist
Worklist of the SCCs queued for processing.
SmallPtrSetImpl< LazyCallGraph::SCC * > & InvalidatedSCCs
The set of invalidated SCCs which should be skipped if they are found in CWorklist.
LazyCallGraph::SCC * UpdatedC
If non-null, the updated current SCC being processed.
PreservedAnalyses CrossSCCPA
Preserved analyses across SCCs.
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:249