forked from OSchip/llvm-project
[New PM][PassInstrumentation] Adding PassInstrumentation to the AnalysisManager runs
As a prerequisite to time-passes implementation which needs to time both passes and analyses, adding instrumentation points to the Analysis Manager. The are two functional differences between Pass and Analysis instrumentation: - the latter does not increment pass execution counter - it does not provide ability to skip execution of the corresponding analysis Reviewers: chandlerc, philip.pfaffe Differential Revision: https://reviews.llvm.org/D51275 llvm-svn: 342778
This commit is contained in:
parent
5f6d527f09
commit
10febb0779
|
@ -68,7 +68,7 @@ class PreservedAnalyses;
|
|||
/// PassInstrumentation to pass control to the registered callbacks.
|
||||
class PassInstrumentationCallbacks {
|
||||
public:
|
||||
// Before/After Pass callbacks accept IRUnits, so they need to take them
|
||||
// Before/After callbacks accept IRUnits, so they need to take them
|
||||
// as pointers, wrapped with llvm::Any
|
||||
using BeforePassFunc = bool(StringRef, Any);
|
||||
using AfterPassFunc = void(StringRef, Any);
|
||||
|
@ -90,11 +90,25 @@ public:
|
|||
AfterPassCallbacks.emplace_back(std::move(C));
|
||||
}
|
||||
|
||||
template <typename CallableT>
|
||||
void registerBeforeAnalysisCallback(CallableT C) {
|
||||
BeforeAnalysisCallbacks.emplace_back(std::move(C));
|
||||
}
|
||||
|
||||
template <typename CallableT>
|
||||
void registerAfterAnalysisCallback(CallableT C) {
|
||||
AfterAnalysisCallbacks.emplace_back(std::move(C));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class PassInstrumentation;
|
||||
|
||||
SmallVector<llvm::unique_function<BeforePassFunc>, 4> BeforePassCallbacks;
|
||||
SmallVector<llvm::unique_function<AfterPassFunc>, 4> AfterPassCallbacks;
|
||||
SmallVector<llvm::unique_function<BeforeAnalysisFunc>, 4>
|
||||
BeforeAnalysisCallbacks;
|
||||
SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
|
||||
AfterAnalysisCallbacks;
|
||||
};
|
||||
|
||||
/// This class provides instrumentation entry points for the Pass Manager,
|
||||
|
@ -133,6 +147,24 @@ public:
|
|||
C(Pass.name(), llvm::Any(&IR));
|
||||
}
|
||||
|
||||
/// BeforeAnalysis instrumentation point - takes \p Analysis instance
|
||||
/// to be executed and constant reference to IR it operates on.
|
||||
template <typename IRUnitT, typename PassT>
|
||||
void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
|
||||
if (Callbacks)
|
||||
for (auto &C : Callbacks->BeforeAnalysisCallbacks)
|
||||
C(Analysis.name(), llvm::Any(&IR));
|
||||
}
|
||||
|
||||
/// AfterAnalysis instrumentation point - takes \p Analysis instance
|
||||
/// that has just been executed and constant reference to IR it operated on.
|
||||
template <typename IRUnitT, typename PassT>
|
||||
void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
|
||||
if (Callbacks)
|
||||
for (auto &C : Callbacks->AfterAnalysisCallbacks)
|
||||
C(Analysis.name(), llvm::Any(&IR));
|
||||
}
|
||||
|
||||
/// Handle invalidation from the pass manager when PassInstrumentation
|
||||
/// is used as the result of PassInstrumentationAnalysis.
|
||||
///
|
||||
|
|
|
@ -943,9 +943,18 @@ private:
|
|||
if (DebugLogging)
|
||||
dbgs() << "Running analysis: " << P.name() << " on " << IR.getName()
|
||||
<< "\n";
|
||||
|
||||
PassInstrumentation PI;
|
||||
if (ID != PassInstrumentationAnalysis::ID()) {
|
||||
PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
|
||||
PI.runBeforeAnalysis(P, IR);
|
||||
}
|
||||
|
||||
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
|
||||
ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
|
||||
|
||||
PI.runAfterAnalysis(P, IR);
|
||||
|
||||
// P.run may have inserted elements into AnalysisResults and invalidated
|
||||
// RI.
|
||||
RI = AnalysisResults.find({ID, &IR});
|
||||
|
|
|
@ -51,8 +51,10 @@
|
|||
; CHECK-O1-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Function
|
||||
; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
|
||||
; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
|
||||
; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
|
||||
; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
|
||||
; CHECK-O-NEXT: Running analysis: AAManager
|
||||
; CHECK-O1-NEXT: Running analysis: PassInstrumentationAnalysis
|
||||
; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
|
||||
; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass
|
||||
; CHECK-O-NEXT: Running analysis: CallGraphAnalysis
|
||||
|
|
|
@ -59,13 +59,14 @@
|
|||
; CHECK-POSTLINK-O-NEXT: Running analysis: ProfileSummaryAnalysis
|
||||
; CHECK-POSTLINK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
|
||||
; CHECK-POSTLINK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
|
||||
; CHECK-POSTLINK-O-NEXT: Running analysis: PassInstrumentationAnalysis
|
||||
; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}>
|
||||
; CHECK-O-NEXT: Starting llvm::Module pass manager run.
|
||||
; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
|
||||
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
|
||||
; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
|
||||
; CHECK-PRELINK-O-NODIS-NEXT: Running analysis: InnerAnalysisManagerProxy
|
||||
; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
|
||||
; CHECK-PRELINK-O-NEXT: Running analysis: PassInstrumentationAnalysis
|
||||
; CHECK-O-NEXT: Starting llvm::Function pass manager run.
|
||||
; CHECK-O-NEXT: Running pass: SimplifyCFGPass
|
||||
; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
|
||||
|
|
|
@ -309,6 +309,8 @@ struct MockPassInstrumentationCallbacks {
|
|||
}
|
||||
MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any));
|
||||
MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any));
|
||||
MOCK_METHOD2(runBeforeAnalysis, void(StringRef PassID, llvm::Any));
|
||||
MOCK_METHOD2(runAfterAnalysis, void(StringRef PassID, llvm::Any));
|
||||
|
||||
void registerPassInstrumentation() {
|
||||
Callbacks.registerBeforePassCallback([this](StringRef P, llvm::Any IR) {
|
||||
|
@ -316,6 +318,11 @@ struct MockPassInstrumentationCallbacks {
|
|||
});
|
||||
Callbacks.registerAfterPassCallback(
|
||||
[this](StringRef P, llvm::Any IR) { this->runAfterPass(P, IR); });
|
||||
Callbacks.registerBeforeAnalysisCallback([this](StringRef P, llvm::Any IR) {
|
||||
return this->runBeforeAnalysis(P, IR);
|
||||
});
|
||||
Callbacks.registerAfterAnalysisCallback(
|
||||
[this](StringRef P, llvm::Any IR) { this->runAfterAnalysis(P, IR); });
|
||||
}
|
||||
|
||||
void ignoreNonMockPassInstrumentation(StringRef IRName) {
|
||||
|
@ -329,6 +336,12 @@ struct MockPassInstrumentationCallbacks {
|
|||
.Times(AnyNumber());
|
||||
EXPECT_CALL(*this, runAfterPass(Not(HasNameRegex("Mock")), HasName(IRName)))
|
||||
.Times(AnyNumber());
|
||||
EXPECT_CALL(*this,
|
||||
runBeforeAnalysis(Not(HasNameRegex("Mock")), HasName(IRName)))
|
||||
.Times(AnyNumber());
|
||||
EXPECT_CALL(*this,
|
||||
runAfterAnalysis(Not(HasNameRegex("Mock")), HasName(IRName)))
|
||||
.Times(AnyNumber());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -468,6 +481,14 @@ TEST_F(ModuleCallbacksTest, InstrumentedPasses) {
|
|||
EXPECT_CALL(CallbacksHandle, runBeforePass(HasNameRegex("MockPassHandle"),
|
||||
HasName("<string>")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"),
|
||||
HasName("<string>")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("<string>")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterPass(HasNameRegex("MockPassHandle"), HasName("<string>")))
|
||||
.InSequence(PISequence);
|
||||
|
@ -492,9 +513,16 @@ TEST_F(ModuleCallbacksTest, InstrumentedSkippedPasses) {
|
|||
EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)).Times(0);
|
||||
EXPECT_CALL(PassHandle, run(HasName("<string>"), _)).Times(0);
|
||||
|
||||
// As the pass is skipped there is no afterPass as well.
|
||||
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
|
||||
// as well.
|
||||
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
|
||||
StringRef PipelineText = "test-transform";
|
||||
ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
|
||||
|
@ -530,6 +558,14 @@ TEST_F(FunctionCallbacksTest, InstrumentedPasses) {
|
|||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterPass(HasNameRegex("MockPassHandle"), HasName("foo")))
|
||||
.InSequence(PISequence);
|
||||
|
@ -554,9 +590,18 @@ TEST_F(FunctionCallbacksTest, InstrumentedSkippedPasses) {
|
|||
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 as well.
|
||||
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
|
||||
// as well.
|
||||
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
|
||||
StringRef PipelineText = "test-transform";
|
||||
ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
|
||||
|
@ -592,6 +637,14 @@ TEST_F(LoopCallbacksTest, InstrumentedPasses) {
|
|||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterPass(HasNameRegex("MockPassHandle"), HasName("loop")))
|
||||
.InSequence(PISequence);
|
||||
|
@ -617,9 +670,16 @@ TEST_F(LoopCallbacksTest, InstrumentedSkippedPasses) {
|
|||
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 as well.
|
||||
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
|
||||
// as well.
|
||||
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
|
||||
StringRef PipelineText = "test-transform";
|
||||
ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
|
||||
|
@ -654,6 +714,14 @@ TEST_F(CGSCCCallbacksTest, InstrumentedPasses) {
|
|||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforePass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(
|
||||
CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)")))
|
||||
.InSequence(PISequence);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterPass(HasNameRegex("MockPassHandle"), HasName("(foo)")))
|
||||
.InSequence(PISequence);
|
||||
|
@ -679,9 +747,16 @@ TEST_F(CGSCCCallbacksTest, InstrumentedSkippedPasses) {
|
|||
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 as well.
|
||||
// As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
|
||||
// as well.
|
||||
EXPECT_CALL(CallbacksHandle, runAfterPass(HasNameRegex("MockPassHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
EXPECT_CALL(CallbacksHandle,
|
||||
runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
|
||||
.Times(0);
|
||||
|
||||
StringRef PipelineText = "test-transform";
|
||||
ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
|
||||
|
|
Loading…
Reference in New Issue