Index: include/llvm/IR/PassInstrumentation.h =================================================================== --- include/llvm/IR/PassInstrumentation.h +++ include/llvm/IR/PassInstrumentation.h @@ -157,7 +157,7 @@ /// point. class PassInstrumentationImpl { 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); @@ -178,6 +178,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; @@ -189,6 +195,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); } @@ -205,6 +221,8 @@ SmallVector, 4> BeforePassCallbacks; SmallVector, 4> AfterPassCallbacks; + SmallVector, 4> BeforeAnalysisCallbacks; + SmallVector, 4> AfterAnalysisCallbacks; SmallVector, 2> StartPipelineCallbacks; SmallVector, 2> EndPipelineCallbacks; }; @@ -249,6 +267,16 @@ Impl->runAfterPass(PassID, IR); } + void runBeforeAnalysis(PassInstanceID PassID, const IRUnitT &IR) { + if (Impl) + Impl->runBeforeAnalysis(PassID, IR); + } + + void runAfterAnalysis(PassInstanceID PassID, const IRUnitT &IR) { + if (Impl) + Impl->runAfterAnalysis(PassID, IR); + } + void startPipeline() { if (Impl) Impl->startPipeline(); @@ -271,6 +299,18 @@ Impl->registerAfterPassCallback(C); } + void registerBeforeAnalysisCallback( + const std::function &C) { + assert(Impl); + Impl->registerBeforeAnalysisCallback(C); + } + + void registerAfterAnalysisCallback( + const std::function &C) { + assert(Impl); + Impl->registerAfterAnalysisCallback(C); + } + void registerStartPipelineCallback(const std::function &C) { assert(Impl); Impl->registerStartPipelineCallback(C); Index: include/llvm/IR/PassManager.h =================================================================== --- include/llvm/IR/PassManager.h +++ include/llvm/IR/PassManager.h @@ -916,9 +916,21 @@ dbgs() << "Running analysis: " << P.name() << " on " << IR.getName() << "\n"; + PassInstrumentation PI; + bool IsInstrumentationAnalysis = + (ID == PassInstrumentationAnalysis::ID()); + if (!IsInstrumentationAnalysis) { + PI = + getPassInstrumentation(IR, std::tuple(ExtraArgs...)); + PI.runBeforeAnalysis(&P, IR); + } + AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); + if (!IsInstrumentationAnalysis) + 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 PassInstrumentationImpl::runBeforeAnalysis(PassInstanceID PassID, + const IRUnitT &IR) const { + for (auto &C : BeforeAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + +template +void PassInstrumentationImpl::runAfterAnalysis(PassInstanceID PassID, + const IRUnitT &IR) const { + for (auto &C : AfterAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + void PassInstrumentationImpl::startPipeline() const { for (auto &C : StartPipelineCallbacks) C(); @@ -62,6 +76,25 @@ PassInstrumentationImpl::runAfterPass(PassInstanceID PassID, const LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(PassInstanceID PassID, + const Module &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(PassInstanceID PassID, + const Function &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(PassInstanceID PassID, + const Loop &IR) const; +template void +PassInstrumentationImpl::runBeforeAnalysis(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(PassInstanceID PassID, + const Module &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(PassInstanceID PassID, + const Function &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(PassInstanceID PassID, + const Loop &IR) const; +template void +PassInstrumentationImpl::runAfterAnalysis(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; + template class PassInstrumentationAnalysis; template class PassInstrumentationAnalysis; 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: PassInstrumentationAnalysis<{{.*}}Function> +; CHECK-PRELINK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis