[NewPM] Add callback for skipped passes

Parallel to https://reviews.llvm.org/D84772.

Will use this for printing when a pass is skipped.

Reviewed By: ychen

Differential Revision: https://reviews.llvm.org/D85478
This commit is contained in:
Arthur Eubanks 2020-08-06 15:14:50 -07:00
parent 20496ec614
commit f51f94852f
2 changed files with 76 additions and 0 deletions

View File

@ -74,6 +74,7 @@ public:
// IRUnits in a safe way, and we might pursue that as soon as there is a
// useful instrumentation that needs it.
using BeforePassFunc = bool(StringRef, Any);
using BeforeSkippedPassFunc = void(StringRef, Any);
using BeforeNonSkippedPassFunc = void(StringRef, Any);
using AfterPassFunc = void(StringRef, Any);
using AfterPassInvalidatedFunc = void(StringRef);
@ -91,6 +92,11 @@ public:
BeforePassCallbacks.emplace_back(std::move(C));
}
template <typename CallableT>
void registerBeforeSkippedPassCallback(CallableT C) {
BeforeSkippedPassCallbacks.emplace_back(std::move(C));
}
template <typename CallableT>
void registerBeforeNonSkippedPassCallback(CallableT C) {
BeforeNonSkippedPassCallbacks.emplace_back(std::move(C));
@ -119,6 +125,8 @@ private:
friend class PassInstrumentation;
SmallVector<llvm::unique_function<BeforePassFunc>, 4> BeforePassCallbacks;
SmallVector<llvm::unique_function<BeforeSkippedPassFunc>, 4>
BeforeSkippedPassCallbacks;
SmallVector<llvm::unique_function<BeforeNonSkippedPassFunc>, 4>
BeforeNonSkippedPassCallbacks;
SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
@ -179,6 +187,9 @@ public:
if (ShouldRun) {
for (auto &C : Callbacks->BeforeNonSkippedPassCallbacks)
C(Pass.name(), llvm::Any(&IR));
} else {
for (auto &C : Callbacks->BeforeSkippedPassCallbacks)
C(Pass.name(), llvm::Any(&IR));
}
return ShouldRun;

View File

@ -320,6 +320,7 @@ struct MockPassInstrumentationCallbacks {
ON_CALL(*this, runBeforePass(_, _)).WillByDefault(Return(true));
}
MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any));
MOCK_METHOD2(runBeforeSkippedPass, void(StringRef PassID, llvm::Any));
MOCK_METHOD2(runBeforeNonSkippedPass, void(StringRef PassID, llvm::Any));
MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any));
MOCK_METHOD1(runAfterPassInvalidated, void(StringRef PassID));
@ -330,6 +331,10 @@ struct MockPassInstrumentationCallbacks {
Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) {
return this->runBeforePass(P, IR);
});
Callbacks.registerBeforeSkippedPassCallback(
[this](StringRef P, llvm::Any IR) {
this->runBeforeSkippedPass(P, IR);
});
Callbacks.registerBeforeNonSkippedPassCallback(
[this](StringRef P, llvm::Any IR) {
this->runBeforeNonSkippedPass(P, IR);
@ -354,6 +359,9 @@ struct MockPassInstrumentationCallbacks {
EXPECT_CALL(*this,
runBeforePass(Not(HasNameRegex("Mock")), HasName(IRName)))
.Times(AnyNumber());
EXPECT_CALL(
*this, runBeforeSkippedPass(Not(HasNameRegex("Mock")), HasName(IRName)))
.Times(AnyNumber());
EXPECT_CALL(*this, runBeforeNonSkippedPass(Not(HasNameRegex("Mock")),
HasName(IRName)))
.Times(AnyNumber());
@ -524,6 +532,13 @@ TEST_F(ModuleCallbacksTest, InstrumentedPasses) {
runAfterPass(HasNameRegex("MockPassHandle"), HasName("<string>")))
.InSequence(PISequence);
// No passes are skipped, so there should be no calls to
// runBeforeSkippedPass().
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("<string>")))
.Times(0);
StringRef PipelineText = "test-transform";
ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
<< "Pipeline was: " << PipelineText;
@ -535,12 +550,17 @@ TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) {
CallbacksHandle.registerPassInstrumentation();
// Non-mock instrumentation run here can safely be ignored.
CallbacksHandle.ignoreNonMockPassInstrumentation("<string>");
CallbacksHandle.ignoreNonMockPassInstrumentation("foo");
// Skip all passes by returning false. Pass managers and adaptor passes are
// also passes that observed by the callbacks.
EXPECT_CALL(CallbacksHandle, runBeforePass(_, _))
.WillRepeatedly(Return(false));
EXPECT_CALL(CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), _))
.Times(3);
EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)).Times(0);
EXPECT_CALL(PassHandle, run(HasName("<string>"), _)).Times(0);
@ -684,6 +704,13 @@ TEST_F(FunctionCallbacksTest, InstrumentedPasses) {
runAfterPass(HasNameRegex("MockPassHandle"), HasName("foo")))
.InSequence(PISequence);
// No passes are skipped, so there should be no calls to
// runBeforeSkippedPass().
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("foo")))
.Times(0);
// Our mock pass does not invalidate IR.
EXPECT_CALL(CallbacksHandle,
runAfterPassInvalidated(HasNameRegex("MockPassHandle")))
@ -706,11 +733,19 @@ TEST_F(FunctionCallbacksTest, InstrumentedSkippedPasses) {
runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
.WillOnce(Return(false));
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("foo")))
.Times(1);
EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)).Times(0);
EXPECT_CALL(PassHandle, run(HasName("foo"), _)).Times(0);
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
// as well.
EXPECT_CALL(CallbacksHandle,
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), _))
.Times(0);
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
.Times(0);
EXPECT_CALL(CallbacksHandle,
@ -780,6 +815,13 @@ TEST_F(LoopCallbacksTest, InstrumentedPasses) {
runAfterPassInvalidated(HasNameRegex("MockPassHandle")))
.Times(0);
// No passes are skipped, so there should be no calls to
// runBeforeSkippedPass().
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("loop")))
.Times(0);
StringRef PipelineText = "test-transform";
ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
<< "Pipeline was: " << PipelineText;
@ -846,11 +888,19 @@ TEST_F(LoopCallbacksTest, InstrumentedSkippedPasses) {
runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
.WillOnce(Return(false));
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("loop")))
.Times(1);
EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)).Times(0);
EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)).Times(0);
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
// as well.
EXPECT_CALL(CallbacksHandle,
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), _))
.Times(0);
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
.Times(0);
EXPECT_CALL(CallbacksHandle,
@ -918,6 +968,13 @@ TEST_F(CGSCCCallbacksTest, InstrumentedPasses) {
runAfterPassInvalidated(HasNameRegex("MockPassHandle")))
.Times(0);
// No passes are skipped, so there should be no calls to
// runBeforeSkippedPass().
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
.Times(0);
StringRef PipelineText = "test-transform";
ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded())
<< "Pipeline was: " << PipelineText;
@ -984,12 +1041,20 @@ TEST_F(CGSCCCallbacksTest, InstrumentedSkippedPasses) {
runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
.WillOnce(Return(false));
EXPECT_CALL(
CallbacksHandle,
runBeforeSkippedPass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
.Times(1);
// neither Analysis nor Pass are called.
EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)).Times(0);
EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)).Times(0);
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
// as well.
EXPECT_CALL(CallbacksHandle,
runBeforeNonSkippedPass(HasNameRegex("MockPassHandle"), _))
.Times(0);
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
.Times(0);
EXPECT_CALL(CallbacksHandle,