LLVM: lib/Analysis/CGSCCPassManager.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
31#include
32#include
33
34#define DEBUG_TYPE "cgscc"
35
36using namespace llvm;
37
38STATISTIC(LargestCGSCC, "Number of functions in the largest SCC");
39
40
41
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
62
63
64
65template <>
71
72
75
77
78
79
81
82
85
87
88
90 continue;
91
92 LargestCGSCC.updateMax(C->size());
93
95
96
99
100 auto *ResultFAMCP =
102 ResultFAMCP->updateFAM(FAM);
103 }
104
105
106
107 PA.intersect(PassPA);
108
109
110
113 LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
114 break;
115 }
116
117
118 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
119
120
121
123
125 }
126
127
128
129
130
132
133
134
135
136
138
139 return PA;
140}
141
144
146 AM.getResult(M).getManager();
147
148
150
151
154
155
156
159
160
161
163
165 InlinedInternalEdges;
166
168
170 InvalidSCCSet,
171 nullptr,
173 InlinedInternalEdges,
174 DeadFunctions,
175 {}};
176
177
178
180
186 "Should always start with an empty RefSCC worklist");
187
188
189
190
191
192
193
194
195
196
197
198 RCWorklist.insert(&RC);
199
200 do {
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
209
210
211
213
214
215
218
219 do {
221
222
223
224
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
234
235
236
237
238
239
240
241
242
243
244
245
246
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
266
267 do {
268
269 assert(!InvalidSCCSet.count(C) && "Processing an invalid SCC!");
270 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
271
274
275
276
277
279 continue;
280
282
283
285
287
288
291 }
292
293
294
296
297
298 PA.intersect(PassPA);
299
300
301
304 LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
305 break;
306 }
307
308
309 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
310
311
312
313
314
315
316
317 CGAM.invalidate(*C, PassPA);
318
320
321
322
323
324
325
326
327
328
329
332 << "Re-running SCC passes after a refinement of the "
333 "current SCC: "
335
336
337
338
340 } while (!CWorklist.empty());
341
342
343
344
345 InlinedInternalEdges.clear();
346 } while (!RCWorklist.empty());
347 }
348
350 for (Function *DeadF : DeadFunctions)
351 DeadF->eraseFromParent();
352
353#if defined(EXPENSIVE_CHECKS)
354
356#endif
357
358
359
362 PA.preserve();
364 return PA;
365}
366
374
375
376
378
379
380
381 struct CallCount {
382 int Direct;
383 int Indirect;
384 };
385
386
387
390 assert(CallHandles.empty() && "Must start with a clear set of handles.");
391
393 CallCount CountLocal = {0, 0};
395 CallCount &Count =
396 CallCounts.insert(std::make_pair(&N.getFunction(), CountLocal))
397 .first->second;
400 if (CB->getCalledFunction()) {
402 } else {
403 ++Count.Indirect;
405 }
406 }
407 }
408
409 return CallCounts;
410 };
411
413
414 auto CallCounts = ScanSCC(*C, UR.IndirectVHs);
415
416 for (int Iteration = 0;; ++Iteration) {
418 continue;
419
421
423
424
425
428 LLVM_DEBUG(dbgs() << "Skipping invalidated root or island SCC!\n");
429 break;
430 }
431
432
433
435
437
438
439
441 break;
442
443 assert(C->begin() != C->end() && "Cannot have an empty SCC!");
444
445
447 if (P.second) {
448 if (CallBase *CB = dyn_cast(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
459
460
462 auto NewCallCounts = ScanSCC(*C, UR.IndirectVHs);
463
464
465
466
467
468
469 if (!Devirt)
470
471
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
490 if (Iteration >= MaxIterations) {
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
505 CallCounts = std::move(NewCallCounts);
506 }
507
508
509
510
511 return PA;
512}
513
518
521
523
524
525
526
528
529 LLVM_DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n");
530
533
534
535
537 continue;
538
540
542 continue;
543
546 continue;
547
549
550
551
552
554
556
557
558
560
561
562
563
567 AM, UR, FAM);
569 "Current SCC not updated to the SCC containing the current node!");
570 }
571 }
572
573
574
575
576
579
580
582
583 return PA;
584}
585
586bool CGSCCAnalysisManagerModuleProxy::Result::invalidate(
588 ModuleAnalysisManager::Invalidator &Inv) {
589
591 return false;
592
593
594
595
596
597
598
599
600
601 auto PAC = PA.getChecker();
605 InnerAM->clear();
606
607
608
609
610 return true;
611 }
612
613
614
615 bool AreSCCAnalysesPreserved =
617
618
619 G->buildRefSCCs();
620 for (auto &RC : G->postorder_ref_sccs())
621 for (auto &C : RC) {
622 std::optional InnerPA;
623
624
625
626
627 if (auto *OuterProxy =
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
642
643 if (InnerPA) {
644 InnerAM->invalidate(C, *InnerPA);
645 continue;
646 }
647
648
649
650 if (!AreSCCAnalysesPreserved)
651 InnerAM->invalidate(C, PA);
652 }
653
654
655 return false;
656}
657
658template <>
659CGSCCAnalysisManagerModuleProxy::Result
661
662
663
664
666
668}
669
670AnalysisKey FunctionAnalysisManagerCGSCCProxy::Key;
671
676
677
678
680 Module &M = *C.begin()->getFunction().getParent();
681 bool ProxyExists =
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
689
690
692}
693
696 CGSCCAnalysisManager::Invalidator &Inv) {
697
699 return false;
700
701
702
703
704
705
706
707
708
712 FAM->invalidate(N.getFunction(), PA);
713
714 return false;
715 }
716
717
718 bool AreFunctionAnalysesPreserved =
720
721
722
725 std::optional FunctionPA;
726
727
728
729
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
745
746 if (FunctionPA) {
747 FAM->invalidate(F, *FunctionPA);
748 continue;
749 }
750
751
752
753 if (!AreFunctionAnalysesPreserved)
754 FAM->invalidate(F, PA);
755 }
756
757
758 return false;
759}
760
761}
762
763
764
765
766
767
768
769
770
771
772
773
774
775
781
782
783
786
787 auto *OuterProxy =
789 if (!OuterProxy)
790
791 continue;
792
793
794
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
805 }
806}
807
808
809
810
811
812
813
814
815
816
817
818template
819static LazyCallGraph::SCC *
824
825 if (NewSCCRange.empty())
826 return C;
827
828
830 LLVM_DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist:" << *C
831 << "\n");
832
833 SCC *OldC = C;
834
835
836
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
843
845 if (auto *FAMProxy =
847 FAM = &FAMProxy->getManager();
848
849
850
851
852
853
854
855
859
860
863
865 assert(C != &NewC && "No need to re-visit the current SCC!");
866 assert(OldC != &NewC && "Already handled the original SCC!");
868 LLVM_DEBUG(dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n");
869
870
873
874
875
877 }
878 return C;
879}
880
889
891 SCC *C = &InitialC;
892 RefSCC *RC = &InitialRC;
894
895
896
904
905
906
907
910 if (Function *Callee = CB->getCalledFunction()) {
911 if (Visited.insert(Callee).second && !Callee->isDeclaration()) {
912 Node *CalleeN = G.lookup(*Callee);
914 "Visited function should already have an associated node");
915 Edge *E = N->lookup(*CalleeN);
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 ()
924 NewCallEdges.insert(CalleeN);
925 else if (->isCall())
926 PromotedRefTargets.insert(CalleeN);
927 }
928 } else {
929
930
934 else if (!Entry->second)
936 }
937 }
938 }
939
940
942 for (Value *Op : I.operand_values())
944 if (Visited.insert(OpC).second)
946
947 auto VisitRef = [&](Function &Referee) {
948 Node *RefereeN = G.lookup(Referee);
950 "Visited function should already have an associated node");
951 Edge *E = N->lookup(*RefereeN);
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 ()
960 NewRefEdges.insert(RefereeN);
961 else if (E->isCall())
962 DemotedCallTargets.insert(RefereeN);
963 };
965
966
967 for (Node *RefTarget : NewRefEdges) {
968 SCC &TargetC = *G.lookupSCC(*RefTarget);
969 RefSCC &TargetRC = TargetC.getOuterRefSCC();
970 (void)TargetRC;
971
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
980 for (Node *CallTarget : NewCallEdges) {
981 SCC &TargetC = *G.lookupSCC(*CallTarget);
982 RefSCC &TargetRC = TargetC.getOuterRefSCC();
983 (void)TargetRC;
984
985#ifdef EXPENSIVE_CHECKS
986 assert((RC == &TargetRC ||
987 RC->isAncestorOf(TargetRC)) && "New call edge is not trivial!");
988#endif
989
990
991 RC->insertTrivialRefEdge(N, *CallTarget);
992 }
993
994
995 for (auto *LibFn : G.getLibFunctions())
996
997
998 if (!Visited.count(LibFn))
999 VisitRef(*LibFn);
1000
1001
1002
1003
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
1014 RC->switchTrivialInternalEdgeToRef(N, E.getNode());
1015 } else {
1016
1019 }
1020 }
1021
1022
1023 DeadTargets.push_back(&E.getNode());
1024 }
1025
1027 SCC &TargetC = *G.lookupSCC(*TargetN);
1028 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1029
1030
1031
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
1042
1043
1044 for (Node *RefTarget : DemotedCallTargets) {
1045 SCC &TargetC = *G.lookupSCC(*RefTarget);
1046 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1047
1048
1049
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
1062
1063 if (C != &TargetC) {
1064
1065 RC->switchTrivialInternalEdgeToRef(N, *RefTarget);
1066 continue;
1067 }
1068
1069
1071 C, AM, UR);
1072 }
1073
1074
1075
1076 PromotedRefTargets.insert_range(NewCallEdges);
1077
1078
1079 for (Node *CallTarget : PromotedRefTargets) {
1080 SCC &TargetC = *G.lookupSCC(*CallTarget);
1081 RefSCC &TargetRC = TargetC.getOuterRefSCC();
1082
1083
1084
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
1099
1100
1101
1102 bool HasFunctionAnalysisProxy = false;
1103 auto InitialSCCIndex = RC->find(*C) - RC->begin();
1104 bool FormedCycle = RC->switchInternalEdgeToCall(
1106 for (SCC *MergedC : MergedSCCs) {
1107 assert(MergedC != &TargetC && "Cannot merge away the target SCC!");
1108
1109 HasFunctionAnalysisProxy |=
1111 *MergedC) != nullptr;
1112
1113
1115
1116
1117
1118
1122 }
1123 });
1124
1125
1126
1127 if (FormedCycle) {
1128 C = &TargetC;
1129 assert(G.lookupSCC(N) == C && "Failed to update current SCC!");
1130
1131
1132
1133
1134 if (HasFunctionAnalysisProxy)
1136
1137
1138
1139
1143 }
1144 auto NewSCCIndex = RC->find(*C) - RC->begin();
1145
1146
1147
1148
1149
1150
1151
1152
1153 if (InitialSCCIndex < NewSCCIndex) {
1154
1155
1156
1157
1159 LLVM_DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist: " << *C
1160 << "\n");
1161
1163 RC->begin() + NewSCCIndex))) {
1165 LLVM_DEBUG(dbgs() << "Enqueuing a newly earlier in post-order SCC: "
1166 << MovedC << "\n");
1167 }
1168 }
1169 }
1170
1172 assert(&C->getOuterRefSCC() == RC && "Current SCC not in current RefSCC!");
1173
1174
1175
1176 if (C != &InitialC)
1178
1179 return *C;
1180}
1181
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static LazyCallGraph::SCC & updateCGAndAnalysisManagerForPass(LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, FunctionAnalysisManager &FAM, bool FunctionPass)
Definition CGSCCPassManager.cpp:881
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...
Definition CGSCCPassManager.cpp:820
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...
Definition CGSCCPassManager.cpp:776
This header provides classes for managing passes over SCCs of the call graph.
#define LLVM_EXPORT_TEMPLATE
This header defines various interfaces for pass management in LLVM.
Implements a lazy call graph analysis and related passes for the new pass manager.
CGSCCAnalysisManager CGAM
FunctionAnalysisManager FAM
Provides implementations for PassManager and AnalysisManager template methods.
This file provides a priority worklist.
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)
This templated class represents "all analyses that operate over " (e....
A container for analyses that lazily runs them and caches their results.
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.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
Definition CGSCCPassManager.cpp:514
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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.
Definition CGSCCPassManager.cpp:367
LLVM_ABI bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA, CGSCCAnalysisManager::Invalidator &Inv)
Definition CGSCCPassManager.cpp:694
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.
Definition CGSCCPassManager.cpp:673
FunctionPass class - This class is used to implement most global optimizations.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Result run(Module &IR, AnalysisManager< Module, ExtraArgTs... > &AM, ExtraArgTs...)
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.
Definition CGSCCPassManager.cpp:143
A Module instance is used to store all the information related to an LLVM module.
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
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.
std::vector< std::unique_ptr< PassConceptT > > Passes
PreservedAnalyses run(LazyCallGraph::SCC &IR, CGSCCAnalysisManager &AM, ExtraArgTs... ExtraArgs)
Pass interface - Implemented by all 'passes'.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
bool areAllPreserved() const
Test whether all analyses are preserved (and none are abandoned).
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool allAnalysesInSetPreserved() const
Directly test whether a set of analyses is preserved.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
static PreservedAnalyses allInSet()
Construct a preserved analyses object with a single preserved set.
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)
bool insert(const value_type &X)
Insert a new element into the SetVector.
static LLVM_ABI AnalysisKey Key
Implements a dense probed hash-table based set with some number of buckets stored inline.
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.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
Value handle that is nullable, but tries to track the Value.
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.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
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.
Definition CGSCCPassManager.cpp:1182
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.
Definition CGSCCPassManager.cpp:1189
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...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
DWARFExpression::Operation Op
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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"))
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
A special type used by analysis passes to provide an address that identifies that particular analysis...
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.