Skip to content

Commit 5cf0c2e

Browse files
author
Yuanfang Chen
committed
[NewPM][PassInstrument] Add a new kind of before-pass callback that only get called if the pass is not skipped
TODO * PrintIRInstrumentation and TimePassesHandler would be using this new callback. * "Running pass" logging will also be moved to use this callback. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D84772
1 parent ee05167 commit 5cf0c2e

File tree

2 files changed

+82
-8
lines changed

2 files changed

+82
-8
lines changed

llvm/include/llvm/IR/PassInstrumentation.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,14 @@ class PassInstrumentationCallbacks {
6767
// to take them as constant pointers, wrapped with llvm::Any.
6868
// For the case when IRUnit has been invalidated there is a different
6969
// callback to use - AfterPassInvalidated.
70+
// We call all BeforePassFuncs to determine if a pass should run or not.
71+
// BeforeNonSkippedPassFuncs are called only if the pass should run.
7072
// TODO: currently AfterPassInvalidated does not accept IRUnit, since passing
71-
// already invalidated IRUnit is unsafe. There are ways to handle invalidated IRUnits
72-
// in a safe way, and we might pursue that as soon as there is a useful instrumentation
73-
// that needs it.
73+
// already invalidated IRUnit is unsafe. There are ways to handle invalidated
74+
// IRUnits in a safe way, and we might pursue that as soon as there is a
75+
// useful instrumentation that needs it.
7476
using BeforePassFunc = bool(StringRef, Any);
77+
using BeforeNonSkippedPassFunc = void(StringRef, Any);
7578
using AfterPassFunc = void(StringRef, Any);
7679
using AfterPassInvalidatedFunc = void(StringRef);
7780
using BeforeAnalysisFunc = void(StringRef, Any);
@@ -88,6 +91,11 @@ class PassInstrumentationCallbacks {
8891
BeforePassCallbacks.emplace_back(std::move(C));
8992
}
9093

94+
template <typename CallableT>
95+
void registerBeforeNonSkippedPassCallback(CallableT C) {
96+
BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
97+
}
98+
9199
template <typename CallableT> void registerAfterPassCallback(CallableT C) {
92100
AfterPassCallbacks.emplace_back(std::move(C));
93101
}
@@ -111,6 +119,8 @@ class PassInstrumentationCallbacks {
111119
friend class PassInstrumentation;
112120

113121
SmallVector<llvm::unique_function<BeforePassFunc>, 4> BeforePassCallbacks;
122+
SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
123+
BeforeNonSkippedPassCallbacks;
114124
SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
115125
SmallVector<llvm::unique_function<AfterPassInvalidatedFunc>, 4>
116126
AfterPassInvalidatedCallbacks;
@@ -165,6 +175,12 @@ class PassInstrumentation {
165175
for (auto &C : Callbacks->BeforePassCallbacks)
166176
ShouldRun &= C(Pass.name(), llvm::Any(&IR));
167177
ShouldRun = ShouldRun || isRequired(Pass);
178+
179+
if (ShouldRun) {
180+
for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
181+
C(Pass.name(), llvm::Any(&IR));
182+
}
183+
168184
return ShouldRun;
169185
}
170186

llvm/unittests/IR/PassBuilderCallbacksTest.cpp

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ struct MockPassInstrumentationCallbacks {
320320
ON_CALL(*this, runBeforePass(_, _)).WillByDefault(Return(true));
321321
}
322322
MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any));
323+
MOCK_METHOD2(runBeforeNonSkippedPass, void(StringRef PassID, llvm::Any));
323324
MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any));
324325
MOCK_METHOD1(runAfterPassInvalidated, void(StringRef PassID));
325326
MOCK_METHOD2(runBeforeAnalysis, void(StringRef PassID, llvm::Any));
@@ -329,6 +330,10 @@ struct MockPassInstrumentationCallbacks {
329330
Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) {
330331
return this->runBeforePass(P, IR);
331332
});
333+
Callbacks.registerBeforeNonSkippedPassCallback(
334+
[this](StringRef P, llvm::Any IR) {
335+
this->runBeforeNonSkippedPass(P, IR);
336+
});
332337
Callbacks.registerAfterPassCallback(
333338
[this](StringRef P, llvm::Any IR) { this->runAfterPass(P, IR); });
334339
Callbacks.registerAfterPassInvalidatedCallback(
@@ -349,6 +354,9 @@ struct MockPassInstrumentationCallbacks {
349354
EXPECT_CALL(*this,
350355
runBeforePass(Not(HasNameRegex("Mock")), HasName(IRName)))
351356
.Times(AnyNumber());
357+
EXPECT_CALL(*this, runBeforeNonSkippedPass(Not(HasNameRegex("Mock")),
358+
HasName(IRName)))
359+
.Times(AnyNumber());
352360
EXPECT_CALL(*this, runAfterPass(Not(HasNameRegex("Mock")), HasName(IRName)))
353361
.Times(AnyNumber());
354362
EXPECT_CALL(*this,
@@ -500,6 +508,10 @@ TEST_F(ModuleCallbacksTest, InstrumentedPasses) {
500508
EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"),
501509
HasName("<string>")))
502510
.InSequence(PISequence);
511+
EXPECT_CALL(CallbacksHandle,
512+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"),
513+
HasName("<string>")))
514+
.InSequence(PISequence);
503515
EXPECT_CALL(CallbacksHandle,
504516
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"),
505517
HasName("<string>")))
@@ -532,8 +544,11 @@ TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) {
532544
EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)).Times(0);
533545
EXPECT_CALL(PassHandle, run(HasName("<string>"), _)).Times(0);
534546

535-
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
536-
// as well.
547+
// As the pass is skipped there is no nonskippedpass/afterPass,
548+
// beforeAnalysis/afterAnalysis as well.
549+
EXPECT_CALL(CallbacksHandle,
550+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), _))
551+
.Times(0);
537552
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
538553
.Times(0);
539554
EXPECT_CALL(CallbacksHandle,
@@ -545,12 +560,35 @@ TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) {
545560

546561
// Order is important here. `Adaptor` expectations should be checked first
547562
// because the its argument contains 'PassManager' (for example:
548-
// ModuleToFunctionPassAdaptor{{.*}}PassManager{{.*}}). Here only check
549-
// `runAfterPass` to show that they are not skipped.
550-
563+
// ModuleToFunctionPassAdaptor{{.*}}PassManager{{.*}}). Check
564+
// `runBeforeNonSkippedPass` and `runAfterPass` to show that they are not
565+
// skipped.
566+
//
551567
// Pass managers are not ignored.
552568
// 5 = (1) ModulePassManager + (2) FunctionPassMangers + (1) LoopPassManager +
553569
// (1) CGSCCPassManager
570+
EXPECT_CALL(CallbacksHandle,
571+
runBeforeNonSkippedPass(HasNameRegex("PassManager"), _))
572+
.Times(5);
573+
EXPECT_CALL(
574+
CallbacksHandle,
575+
runBeforeNonSkippedPass(HasNameRegex("ModuleToFunctionPassAdaptor"), _))
576+
.Times(1);
577+
EXPECT_CALL(CallbacksHandle,
578+
runBeforeNonSkippedPass(
579+
HasNameRegex("ModuleToPostOrderCGSCCPassAdaptor"), _))
580+
.Times(1);
581+
EXPECT_CALL(
582+
CallbacksHandle,
583+
runBeforeNonSkippedPass(HasNameRegex("CGSCCToFunctionPassAdaptor"), _))
584+
.Times(1);
585+
EXPECT_CALL(
586+
CallbacksHandle,
587+
runBeforeNonSkippedPass(HasNameRegex("FunctionToLoopPassAdaptor"), _))
588+
.Times(1);
589+
590+
// The `runAfterPass` checks are the same as these of
591+
// `runBeforeNonSkippedPass`.
554592
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("PassManager"), _))
555593
.Times(5);
556594
EXPECT_CALL(CallbacksHandle,
@@ -630,6 +668,10 @@ TEST_F(FunctionCallbacksTest, InstrumentedPasses) {
630668
EXPECT_CALL(CallbacksHandle,
631669
runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
632670
.InSequence(PISequence);
671+
EXPECT_CALL(
672+
CallbacksHandle,
673+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), HasName("foo")))
674+
.InSequence(PISequence);
633675
EXPECT_CALL(
634676
CallbacksHandle,
635677
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo")))
@@ -717,6 +759,10 @@ TEST_F(LoopCallbacksTest, InstrumentedPasses) {
717759
EXPECT_CALL(CallbacksHandle,
718760
runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
719761
.InSequence(PISequence);
762+
EXPECT_CALL(
763+
CallbacksHandle,
764+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), HasName("loop")))
765+
.InSequence(PISequence);
720766
EXPECT_CALL(
721767
CallbacksHandle,
722768
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop")))
@@ -758,6 +804,10 @@ TEST_F(LoopCallbacksTest, InstrumentedInvalidatingPasses) {
758804
EXPECT_CALL(CallbacksHandle,
759805
runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
760806
.InSequence(PISequence);
807+
EXPECT_CALL(
808+
CallbacksHandle,
809+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), HasName("loop")))
810+
.InSequence(PISequence);
761811
EXPECT_CALL(
762812
CallbacksHandle,
763813
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop")))
@@ -847,6 +897,10 @@ TEST_F(CGSCCCallbacksTest, InstrumentedPasses) {
847897
EXPECT_CALL(CallbacksHandle,
848898
runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
849899
.InSequence(PISequence);
900+
EXPECT_CALL(
901+
CallbacksHandle,
902+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
903+
.InSequence(PISequence);
850904
EXPECT_CALL(
851905
CallbacksHandle,
852906
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)")))
@@ -888,6 +942,10 @@ TEST_F(CGSCCCallbacksTest, InstrumentedInvalidatingPasses) {
888942
EXPECT_CALL(CallbacksHandle,
889943
runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
890944
.InSequence(PISequence);
945+
EXPECT_CALL(
946+
CallbacksHandle,
947+
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
948+
.InSequence(PISequence);
891949
EXPECT_CALL(
892950
CallbacksHandle,
893951
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)")))

0 commit comments

Comments
 (0)