Index: include/llvm/IR/PassInstrumentation.h =================================================================== --- include/llvm/IR/PassInstrumentation.h +++ include/llvm/IR/PassInstrumentation.h @@ -150,7 +150,7 @@ /// point. class PassInstrumentation { 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(PassInstanceID, Any, PassExecutionCounter); using AfterPassFunc = void(PassInstanceID, Any, PassExecutionCounter); @@ -175,6 +175,12 @@ template void runAfterPass(PassInstanceID PassID, const IRUnitT &) const; + template + void runBeforeAnalysis(PassInstanceID PassID, const IRUnitT &) const; + + template + void runAfterAnalysis(PassInstanceID PassID, const IRUnitT &) const; + void startPipeline() const; void endPipeline() const; @@ -186,6 +192,16 @@ AfterPassCallbacks.push_back(C); } + void + registerBeforeAnalysisCallback(const std::function &C) { + BeforeAnalysisCallbacks.push_back(C); + } + + void + registerAfterAnalysisCallback(const std::function &C) { + AfterAnalysisCallbacks.push_back(C); + } + void registerStartPipelineCallback(const std::function &C) { StartPipelineCallbacks.push_back(C); } @@ -202,6 +218,8 @@ SmallVector, 4> BeforePassCallbacks; SmallVector, 4> AfterPassCallbacks; + SmallVector, 4> BeforeAnalysisCallbacks; + SmallVector, 4> AfterAnalysisCallbacks; SmallVector, 2> StartPipelineCallbacks; SmallVector, 2> EndPipelineCallbacks; }; Index: include/llvm/IR/PassManager.h =================================================================== --- include/llvm/IR/PassManager.h +++ include/llvm/IR/PassManager.h @@ -917,9 +917,21 @@ dbgs() << "Running analysis: " << P.name() << " on " << IR.getName() << "\n"; + PassInstrumentation* PI = nullptr; + bool IsInstrumentationAnalysis = + (ID == PassInstrumentationProxy::ID()); + if (!IsInstrumentationAnalysis) { + PI = + getPassInstrumentation(IR, std::tuple(ExtraArgs...)); + if (PI) PI->runBeforeAnalysis(&P, IR); + } + AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); + if (PI) + PI->runAfterAnalysis(&P, IR); + // P.run may have inserted elements into AnalysisResults and invalidated // RI. RI = AnalysisResults.find({ID, &IR}); Index: lib/IR/PassInstrumentation.cpp =================================================================== --- lib/IR/PassInstrumentation.cpp +++ lib/IR/PassInstrumentation.cpp @@ -33,6 +33,20 @@ C(PassID, llvm::Any(&IR), PC); } +template +void PassInstrumentation::runBeforeAnalysis(PassInstanceID PassID, + const IRUnitT &IR) const { + for (auto &C : BeforeAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + +template +void PassInstrumentation::runAfterAnalysis(PassInstanceID PassID, + const IRUnitT &IR) const { + for (auto &C : AfterAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + void PassInstrumentation::startPipeline() const { for (auto &C : StartPipelineCallbacks) C(); @@ -45,7 +59,8 @@ bool PassInstrumentation::empty() const { return BeforePassCallbacks.empty() && AfterPassCallbacks.empty() && - StartPipelineCallbacks.empty() && EndPipelineCallbacks.empty(); + BeforeAnalysisCallbacks.empty() && AfterAnalysisCallbacks.empty() && + StartPipelineCallbacks.empty() && EndPipelineCallbacks.empty(); } template bool PassInstrumentation::runBeforePass(PassInstanceID PassID, @@ -66,6 +81,24 @@ template void PassInstrumentation::runAfterPass(PassInstanceID PassID, const LazyCallGraph::SCC &IR) const; +template void PassInstrumentation::runBeforeAnalysis(PassInstanceID PassID, + const Module &IR) const; +template void PassInstrumentation::runBeforeAnalysis(PassInstanceID PassID, + const Function &IR) const; +template void PassInstrumentation::runBeforeAnalysis(PassInstanceID PassID, + const Loop &IR) const; +template void +PassInstrumentation::runBeforeAnalysis(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; +template void PassInstrumentation::runAfterAnalysis(PassInstanceID PassID, + const Module &IR) const; +template void PassInstrumentation::runAfterAnalysis(PassInstanceID PassID, + const Function &IR) const; +template void PassInstrumentation::runAfterAnalysis(PassInstanceID PassID, + const Loop &IR) const; +template void +PassInstrumentation::runAfterAnalysis(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; template class PassInstrumentationProxy; template class PassInstrumentationProxy; Index: test/Other/new-pm-lto-defaults.ll =================================================================== --- test/Other/new-pm-lto-defaults.ll +++ test/Other/new-pm-lto-defaults.ll @@ -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<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: AAManager +; CHECK-O1-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: CallGraphAnalysis Index: test/Other/new-pm-thinlto-defaults.ll =================================================================== --- test/Other/new-pm-thinlto-defaults.ll +++ test/Other/new-pm-thinlto-defaults.ll @@ -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<{{.*}}Function> ; 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: PassInstrumentationProxy<{{.*}}Function> +; CHECK-PRELINK-O-NEXT: Running analysis: PassInstrumentationProxy<{{.*}}Function> ; CHECK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis