llvm.org GIT mirror llvm / e6959a6
[New PM] Introducing PassInstrumentation framework Pass Execution Instrumentation interface enables customizable instrumentation of pass execution, as per "RFC: Pass Execution Instrumentation interface" posted 06/07/2018 on llvm-dev@ The intent is to provide a common machinery to implement all the pass-execution-debugging features like print-before/after, opt-bisect, time-passes etc. Here we get a basic implementation consisting of: * PassInstrumentationCallbacks class that handles registration of callbacks and access to them. * PassInstrumentation class that handles instrumentation-point interfaces that call into PassInstrumentationCallbacks. * Callbacks accept StringRef which is just a name of the Pass right now. There were some ideas to pass an opaque wrapper for the pointer to pass instance, however it appears that pointer does not actually identify the instance (adaptors and managers might have the same address with the pass they govern). Hence it was decided to go simple for now and then later decide on what the proper mental model of identifying a "pass in a phase of pipeline" is. * Callbacks accept llvm::Any serving as a wrapper for const IRUnit*, to remove direct dependencies on different IRUnits (e.g. Analyses). * PassInstrumentationAnalysis analysis is explicitly requested from PassManager through usual AnalysisManager::getResult. All pass managers were updated to run that to get PassInstrumentation object for instrumentation calls. * Using tuples/index_sequence getAnalysisResult helper to extract generic AnalysisManager's extra args out of a generic PassManager's extra args. This is the only way I was able to explicitly run getResult for PassInstrumentationAnalysis out of a generic code like PassManager::run or RepeatedPass::run. TODO: Upon lengthy discussions we agreed to accept this as an initial implementation and then get rid of getAnalysisResult by improving RepeatedPass implementation. * PassBuilder takes PassInstrumentationCallbacks object to pass it further into PassInstrumentationAnalysis. Callbacks registration should be performed directly through PassInstrumentationCallbacks. * new-pm tests updated to account for PassInstrumentationAnalysis being run * Added PassInstrumentation tests to PassBuilderCallbacks unit tests. Other unit tests updated with registration of the now-required PassInstrumentationAnalysis. Made getName helper to return std::string (instead of StringRef initially) to fix asan builtbot failures on CGSCC tests. Reviewers: chandlerc, philip.pfaffe Differential Revision: https://reviews.llvm.org/D47858 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@342664 91177308-0d34-0410-b5e6-96231b3b80d8 Fedor Sergeev a year ago
22 changed file(s) with 733 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
362362 CGSCCUpdateResult UR = {RCWorklist, CWorklist, InvalidRefSCCSet,
363363 InvalidSCCSet, nullptr, nullptr,
364364 InlinedInternalEdges};
365
366 // Request PassInstrumentation from analysis manager, will use it to run
367 // instrumenting callbacks for the passes later.
368 PassInstrumentation PI = AM.getResult(M);
365369
366370 PreservedAnalyses PA = PreservedAnalyses::all();
367371 CG.buildRefSCCs();
427431
428432 UR.UpdatedRC = nullptr;
429433 UR.UpdatedC = nullptr;
434
435 // Check the PassInstrumentation's BeforePass callbacks before
436 // running the pass, skip its execution completely if asked to
437 // (callback returns false).
438 if (!PI.runBeforePass(Pass, *C))
439 continue;
440
430441 PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR);
442
443 PI.runAfterPass(Pass, *C);
431444
432445 // Update the SCC and RefSCC if necessary.
433446 C = UR.UpdatedC ? UR.UpdatedC : C;
614627 if (CG.lookupSCC(*N) != CurrentC)
615628 continue;
616629
617 PreservedAnalyses PassPA = Pass.run(N->getFunction(), FAM);
630 Function &F = N->getFunction();
631
632 PassInstrumentation PI = FAM.getResult(F);
633 if (!PI.runBeforePass(Pass, F))
634 continue;
635
636 PreservedAnalyses PassPA = Pass.run(F, FAM);
637
638 PI.runAfterPass(Pass, F);
618639
619640 // We know that the function pass couldn't have invalidated any other
620641 // function's analyses (that's the contract of a function pass), so
621642 // directly handle the function analysis manager's invalidation here.
622 FAM.invalidate(N->getFunction(), PassPA);
643 FAM.invalidate(F, PassPA);
623644
624645 // Then intersect the preserved set so that invalidation of module
625646 // analyses will eventually occur when the module pass completes.
689710 PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM,
690711 LazyCallGraph &CG, CGSCCUpdateResult &UR) {
691712 PreservedAnalyses PA = PreservedAnalyses::all();
713 PassInstrumentation PI =
714 AM.getResult(InitialC, CG);
692715
693716 // The SCC may be refined while we are running passes over it, so set up
694717 // a pointer that we can update.
732755 auto CallCounts = ScanSCC(*C, CallHandles);
733756
734757 for (int Iteration = 0;; ++Iteration) {
758
759 if (!PI.runBeforePass(Pass, *C))
760 continue;
761
735762 PreservedAnalyses PassPA = Pass.run(*C, AM, CG, UR);
763
764 PI.runAfterPass(Pass, *C);
736765
737766 // If the SCC structure has changed, bail immediately and let the outer
738767 // CGSCC layer handle any iteration to reflect the refined structure.
0 //===- llvm/IR/PassInstrumentation.h ----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file defines the Pass Instrumentation classes that provide
11 /// instrumentation points into the pass execution by PassManager.
12 ///
13 /// There are two main classes:
14 /// - PassInstrumentation provides a set of instrumentation points for
15 /// pass managers to call on.
16 ///
17 /// - PassInstrumentationCallbacks registers callbacks and provides access
18 /// to them for PassInstrumentation.
19 ///
20 /// PassInstrumentation object is being used as a result of
21 /// PassInstrumentationAnalysis (so it is intended to be easily copyable).
22 ///
23 /// Intended scheme of use for Pass Instrumentation is as follows:
24 /// - register instrumentation callbacks in PassInstrumentationCallbacks
25 /// instance. PassBuilder provides helper for that.
26 ///
27 /// - register PassInstrumentationAnalysis with all the PassManagers.
28 /// PassBuilder handles that automatically when registering analyses.
29 ///
30 /// - Pass Manager requests PassInstrumentationAnalysis from analysis manager
31 /// and gets PassInstrumentation as its result.
32 ///
33 /// - Pass Manager invokes PassInstrumentation entry points appropriately,
34 /// passing StringRef identification ("name") of the pass currently being
35 /// executed and IRUnit it works on. There can be different schemes of
36 /// providing names in future, currently it is just a name() of the pass.
37 ///
38 /// - PassInstrumentation wraps address of IRUnit into llvm::Any and passes
39 /// control to all the registered callbacks. Note that we specifically wrap
40 /// 'const IRUnitT*' so as to avoid any accidental changes to IR in
41 /// instrumenting callbacks.
42 ///
43 /// - Some instrumentation points (BeforePass) allow to control execution
44 /// of a pass. For those callbacks returning false means pass will not be
45 /// executed.
46 ///
47 /// TODO: currently there is no way for a pass to opt-out of execution control
48 /// (e.g. become unskippable). PassManager is the only entity that determines
49 /// how pass instrumentation affects pass execution.
50 ///
51 //===----------------------------------------------------------------------===//
52
53 #ifndef LLVM_IR_PASSINSTRUMENTATION_H
54 #define LLVM_IR_PASSINSTRUMENTATION_H
55
56 #include "llvm/ADT/Any.h"
57 #include "llvm/ADT/FunctionExtras.h"
58 #include "llvm/ADT/SmallVector.h"
59 #include "llvm/Support/TypeName.h"
60 #include
61
62 namespace llvm {
63
64 class PreservedAnalyses;
65
66 /// This class manages callbacks registration, as well as provides a way for
67 /// PassInstrumentation to pass control to the registered callbacks.
68 class PassInstrumentationCallbacks {
69 public:
70 // Before/After Pass callbacks accept IRUnits, so they need to take them
71 // as pointers, wrapped with llvm::Any
72 using BeforePassFunc = bool(StringRef, Any);
73 using AfterPassFunc = void(StringRef, Any);
74 using BeforeAnalysisFunc = void(StringRef, Any);
75 using AfterAnalysisFunc = void(StringRef, Any);
76
77 public:
78 PassInstrumentationCallbacks() {}
79
80 /// Copying PassInstrumentationCallbacks is not intended.
81 PassInstrumentationCallbacks(const PassInstrumentationCallbacks &) = delete;
82 void operator=(const PassInstrumentationCallbacks &) = delete;
83
84 template void registerBeforePassCallback(CallableT C) {
85 BeforePassCallbacks.emplace_back(std::move(C));
86 }
87
88 template void registerAfterPassCallback(CallableT C) {
89 AfterPassCallbacks.emplace_back(std::move(C));
90 }
91
92 private:
93 friend class PassInstrumentation;
94
95 SmallVector, 4> BeforePassCallbacks;
96 SmallVector, 4> AfterPassCallbacks;
97 };
98
99 /// This class provides instrumentation entry points for the Pass Manager,
100 /// doing calls to callbacks registered in PassInstrumentationCallbacks.
101 class PassInstrumentation {
102 PassInstrumentationCallbacks *Callbacks;
103
104 public:
105 /// Callbacks object is not owned by PassInstrumentation, its life-time
106 /// should at least match the life-time of corresponding
107 /// PassInstrumentationAnalysis (which usually is till the end of current
108 /// compilation).
109 PassInstrumentation(PassInstrumentationCallbacks *CB = nullptr)
110 : Callbacks(CB) {}
111
112 /// BeforePass instrumentation point - takes \p Pass instance to be executed
113 /// and constant reference to IR it operates on. \Returns true if pass is
114 /// allowed to be executed.
115 template
116 bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const {
117 if (!Callbacks)
118 return true;
119
120 bool ShouldRun = true;
121 for (auto &C : Callbacks->BeforePassCallbacks)
122 ShouldRun &= C(Pass.name(), llvm::Any(&IR));
123 return ShouldRun;
124 }
125
126 /// AfterPass instrumentation point - takes \p Pass instance that has
127 /// just been executed and constant reference to IR it operates on.
128 template
129 void runAfterPass(const PassT &Pass, const IRUnitT &IR) const {
130 if (Callbacks)
131 for (auto &C : Callbacks->AfterPassCallbacks)
132 C(Pass.name(), llvm::Any(&IR));
133 }
134
135 /// Handle invalidation from the pass manager when PassInstrumentation
136 /// is used as the result of PassInstrumentationAnalysis.
137 ///
138 /// On attempt to invalidate just return false. There is nothing to become
139 /// invalid here.
140 template
141 bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &,
142 ExtraArgsT...) {
143 return false;
144 }
145 };
146
147 } // namespace llvm
148
149 #endif
4343 #include "llvm/ADT/TinyPtrVector.h"
4444 #include "llvm/IR/Function.h"
4545 #include "llvm/IR/Module.h"
46 #include "llvm/IR/PassInstrumentation.h"
4647 #include "llvm/IR/PassManagerInternal.h"
4748 #include "llvm/Support/Debug.h"
4849 #include "llvm/Support/TypeName.h"
401402 }
402403 };
403404
405 namespace detail {
406
407 /// Actual unpacker of extra arguments in getAnalysisResult,
408 /// passes only those tuple arguments that are mentioned in index_sequence.
409 template
410 typename... ArgTs, size_t... Ns>
411 typename PassT::Result
412 getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR,
413 std::tuple Args,
414 llvm::index_sequence) {
415 (void)Args;
416 return AM.template getResult(IR, std::get(Args)...);
417 }
418
419 /// Helper for *partial* unpacking of extra arguments in getAnalysisResult.
420 ///
421 /// Arguments passed in tuple come from PassManager, so they might have extra
422 /// arguments after those AnalysisManager's ExtraArgTs ones that we need to
423 /// pass to getResult.
424 template
425 typename... MainArgTs>
426 typename PassT::Result
427 getAnalysisResult(AnalysisManager &AM, IRUnitT &IR,
428 std::tuple Args) {
429 return (getAnalysisResultUnpackTuple<
430 PassT, IRUnitT>)(AM, IR, Args,
431 llvm::index_sequence_for{});
432 }
433
434 } // namespace detail
435
436 // Forward declare the pass instrumentation analysis explicitly queried in
437 // generic PassManager code.
438 // FIXME: figure out a way to move PassInstrumentationAnalysis into its own
439 // header.
440 class PassInstrumentationAnalysis;
441
404442 /// Manages a sequence of passes over a particular unit of IR.
405443 ///
406444 /// A pass manager contains a sequence of passes to run over a particular unit
444482 ExtraArgTs... ExtraArgs) {
445483 PreservedAnalyses PA = PreservedAnalyses::all();
446484
485 // Request PassInstrumentation from analysis manager, will use it to run
486 // instrumenting callbacks for the passes later.
487 // Here we use std::tuple wrapper over getResult which helps to extract
488 // AnalysisManager's arguments out of the whole ExtraArgs set.
489 PassInstrumentation PI =
490 detail::getAnalysisResult(
491 AM, IR, std::tuple(ExtraArgs...));
492
447493 if (DebugLogging)
448494 dbgs() << "Starting " << getTypeName() << " pass manager run.\n";
449495
450496 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
497 auto *P = Passes[Idx].get();
451498 if (DebugLogging)
452 dbgs() << "Running pass: " << Passes[Idx]->name() << " on "
453 << IR.getName() << "\n";
454
455 PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM, ExtraArgs...);
499 dbgs() << "Running pass: " << P->name() << " on " << IR.getName()
500 << "\n";
501
502 // Check the PassInstrumentation's BeforePass callbacks before running the
503 // pass, skip its execution completely if asked to (callback returns
504 // false).
505 if (!PI.runBeforePass(*P, IR))
506 continue;
507
508 PreservedAnalyses PassPA = P->run(IR, AM, ExtraArgs...);
509
510 // Call onto PassInstrumentation's AfterPass callbacks immediately after
511 // running the pass.
512 PI.runAfterPass(*P, IR);
456513
457514 // Update the analysis manager as each pass runs and potentially
458515 // invalidates analyses.
508565
509566 /// Convenience typedef for a pass manager over functions.
510567 using FunctionPassManager = PassManager;
568
569 /// Pseudo-analysis pass that exposes the \c PassInstrumentation to pass
570 /// managers. Goes before AnalysisManager definition to provide its
571 /// internals (e.g PassInstrumentationAnalysis::ID) for use there if needed.
572 /// FIXME: figure out a way to move PassInstrumentationAnalysis into its own
573 /// header.
574 class PassInstrumentationAnalysis
575 : public AnalysisInfoMixin {
576 friend AnalysisInfoMixin;
577 static AnalysisKey Key;
578
579 PassInstrumentationCallbacks *Callbacks;
580
581 public:
582 /// PassInstrumentationCallbacks object is shared, owned by something else,
583 /// not this analysis.
584 PassInstrumentationAnalysis(PassInstrumentationCallbacks *Callbacks = nullptr)
585 : Callbacks(Callbacks) {}
586
587 using Result = PassInstrumentation;
588
589 template
590 Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
591 return PassInstrumentation(Callbacks);
592 }
593 };
511594
512595 /// A container for analyses that lazily runs them and caches their
513596 /// results.
11911274 FunctionAnalysisManager &FAM =
11921275 AM.getResult(M).getManager();
11931276
1277 // Request PassInstrumentation from analysis manager, will use it to run
1278 // instrumenting callbacks for the passes later.
1279 PassInstrumentation PI = AM.getResult(M);
1280
11941281 PreservedAnalyses PA = PreservedAnalyses::all();
11951282 for (Function &F : M) {
11961283 if (F.isDeclaration())
11971284 continue;
11981285
1286 // Check the PassInstrumentation's BeforePass callbacks before running the
1287 // pass, skip its execution completely if asked to (callback returns
1288 // false).
1289 if (!PI.runBeforePass(Pass, F))
1290 continue;
11991291 PreservedAnalyses PassPA = Pass.run(F, FAM);
1292
1293 PI.runAfterPass(Pass, F);
12001294
12011295 // We know that the function pass couldn't have invalidated any other
12021296 // function's analyses (that's the contract of a function pass), so
13011395 RepeatedPass(int Count, PassT P) : Count(Count), P(std::move(P)) {}
13021396
13031397 template
1304 PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, Ts &&... Args) {
1398 PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, Ts &&... Args) {
1399
1400 // Request PassInstrumentation from analysis manager, will use it to run
1401 // instrumenting callbacks for the passes later.
1402 // Here we use std::tuple wrapper over getResult which helps to extract
1403 // AnalysisManager's arguments out of the whole Args set.
1404 PassInstrumentation PI =
1405 detail::getAnalysisResult(
1406 AM, IR, std::tuple(Args...));
1407
13051408 auto PA = PreservedAnalyses::all();
1306 for (int i = 0; i < Count; ++i)
1307 PA.intersect(P.run(Arg, AM, std::forward(Args)...));
1409 for (int i = 0; i < Count; ++i) {
1410 // Check the PassInstrumentation's BeforePass callbacks before running the
1411 // pass, skip its execution completely if asked to (callback returns
1412 // false).
1413 if (!PI.runBeforePass(P, IR))
1414 continue;
1415 PA.intersect(P.run(IR, AM, std::forward(Args)...));
1416 PI.runAfterPass(P, IR);
1417 }
13081418 return PA;
13091419 }
13101420
5757 class PassBuilder {
5858 TargetMachine *TM;
5959 Optional PGOOpt;
60 PassInstrumentationCallbacks *PIC;
6061
6162 public:
6263 /// A struct to capture parsed pass pipeline names.
171172 };
172173
173174 explicit PassBuilder(TargetMachine *TM = nullptr,
174 Optional PGOOpt = None)
175 : TM(TM), PGOOpt(PGOOpt) {}
175 Optional PGOOpt = None,
176 PassInstrumentationCallbacks *PIC = nullptr)
177 : TM(TM), PGOOpt(PGOOpt), PIC(PIC) {}
176178
177179 /// Cross register the analysis managers through their proxies.
178180 ///
275275 // pass pipeline to put loops into their canonical form. Note that we can
276276 // directly build up function analyses after this as the function pass
277277 // manager handles all the invalidation at that layer.
278 PreservedAnalyses PA = LoopCanonicalizationFPM.run(F, AM);
278 PassInstrumentation PI = AM.getResult(F);
279
280 PreservedAnalyses PA = PreservedAnalyses::all();
281 // Check the PassInstrumentation's BeforePass callbacks before running the
282 // canonicalization pipeline.
283 if (PI.runBeforePass(LoopCanonicalizationFPM, F)) {
284 PA = LoopCanonicalizationFPM.run(F, AM);
285 PI.runAfterPass(LoopCanonicalizationFPM, F);
286 }
279287
280288 // Get the loop structure for this function
281289 LoopInfo &LI = AM.getResult(F);
336344 assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
337345 "Loops must remain in LCSSA form!");
338346 #endif
339
347 // Check the PassInstrumentation's BeforePass callbacks before running the
348 // pass, skip its execution completely if asked to (callback returns
349 // false).
350 if (!PI.runBeforePass(Pass, *L))
351 continue;
340352 PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
353
354 PI.runAfterPass(Pass, *L);
355
341356 // FIXME: We should verify the set of analyses relevant to Loop passes
342357 // are preserved.
343358
5353 CGSCCUpdateResult &>::run(LazyCallGraph::SCC &InitialC,
5454 CGSCCAnalysisManager &AM,
5555 LazyCallGraph &G, CGSCCUpdateResult &UR) {
56 // Request PassInstrumentation from analysis manager, will use it to run
57 // instrumenting callbacks for the passes later.
58 PassInstrumentation PI =
59 AM.getResult(InitialC, G);
60
5661 PreservedAnalyses PA = PreservedAnalyses::all();
5762
5863 if (DebugLogging)
6671 if (DebugLogging)
6772 dbgs() << "Running pass: " << Pass->name() << " on " << *C << "\n";
6873
74 // Check the PassInstrumentation's BeforePass callbacks before running the
75 // pass, skip its execution completely if asked to (callback returns false).
76 if (!PI.runBeforePass(*Pass, *C))
77 continue;
78
6979 PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR);
80
81 PI.runAfterPass(*Pass, *C);
7082
7183 // Update the SCC if necessary.
7284 C = UR.UpdatedC ? UR.UpdatedC : C;
7272 FPM.addPass(DCEPass());
7373 FunctionAnalysisManager FAM;
7474 FAM.registerPass([&] { return TargetLibraryAnalysis(); });
75 FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
7576 FPM.run(F, FAM);
7677 }
7778
4141 Operator.cpp
4242 OptBisect.cpp
4343 Pass.cpp
44 PassInstrumentation.cpp
4445 PassManager.cpp
4546 PassRegistry.cpp
4647 PassTimingInfo.cpp
0 //===- PassInstrumentation.cpp - Pass Instrumentation interface -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file provides the implementation of PassInstrumentation class.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/IR/PassInstrumentation.h"
15 #include "llvm/IR/PassManager.h"
16
17 namespace llvm {
18
19 AnalysisKey PassInstrumentationAnalysis::Key;
20
21 } // namespace llvm
2525 MODULE_ANALYSIS("profile-summary", ProfileSummaryAnalysis())
2626 MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
2727 MODULE_ANALYSIS("verify", VerifierAnalysis())
28 MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
2829
2930 #ifndef MODULE_ALIAS_ANALYSIS
3031 #define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
8384 #endif
8485 CGSCC_ANALYSIS("no-op-cgscc", NoOpCGSCCAnalysis())
8586 CGSCC_ANALYSIS("fam-proxy", FunctionAnalysisManagerCGSCCProxy())
87 CGSCC_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
8688 #undef CGSCC_ANALYSIS
8789
8890 #ifndef CGSCC_PASS
120122 FUNCTION_ANALYSIS("targetir",
121123 TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())
122124 FUNCTION_ANALYSIS("verify", VerifierAnalysis())
125 FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
123126
124127 #ifndef FUNCTION_ALIAS_ANALYSIS
125128 #define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
225228 LOOP_ANALYSIS("no-op-loop", NoOpLoopAnalysis())
226229 LOOP_ANALYSIS("access-info", LoopAccessAnalysis())
227230 LOOP_ANALYSIS("ivusers", IVUsersAnalysis())
231 LOOP_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
228232 #undef LOOP_ANALYSIS
229233
230234 #ifndef LOOP_PASS
2929 if (DebugLogging)
3030 dbgs() << "Starting Loop pass manager run.\n";
3131
32 // Request PassInstrumentation from analysis manager, will use it to run
33 // instrumenting callbacks for the passes later.
34 PassInstrumentation PI = AM.getResult(L, AR);
3235 for (auto &Pass : Passes) {
3336 if (DebugLogging)
3437 dbgs() << "Running pass: " << Pass->name() << " on " << L;
3538
39 // Check the PassInstrumentation's BeforePass callbacks before running the
40 // pass, skip its execution completely if asked to (callback returns false).
41 if (!PI.runBeforePass(*Pass, L))
42 continue;
43
3644 PreservedAnalyses PassPA = Pass->run(L, AM, AR, U);
45
46 PI.runAfterPass(*Pass, L);
3747
3848 // If the loop was deleted, abort the run and return to the outer walk.
3949 if (U.skipCurrentLoop()) {
7272 ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis
7373 ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
7474 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
75 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
7576 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
7677 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
7778 ; CHECK-LOOP-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}LoopAnalysis
8990 ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
9091 ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
9192 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
93 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
9294 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
9395 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
9496 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run.
107109 ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis
108110 ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
109111 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
112 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
110113 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
111114 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
112115 ; CHECK-SCEV-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
122125 ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
123126 ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
124127 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
128 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
125129 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
126130 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
127131 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run.
152156 ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis
153157 ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
154158 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
155 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
156 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
157 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
159 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
160 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
161 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
162 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
163 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
158164 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
159165 ; CHECK-LOOP-INV: Finished {{.*}}Loop pass manager run.
160166 ; CHECK-LOOP-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}LoopAnalysis
173179 ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
174180 ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
175181 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
176 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
177 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
178 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
182 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
183 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
184 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
185 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
186 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
179187 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
180188 ; CHECK-LOOP-INV: Finished {{.*}}Loop pass manager run.
181189 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run.
194202 ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis
195203 ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
196204 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
197 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
198 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
199 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
205 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
206 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
207 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
208 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
209 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
200210 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
201211 ; CHECK-SCEV-INV: Finished {{.*}}Loop pass manager run.
202212 ; CHECK-SCEV-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
213223 ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
214224 ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
215225 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
216 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
217 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
218 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
226 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
227 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
228 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
229 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
230 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
219231 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
220232 ; CHECK-SCEV-INV: Finished {{.*}}Loop pass manager run.
221233 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run.
253265 ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis
254266 ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
255267 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
268 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
256269 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
257270 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
258271 ; CHECK-LOOP-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}LoopAnalysis
270283 ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
271284 ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
272285 ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run.
286 ; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis
273287 ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass
274288 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run.
275289 ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run.
288302 ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis
289303 ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
290304 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
305 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
291306 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
292307 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
293308 ; CHECK-SCEV-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
303318 ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis
304319 ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
305320 ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run.
321 ; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis
306322 ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass
307323 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run.
308324 ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run.
321337 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: TargetIRAnalysis
322338 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop
323339 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Starting {{.*}}Loop pass manager run.
340 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: PassInstrumentationAnalysis
324341 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: NoOpLoopPass
325342 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: LoopDeletionPass
326343 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Clearing all analysis results for:
2323 ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
2424 ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
2525 ; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
26 ; CHECK-CGSCC-PASS-NEXT: Running analysis: PassInstrumentationAnalysis
2627 ; CHECK-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
2728 ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
2829 ; CHECK-CGSCC-PASS-NEXT: Finished CGSCC pass manager run
3738 ; CHECK-FUNCTION-PASS: Starting llvm::Module pass manager run
3839 ; CHECK-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor
3940 ; CHECK-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
41 ; CHECK-FUNCTION-PASS-NEXT: Running analysis: PassInstrumentationAnalysis
4042 ; CHECK-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
4143 ; CHECK-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
4244 ; CHECK-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
407409 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
408410 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
409411 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
412 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: PassInstrumentationAnalysis
410413 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
411414 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatedPass
412415 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
427430 ; CHECK-REPEAT-FUNCTION-PASS: Starting llvm::Module pass manager run
428431 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor
429432 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
433 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: PassInstrumentationAnalysis
430434 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
431435 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: RepeatedPass
432436 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
447451 ; CHECK-REPEAT-LOOP-PASS: Starting llvm::Module pass manager run
448452 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor
449453 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
454 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: PassInstrumentationAnalysis
450455 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run
451456 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: FunctionToLoopPassAdaptor
452457 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run
463468 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetIRAnalysis
464469 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
465470 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run
471 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: PassInstrumentationAnalysis
466472 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: RepeatedPass
467473 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run
468474 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass
6666 ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
6767 ; RUN: --check-prefix=CHECK-EP-PIPELINE-START
6868
69 ; CHECK-O: Starting llvm::Module pass manager run.
69 ; CHECK-O: Running analysis: PassInstrumentationAnalysis
70 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
7071 ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}>
7172 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
7273 ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass
7778 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
7879 ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
7980 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
81 ; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
8082 ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
8183 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
8284 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
109111 ; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}>
110112 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
111113 ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
114 ; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
112115 ; CHECK-O-NEXT: Starting CGSCC pass manager run.
113116 ; CHECK-O-NEXT: Running pass: InlinerPass
114117 ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
148151 ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
149152 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
150153 ; CHECK-O-NEXT: Starting Loop pass manager run.
154 ; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
151155 ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass
152156 ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass
153157 ; CHECK-O-NEXT: Running pass: LoopRotatePass
2222 ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 \
2323 ; RUN: --check-prefix=CHECK-O3 --check-prefix=CHECK-EP-Peephole
2424
25 ; CHECK-O: Starting llvm::Module pass manager run.
25 ; CHECK-O: Running analysis: PassInstrumentationAnalysis
26 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
2627 ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module
2728 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
2829 ; CHECK-O-NEXT: Running pass: GlobalDCEPass
3132 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
3233 ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
3334 ; CHECK-O2-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Module
35 ; CHECK-O2-NEXT: Running analysis: PassInstrumentationAnalysis
3436 ; CHECK-O2-NEXT: Starting llvm::Function pass manager run.
3537 ; CHECK-O2-NEXT: Running pass: CallSiteSplittingPass on foo
3638 ; CHECK-O2-NEXT: Running analysis: TargetLibraryAnalysis on foo
4646 ; RUN: -passes='thinlto' -S %s 2>&1 \
4747 ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-POSTLINK-O,CHECK-POSTLINK-O2
4848 ;
49 ; CHECK-O: Starting llvm::Module pass manager run.
49 ; CHECK-O: Running analysis: PassInstrumentationAnalysis
50 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
5051 ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}>
5152 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
5253 ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass
6364 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
6465 ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
6566 ; CHECK-PRELINK-O-NODIS-NEXT: Running analysis: InnerAnalysisManagerProxy
67 ; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
6668 ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
6769 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
6870 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
9496 ; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}>
9597 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
9698 ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
99 ; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
97100 ; CHECK-O-NEXT: Starting CGSCC pass manager run.
98101 ; CHECK-O-NEXT: Running pass: InlinerPass
99102 ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
132135 ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis
133136 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
134137 ; CHECK-O-NEXT: Starting Loop pass manager run.
138 ; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
135139 ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass
136140 ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass
137141 ; CHECK-O-NEXT: Running pass: LoopRotatePass
3232 ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_g
3333 ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_g
3434 ; CHECK-NEXT: Finished llvm::Function pass manager run.
35 ; CHECK-NEXT: Starting llvm::Function pass manager run.
35 ; CHECK-NOT: Invalidating analysis:
36 ; CHECK: Starting llvm::Function pass manager run.
3637 ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_h
3738 ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_h
3839 ; CHECK-NEXT: Finished llvm::Function pass manager run.
2020 ; CHECK-NEXT: Running analysis: TargetIRAnalysis on f
2121 ; CHECK-NEXT: Running analysis: InnerAnalysisManagerProxy{{.*}} on f
2222 ; CHECK-NEXT: Starting Loop pass manager run.
23 ; CHECK-NEXT: Running analysis: PassInstrumentationAnalysis on bb
2324 ; CHECK-NEXT: Running pass: LoopRotatePass on Loop at depth 1 containing: %bb
,%bb4
2425 ; CHECK-NEXT: Folding loop latch bb4 into bb
2526 ; CHECK-NEXT: Invalidating all non-preserved analyses for: bb
230230 MAM.registerPass([&] { return TargetLibraryAnalysis(); });
231231 MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
232232 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
233
234 // Register required pass instrumentation analysis.
235 MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
236 CGAM.registerPass([&] { return PassInstrumentationAnalysis(); });
237 FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
238
239 // Cross-register proxies.
233240 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
234241 CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(); });
235242 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
66 //
77 //===----------------------------------------------------------------------===//
88
9 #include
910 #include
1011 #include
12 #include
1113 #include
1214 #include
1315 #include
1416 #include
17 #include
1518 #include
1619 #include
20 #include
1721 #include
1822 #include
1923
3135 }
3236
3337 namespace {
38 using testing::AnyNumber;
39 using testing::AtLeast;
3440 using testing::DoDefault;
41 using testing::Not;
3542 using testing::Return;
3643 using testing::Expectation;
3744 using testing::Invoke;
8693 typename Analysis::Result getResult() {
8794 return typename Analysis::Result(static_cast(*this));
8895 }
96 static StringRef getName() { return llvm::getTypeName(); }
8997
9098 protected:
9199 // FIXME: MSVC seems unable to handle a lambda argument to Invoke from within
141149 return Handle->run(IR, AM, ExtraArgs...);
142150 }
143151 };
152
153 static StringRef getName() { return llvm::getTypeName(); }
144154
145155 Pass getPass() { return Pass(static_cast(*this)); }
146156
256266 SMDiagnostic Err;
257267 return parseAssemblyString(IR, Err, C);
258268 }
269
270 /// Helper for HasName matcher that returns getName both for IRUnit and
271 /// for IRUnit pointer wrapper into llvm::Any (wrapped by PassInstrumentation).
272 template std::string getName(const IRUnitT &IR) {
273 return IR.getName();
274 }
275
276 template <> std::string getName(const StringRef &name) { return name; }
277
278 template <> std::string getName(const llvm::Any &WrappedIR) {
279 if (any_isa(WrappedIR))
280 return any_cast(WrappedIR)->getName().str();
281 if (any_isa(WrappedIR))
282 return any_cast(WrappedIR)->getName().str();
283 if (any_isa(WrappedIR))
284 return any_cast(WrappedIR)->getName().str();
285 if (any_isa(WrappedIR))
286 return any_cast(WrappedIR)->getName();
287 return "";
288 }
289 /// Define a custom matcher for objects which support a 'getName' method.
290 ///
291 /// LLVM often has IR objects or analysis objects which expose a name
292 /// and in tests it is convenient to match these by name for readability.
293 /// Usually, this name is either a StringRef or a plain std::string. This
294 /// matcher supports any type exposing a getName() method of this form whose
295 /// return value is compatible with an std::ostream. For StringRef, this uses
296 /// the shift operator defined above.
297 ///
298 /// It should be used as:
299 ///
300 /// HasName("my_function")
301 ///
302 /// No namespace or other qualification is required.
303 MATCHER_P(HasName, Name, "") {
304 *result_listener << "has name '" << getName(arg) << "'";
305 return Name == getName(arg);
306 }
307
308 MATCHER_P(HasNameRegex, Name, "") {
309 *result_listener << "has name '" << getName(arg) << "'";
310 llvm::Regex r(Name);
311 return r.match(getName(arg));
312 }
313
314 struct MockPassInstrumentationCallbacks {
315 PassInstrumentationCallbacks Callbacks;
316
317 MockPassInstrumentationCallbacks() {
318 ON_CALL(*this, runBeforePass(_, _)).WillByDefault(Return(true));
319 }
320 MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any));
321 MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any));
322
323 void registerPassInstrumentation() {
324 Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) {
325 return this->runBeforePass(P, IR);
326 });
327 Callbacks.registerAfterPassCallback(
328 [this](StringRef P, llvm::Any IR) { this->runAfterPass(P, IR); });
329 }
330
331 void ignoreNonMockPassInstrumentation(StringRef IRName) {
332 // Generic EXPECT_CALLs are needed to match instrumentation on unimportant
333 // parts of a pipeline that we do not care about (e.g. various passes added
334 // by default by PassBuilder - Verifier pass etc).
335 // Make sure to avoid ignoring Mock passes/analysis, we definitely want
336 // to check these explicitly.
337 EXPECT_CALL(*this,
338 runBeforePass(Not(HasNameRegex("Mock")), HasName(IRName)))
339 .Times(AnyNumber());
340 EXPECT_CALL(*this, runAfterPass(Not(HasNameRegex("Mock")), HasName(IRName)))
341 .Times(AnyNumber());
342 }
343 };
259344
260345 template class PassBuilderCallbacksTest;
261346
278363
279364 LLVMContext Context;
280365 std::unique_ptr M;
366
367 MockPassInstrumentationCallbacks CallbacksHandle;
281368
282369 PassBuilder PB;
283370 ModulePassManager PM;
311398 "exit:\n"
312399 " ret void\n"
313400 "}\n")),
401 CallbacksHandle(), PB(nullptr, None, &CallbacksHandle.Callbacks),
314402 PM(true), LAM(true), FAM(true), CGAM(true), AM(true) {
315403
316404 /// Register a callback for analysis registration.
355443 }
356444 };
357445
358 /// Define a custom matcher for objects which support a 'getName' method.
359 ///
360 /// LLVM often has IR objects or analysis objects which expose a name
361 /// and in tests it is convenient to match these by name for readability.
362 /// Usually, this name is either a StringRef or a plain std::string. This
363 /// matcher supports any type exposing a getName() method of this form whose
364 /// return value is compatible with an std::ostream. For StringRef, this uses
365 /// the shift operator defined above.
366 ///
367 /// It should be used as:
368 ///
369 /// HasName("my_function")
370 ///
371 /// No namespace or other qualification is required.
372 MATCHER_P(HasName, Name, "") {
373 *result_listener << "has name '" << arg.getName() << "'";
374 return Name == arg.getName();
375 }
376
377446 using ModuleCallbacksTest = PassBuilderCallbacksTest;
378447 using CGSCCCallbacksTest = PassBuilderCallbacksTest;
379448 using FunctionCallbacksTest = PassBuilderCallbacksTest;
390459 StringRef PipelineText = "test-transform";
391460 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
392461 << "Pipeline was: " << PipelineText;
462
463 PM.run(*M, AM);
464 }
465
466 TEST_F(ModuleCallbacksTest, InstrumentedPasses) {
467 EXPECT_CALL(AnalysisHandle, run(HasName(""), _));
468 EXPECT_CALL(PassHandle, run(HasName(""), _))
469 .WillOnce(Invoke(getAnalysisResult));
470
471 CallbacksHandle.registerPassInstrumentation();
472 // Non-mock instrumentation not specifically mentioned below can be ignored.
473 CallbacksHandle.ignoreNonMockPassInstrumentation("");
474
475 // PassInstrumentation calls should happen in-sequence, in the same order
476 // as passes/analyses are scheduled.
477 ::testing::Sequence PISequence;
478 EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"),
479 HasName("")))
480 .InSequence(PISequence);
481 EXPECT_CALL(CallbacksHandle,
482 runAfterPass(HasNameRegex("MockPassHandle"), HasName("")))
483 .InSequence(PISequence);
484
485 StringRef PipelineText = "test-transform";
486 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
487 << "Pipeline was: " << PipelineText;
488
489 PM.run(*M, AM);
490 }
491
492 TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) {
493 CallbacksHandle.registerPassInstrumentation();
494 // Non-mock instrumentation run here can safely be ignored.
495 CallbacksHandle.ignoreNonMockPassInstrumentation("");
496
497 // Skip the pass by returning false.
498 EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"),
499 HasName("")))
500 .WillOnce(Return(false));
501
502 EXPECT_CALL(AnalysisHandle, run(HasName(""), _)).Times(0);
503 EXPECT_CALL(PassHandle, run(HasName(""), _)).Times(0);
504
505 // As the pass is skipped there is no afterPass as well.
506 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
507 .Times(0);
508
509 StringRef PipelineText = "test-transform";
510 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
511 << "Pipeline was: " << PipelineText;
512
393513 PM.run(*M, AM);
394514 }
395515
404524 PM.run(*M, AM);
405525 }
406526
527 TEST_F(FunctionCallbacksTest, InstrumentedPasses) {
528 CallbacksHandle.registerPassInstrumentation();
529 // Non-mock instrumentation not specifically mentioned below can be ignored.
530 CallbacksHandle.ignoreNonMockPassInstrumentation("");
531 CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
532
533 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _));
534 EXPECT_CALL(PassHandle, run(HasName("foo"), _))
535 .WillOnce(Invoke(getAnalysisResult));
536
537 // PassInstrumentation calls should happen in-sequence, in the same order
538 // as passes/analyses are scheduled.
539 ::testing::Sequence PISequence;
540 EXPECT_CALL(CallbacksHandle,
541 runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
542 .InSequence(PISequence);
543 EXPECT_CALL(CallbacksHandle,
544 runAfterPass(HasNameRegex("MockPassHandle"), HasName("foo")))
545 .InSequence(PISequence);
546
547 StringRef PipelineText = "test-transform";
548 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
549 << "Pipeline was: " << PipelineText;
550 PM.run(*M, AM);
551 }
552
553 TEST_F(FunctionCallbacksTest, InstrumentedSkippedPasses) {
554 CallbacksHandle.registerPassInstrumentation();
555 // Non-mock instrumentation run here can safely be ignored.
556 CallbacksHandle.ignoreNonMockPassInstrumentation("");
557 CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
558
559 // Skip the pass by returning false.
560 EXPECT_CALL(CallbacksHandle,
561 runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
562 .WillOnce(Return(false));
563
564 EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)).Times(0);
565 EXPECT_CALL(PassHandle, run(HasName("foo"), _)).Times(0);
566
567 // As the pass is skipped there is no afterPass as well.
568 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
569 .Times(0);
570
571 StringRef PipelineText = "test-transform";
572 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
573 << "Pipeline was: " << PipelineText;
574 PM.run(*M, AM);
575 }
576
407577 TEST_F(LoopCallbacksTest, Passes) {
408578 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _));
409579 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _))
415585 PM.run(*M, AM);
416586 }
417587
588 TEST_F(LoopCallbacksTest, InstrumentedPasses) {
589 CallbacksHandle.registerPassInstrumentation();
590 // Non-mock instrumentation not specifically mentioned below can be ignored.
591 CallbacksHandle.ignoreNonMockPassInstrumentation("");
592 CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
593 CallbacksHandle.ignoreNonMockPassInstrumentation("loop");
594
595 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _));
596 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _))
597 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
598
599 // PassInstrumentation calls should happen in-sequence, in the same order
600 // as passes/analyses are scheduled.
601 ::testing::Sequence PISequence;
602 EXPECT_CALL(CallbacksHandle,
603 runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
604 .InSequence(PISequence);
605 EXPECT_CALL(CallbacksHandle,
606 runAfterPass(HasNameRegex("MockPassHandle"), HasName("loop")))
607 .InSequence(PISequence);
608
609 StringRef PipelineText = "test-transform";
610 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
611 << "Pipeline was: " << PipelineText;
612 PM.run(*M, AM);
613 }
614
615 TEST_F(LoopCallbacksTest, InstrumentedSkippedPasses) {
616 CallbacksHandle.registerPassInstrumentation();
617 // Non-mock instrumentation run here can safely be ignored.
618 CallbacksHandle.ignoreNonMockPassInstrumentation("");
619 CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
620 CallbacksHandle.ignoreNonMockPassInstrumentation("loop");
621
622 // Skip the pass by returning false.
623 EXPECT_CALL(CallbacksHandle,
624 runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
625 .WillOnce(Return(false));
626
627 EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)).Times(0);
628 EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)).Times(0);
629
630 // As the pass is skipped there is no afterPass as well.
631 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
632 .Times(0);
633
634 StringRef PipelineText = "test-transform";
635 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
636 << "Pipeline was: " << PipelineText;
637 PM.run(*M, AM);
638 }
639
418640 TEST_F(CGSCCCallbacksTest, Passes) {
419641 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _));
420642 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _))
421643 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
644
645 StringRef PipelineText = "test-transform";
646 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
647 << "Pipeline was: " << PipelineText;
648 PM.run(*M, AM);
649 }
650
651 TEST_F(CGSCCCallbacksTest, InstrumentedPasses) {
652 CallbacksHandle.registerPassInstrumentation();
653 // Non-mock instrumentation not specifically mentioned below can be ignored.
654 CallbacksHandle.ignoreNonMockPassInstrumentation("");
655 CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)");
656
657 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _));
658 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _))
659 .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult)));
660
661 // PassInstrumentation calls should happen in-sequence, in the same order
662 // as passes/analyses are scheduled.
663 ::testing::Sequence PISequence;
664 EXPECT_CALL(CallbacksHandle,
665 runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
666 .InSequence(PISequence);
667 EXPECT_CALL(CallbacksHandle,
668 runAfterPass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
669 .InSequence(PISequence);
670
671 StringRef PipelineText = "test-transform";
672 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
673 << "Pipeline was: " << PipelineText;
674 PM.run(*M, AM);
675 }
676
677 TEST_F(CGSCCCallbacksTest, InstrumentedSkippedPasses) {
678 CallbacksHandle.registerPassInstrumentation();
679 // Non-mock instrumentation run here can safely be ignored.
680 CallbacksHandle.ignoreNonMockPassInstrumentation("");
681 CallbacksHandle.ignoreNonMockPassInstrumentation("(foo)");
682
683 // Skip the pass by returning false.
684 EXPECT_CALL(CallbacksHandle,
685 runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
686 .WillOnce(Return(false));
687
688 // neither Analysis nor Pass are called.
689 EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)).Times(0);
690 EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)).Times(0);
691
692 // As the pass is skipped there is no afterPass as well.
693 EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
694 .Times(0);
422695
423696 StringRef PipelineText = "test-transform";
424697 ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
404404 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
405405 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
406406 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
407
408 MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
409 FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
407410
408411 ModulePassManager MPM;
409412
555558 TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
556559 CustomizedAnalysisManager AM;
557560 AM.registerPass([&] { return CustomizedAnalysis(); });
561 PassInstrumentationCallbacks PIC;
562 AM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
558563
559564 CustomizedPassManager PM;
560565
686691 MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
687692 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
688693 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
694
695 PassInstrumentationCallbacks PIC;
696 MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
697 FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
689698
690699 int InstrCount = 0, FunctionCount = 0;
691700 ModulePassManager MPM(/*DebugLogging*/ true);
306306 FAM.registerPass([&] { return ScalarEvolutionAnalysis(); });
307307 FAM.registerPass([&] { return TargetLibraryAnalysis(); });
308308 FAM.registerPass([&] { return TargetIRAnalysis(); });
309
310 // Register required pass instrumentation analysis.
311 LAM.registerPass([&] { return PassInstrumentationAnalysis(); });
312 FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
313 MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
309314
310315 // Cross-register proxies.
311316 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });