Index: include/llvm/IR/PassInstrumentation.h =================================================================== --- include/llvm/IR/PassInstrumentation.h +++ include/llvm/IR/PassInstrumentation.h @@ -47,10 +47,12 @@ 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(StringRef, Any, PassExecutionCounter); using AfterPassFunc = void(StringRef, Any, PassExecutionCounter); + using BeforeAnalysisFunc = void(StringRef, Any, PassExecutionCounter); + using AfterAnalysisFunc = void(StringRef, Any, PassExecutionCounter); public: PassInstrumentationImpl() {} @@ -61,6 +63,12 @@ template void runAfterPass(StringRef PassID, IRUnitT &) const; + template + void runBeforeAnalysis(StringRef PassID, IRUnitT &) const; + + template + void runAfterAnalysis(StringRef PassID, IRUnitT &) const; + void runStartPipeline() const; void runEndPipeline() const; @@ -73,6 +81,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); } @@ -89,6 +107,8 @@ SmallVector, 4> BeforePassCallbacks; SmallVector, 4> AfterPassCallbacks; + SmallVector, 4> BeforeAnalysisCallbacks; + SmallVector, 4> AfterAnalysisCallbacks; SmallVector, 2> StartPipelineCallbacks; SmallVector, 2> EndPipelineCallbacks; }; @@ -130,6 +150,16 @@ Impl->runAfterPass(PassID, IR); } + void runBeforeAnalysis(StringRef PassID, IRUnitT &IR) { + if (Impl) + Impl->runBeforeAnalysis(PassID, IR); + } + + void runAfterAnalysis(StringRef PassID, IRUnitT &IR) { + if (Impl) + Impl->runAfterAnalysis(PassID, IR); + } + void runStartPipeline() { if (Impl) Impl->runStartPipeline(); @@ -152,6 +182,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 @@ -905,9 +905,22 @@ if (DebugLogging) 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.name(), IR); + } + AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); + if (!IsInstrumentationAnalysis) + PI.runAfterAnalysis(P.name(), 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(StringRef PassID, + IRUnitT &IR) const { + for (auto &C : BeforeAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + +template +void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + IRUnitT &IR) const { + for (auto &C : AfterAnalysisCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + void PassInstrumentationImpl::runStartPipeline() const { for (auto &C : StartPipelineCallbacks) C(); @@ -62,6 +76,25 @@ PassInstrumentationImpl::runAfterPass(StringRef PassID, LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + Module &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + Function &IR) const; +template void PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + Loop &IR) const; +template void +PassInstrumentationImpl::runBeforeAnalysis(StringRef PassID, + LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + Module &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + Function &IR) const; +template void PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + Loop &IR) const; +template void +PassInstrumentationImpl::runAfterAnalysis(StringRef PassID, + LazyCallGraph::SCC &IR) const; + template class PassInstrumentationAnalysis; template class PassInstrumentationAnalysis;