Index: include/llvm/Analysis/CGSCCPassManager.h =================================================================== --- include/llvm/Analysis/CGSCCPassManager.h +++ include/llvm/Analysis/CGSCCPassManager.h @@ -119,6 +119,8 @@ extern template class AnalysisManager; +extern template class PassInstrumentationAnalysis; + /// The CGSCC analysis manager. /// /// See the documentation for the AnalysisManager template for detail @@ -364,6 +366,10 @@ InvalidSCCSet, nullptr, nullptr, InlinedInternalEdges}; + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + PassInstrumentation PI = AM.getPassInstrumentation(M); + PreservedAnalyses PA = PreservedAnalyses::all(); CG.buildRefSCCs(); for (auto RCI = CG.postorder_ref_scc_begin(), @@ -428,8 +434,16 @@ UR.UpdatedRC = nullptr; UR.UpdatedC = nullptr; + + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns false). + if (!PI.runBeforePass(&Pass, *C)) + continue; + PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR); + PI.runAfterPass(&Pass, *C); + // Update the SCC and RefSCC if necessary. C = UR.UpdatedC ? UR.UpdatedC : C; RC = UR.UpdatedRC ? UR.UpdatedRC : RC; @@ -615,12 +629,20 @@ if (CG.lookupSCC(*N) != CurrentC) continue; - PreservedAnalyses PassPA = Pass.run(N->getFunction(), FAM); + Function &F = N->getFunction(); + + PassInstrumentation PI = FAM.getPassInstrumentation(F); + if (!PI.runBeforePass(&Pass, F)) + continue; + + PreservedAnalyses PassPA = Pass.run(F, FAM); + + PI.runAfterPass(&Pass, F); // We know that the function pass couldn't have invalidated any other // function's analyses (that's the contract of a function pass), so // directly handle the function analysis manager's invalidation here. - FAM.invalidate(N->getFunction(), PassPA); + FAM.invalidate(F, PassPA); // Then intersect the preserved set so that invalidation of module // analyses will eventually occur when the module pass completes. @@ -690,6 +712,8 @@ PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR) { PreservedAnalyses PA = PreservedAnalyses::all(); + PassInstrumentation PI = + AM.getPassInstrumentation(InitialC, CG); // The SCC may be refined while we are running passes over it, so set up // a pointer that we can update. @@ -733,8 +757,14 @@ auto CallCounts = ScanSCC(*C, CallHandles); for (int Iteration = 0;; ++Iteration) { + + if (!PI.runBeforePass(&Pass, *C)) + continue; + PreservedAnalyses PassPA = Pass.run(*C, AM, CG, UR); + PI.runAfterPass(&Pass, *C); + // If the SCC structure has changed, bail immediately and let the outer // CGSCC layer handle any iteration to reflect the refined structure. if (UR.UpdatedC && UR.UpdatedC != C) { Index: include/llvm/IR/PassInstrumentation.h =================================================================== --- /dev/null +++ include/llvm/IR/PassInstrumentation.h @@ -0,0 +1,280 @@ +//===- llvm/IR/PassInstrumentation.h ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file defines the Pass Instrumentation classes that provide +/// instrumentation points into the pass execution by PassManager. +/// +/// Main interface class is PassInstrumentation template, which provides: +/// +/// - registerXXXCallback() set of methods to register custom instrumentation +/// callbacks +/// - runXXX() set of instrumentation entry points to run the registered +/// instrumentation callbacks +/// +/// +/// PassInstrumentationImpl class provides the actual implementation for all the +/// above, with PassInstrumentation being a pimpl wrapper over it. That allows +/// PassInstrumentation to be easily copyable, which is necessary since it is +/// intended to be queried through the analysis framework. +/// +/// PassExecutionCounter class tracks pass execution. Currently it is a simple +/// counter, to be enhanced with more sophisticated schemes of tracking the +/// exact execution location as soon as the need for more sophisticated +/// instrumentations arives. +/// +/// Intended scheme of use for Pass Instrumentation is as follows: +/// - register instrumentation callbacks. +/// +/// - register PassInstrumentationAnalysis (see PassManager.h) with Pass +/// Manager. +/// +/// - Pass Manager requests PassInstrumentationAnalysis and gets +/// PassInstrumentation as its result. +/// +/// - Pass Manager invokes PassInstrumentation entry points appropriately, +/// passing PassInstanceID of the pass currently being executed and IRUnit +/// it works on. +/// +/// - PassInstrumentation wraps address of IRUnit into llvm::Any, increments +/// PassExecutionCounter and passes control to all the registered +/// callbacks. Note that we specifically wrap 'const IRUnitT*' so as to +/// avoid any accidental changes to IR in instrumenting callbacks. +/// +/// - Some instrumentation points (runBeforePass) allow to control execution +/// of a pass. For those callback returning false means pass will not be +/// executed. +/// +/// TODO?: currently there is no way for a pass to opt-out of execution control +/// (e.g. become unskippable). PassManager is the only entity that determines +/// how pass instrumentation affects pass execution. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_PASSINSTRUMENTATION_H +#define LLVM_IR_PASSINSTRUMENTATION_H + +#include "llvm/ADT/Any.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/TypeName.h" +#include + +namespace llvm { + +class PreservedAnalyses; + +class PassExecutionCounter { + unsigned count = 0; + +public: + PassExecutionCounter() = default; + PassExecutionCounter(const PassExecutionCounter &PC) = default; + PassExecutionCounter(PassExecutionCounter &&PC) = default; + + PassExecutionCounter &operator=(const PassExecutionCounter &PC) { + count = PC.count; + return *this; + } + + operator int() const { return count; } + + /// preincrement, advance the counter + void operator++() { count++; } +}; + +// Forward declaration for PassConcept, wrapper for pass instances in new pass manager. +template +struct PassConcept; + +/// This class is an opaque wrapper over any kind of new pass manager's pass instance. +/// +/// Note that new pass manager lacks a particular hierarchy of classes and uses tricks +/// to store pass instances. Thus we need to handle both actual pass instances (say, +/// for PassManager instances inside the PassManager itself) and pass instances +/// wrapped by PassManager into PassModel/PassConcept objects. +/// +/// For that we "unwrap" PassConcept in one of the constructors, by calling getPassInstance +/// method. It allows us to use a plain void* as an identifier for the pass instance. +struct PassInstanceID { + StringRef Name; + const void *Pass; + + /// Constructor for the "empty" instance. + PassInstanceID() : Name(), Pass(nullptr) {} + + /// Constructor that unwraps PassConcept object by calling getPassInstance member. + template + PassInstanceID(PassConcept *P) + : Name(P->name()), Pass(P->getPassInstance()) { } + + /// Constructor that just takes a pointer to the pass parameter. + template + PassInstanceID(PassT *P) + : Name(P->name()), Pass(P) { } + + /// Returns the name of the pass + StringRef getName() const { return Name; } + + /// Returns an opaque pointer that uniquely identifies the Pass Instance + /// in current pipeline. + const void *getInstance() const { return Pass; } + + bool emptyInstance() const { return Pass == nullptr; } +}; + +/// This class provides actual implementation for pass instrumentation +/// interface. It manages callbacks registration, as well as passes control to +/// the registered callbacks when Pass Managers call a specific instrumentation +/// point. +class PassInstrumentationImpl { +public: + // Before/After Pass 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); + using BeforeAnalysisFunc = void(PassInstanceID, Any, PassExecutionCounter); + using AfterAnalysisFunc = void(PassInstanceID, Any, PassExecutionCounter); + +public: + PassInstrumentationImpl() {} + + /// BeforePass instrumentation point - takes \p PassID identifier for the + /// pass instance to be executed and constant reference to IR it operates on. + /// \Returns true if pass is allowed to be executed. + template + bool runBeforePass(PassInstanceID PassID, const IRUnitT &) const; + + /// AfterPass instrumentation point - takes \p PassID identifier for the + /// pass instance to be executed and constant reference to IR it operates on. + template + void runAfterPass(PassInstanceID PassID, const IRUnitT &) const; + + void startPipeline() const; + void endPipeline() const; + + void registerBeforePassCallback(const std::function &C) { + BeforePassCallbacks.push_back(C); + } + + void registerAfterPassCallback(const std::function &C) { + AfterPassCallbacks.push_back(C); + } + + void registerStartPipelineCallback(const std::function &C) { + StartPipelineCallbacks.push_back(C); + } + void registerEndPipelineCallback(const std::function &C) { + EndPipelineCallbacks.push_back(C); + } + + PassExecutionCounter &getPC() { return PC; } + +private: + mutable PassExecutionCounter PC; + + // instrumentation callbacks + + SmallVector, 4> BeforePassCallbacks; + SmallVector, 4> AfterPassCallbacks; + SmallVector, 2> StartPipelineCallbacks; + SmallVector, 2> EndPipelineCallbacks; +}; + +/// This class provides the main interface for pass instrumentation. +/// It handles both registration of callbacks and exposes instrumentation calls +/// to be invoked by PassManagers. +template class PassInstrumentation { + PassInstrumentationImpl *Impl; + +public: + PassInstrumentation() : Impl(nullptr) {} + + explicit PassInstrumentation(PassInstrumentationImpl &Impl) : Impl(&Impl) {} + + template friend class PassInstrumentation; + + template + PassInstrumentation(const PassInstrumentation &PI) + : Impl(PI.Impl), MainPassID(PI.MainPassID) {} + + // Provide value semantics. + PassInstrumentation(const PassInstrumentation &PI) : Impl(PI.Impl) {} + PassInstrumentation(PassInstrumentation &&PI) : Impl(PI.Impl) {} + + PassInstrumentation &operator=(const PassInstrumentation &PI) { + Impl = PI.Impl; + return *this; + } + PassInstrumentation &operator=(PassInstrumentation &&PI) { + Impl = PI.Impl; + return *this; + } + + // pass-instrumentation calls + bool runBeforePass(PassInstanceID PassID, const IRUnitT &IR) { + return (Impl ? Impl->runBeforePass(PassID, IR) : true); + } + + void runAfterPass(PassInstanceID PassID, const IRUnitT &IR) { + if (Impl) + Impl->runAfterPass(PassID, IR); + } + + void startPipeline() { + if (Impl) + Impl->startPipeline(); + } + + void endPipeline() { + if (Impl) + Impl->endPipeline(); + } + + void registerBeforePassCallback( + const std::function &C) { + assert(Impl); + Impl->registerBeforePassCallback(C); + } + + void registerAfterPassCallback( + const std::function &C) { + assert(Impl); + Impl->registerAfterPassCallback(C); + } + + void registerStartPipelineCallback(const std::function &C) { + assert(Impl); + Impl->registerStartPipelineCallback(C); + } + + void registerEndPpelineCallback(const std::function &C) { + assert(Impl); + Impl->registerEndPipelineCallback(C); + } + + PassExecutionCounter &getPC() { + assert(Impl); + return Impl->getPC(); + } + + /// Handle invalidation from the pass manager when being used as a result of + /// analysis. + /// + /// On attempt to invalidate just return false. There is nothing to become + /// invalid here. + template + bool invalidate(IRUnitT &, const class llvm::PreservedAnalyses &, + ExtraArgsT...) { + return false; + } +}; + +} // namespace llvm + +#endif Index: include/llvm/IR/PassManager.h =================================================================== --- include/llvm/IR/PassManager.h +++ include/llvm/IR/PassManager.h @@ -44,6 +44,7 @@ #include "llvm/ADT/TinyPtrVector.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PassManagerInternal.h" #include "llvm/Support/Debug.h" #include "llvm/Support/TypeName.h" @@ -402,6 +403,9 @@ } }; +// Forward declare the PassInstrumentation Analysis template. +template class PassInstrumentationAnalysis; + /// Manages a sequence of passes over a particular unit of IR. /// /// A pass manager contains a sequence of passes to run over a particular unit @@ -445,6 +449,11 @@ ExtraArgTs... ExtraArgs) { PreservedAnalyses PA = PreservedAnalyses::all(); + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + PassInstrumentation PI = + AM.getPassInstrumentation(IR, std::tuple(ExtraArgs...)); + if (DebugLogging) dbgs() << "Starting " << getTypeName() << " pass manager run.\n"; @@ -453,8 +462,18 @@ dbgs() << "Running pass: " << Passes[Idx]->name() << " on " << IR.getName() << "\n"; + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns + // false). + if (!PI.runBeforePass(Passes[Idx].get(), IR)) + continue; + PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM, ExtraArgs...); + // Call onto PassInstrumentation's AfterPass callbacks immediately after + // running the pass. + PI.runAfterPass(Passes[Idx].get(), IR); + // Update the analysis manager as each pass runs and potentially // invalidates analyses. AM.invalidate(IR, PassPA); @@ -680,6 +699,42 @@ AnalysisResultLists.clear(); } + /// Helper for partial unpacking of extra arguments in getPassInstrumentation. + /// + /// Arguments passed in tuple come from PassManager, so they might have extra + /// arguments after those AnalysisManager's ExtraArgTs ones that we need to + /// pass to getResult. + template + PassInstrumentation + getPassInstrumentation(IRUnitT &IR, std::tuple Args) { + return getPassInstrumentation(IR, Args, + llvm::index_sequence_for{}); + } + + /// Actual unpacker of extra arguments in getPassInstrumentation, + /// passes only those tuple arguments that are mentioned in index_sequence. + template + PassInstrumentation + getPassInstrumentation(IRUnitT &IR, std::tuple Args, + llvm::index_sequence) { + (void)Args; + return getPassInstrumentation(IR, std::get(Args)...); + } + + /// Get the PassInstrumentation object as a result of + /// PassInstrumentationAnalysis. + PassInstrumentation getPassInstrumentation(IRUnitT &IR, + ExtraArgTs... ExtraArgs) { + // avoid failing when analysis is not registered (mostly for tests). + if (!isRegisteredAnalysis>()) + return PassInstrumentation(); + return getResult>(IR, ExtraArgs...); + } + + template bool isRegisteredAnalysis() const { + return AnalysisPasses.count(PassT::ID()) != 0; + } + /// Get the result of an analysis pass for a given IR unit. /// /// Runs the analysis if a cached result is not available. @@ -860,6 +915,7 @@ if (DebugLogging) dbgs() << "Running analysis: " << P.name() << " on " << IR.getName() << "\n"; + AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); @@ -1147,6 +1203,36 @@ const AnalysisManagerT *AM; }; +/// Pseudo-analysis pass that exposes the \c PassInstrumentation for IRUnit +/// being processed. +template +class PassInstrumentationAnalysis + : public AnalysisInfoMixin> { + friend AnalysisInfoMixin>; + static AnalysisKey Key; + + /// Shared PassInstrumentationImpl object that we indirectly access through + /// PassInstrumentation objects. Owned by something else, not this analysis. + PassInstrumentationImpl &PIImpl; + +public: + PassInstrumentationAnalysis(PassInstrumentationImpl &_PIImpl) + : PIImpl(_PIImpl) {} + + typedef PassInstrumentation Result; + + template + Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) { + return PassInstrumentation(PIImpl); + } +}; + +template +AnalysisKey PassInstrumentationAnalysis::Key; + +extern template class PassInstrumentationAnalysis; +extern template class PassInstrumentationAnalysis; + template AnalysisKey OuterAnalysisManagerProxy::Key; @@ -1192,13 +1278,24 @@ FunctionAnalysisManager &FAM = AM.getResult(M).getManager(); + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + PassInstrumentation PI = AM.getPassInstrumentation(M); + PreservedAnalyses PA = PreservedAnalyses::all(); for (Function &F : M) { if (F.isDeclaration()) continue; + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns + // false). + if (!PI.runBeforePass(&Pass, F)) + continue; PreservedAnalyses PassPA = Pass.run(F, FAM); + PI.runAfterPass(&Pass, F); + // We know that the function pass couldn't have invalidated any other // function's analyses (that's the contract of a function pass), so // directly handle the function analysis manager's invalidation here. @@ -1302,10 +1399,25 @@ RepeatedPass(int Count, PassT P) : Count(Count), P(std::move(P)) {} template - PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, Ts &&... Args) { + PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, Ts &&... Args) { + + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + // Here we use std::tuple version of getPassInstrumentation which helps + // to extract AnalysisManager's arguments out of the whole Args set. + PassInstrumentation PI = + AM.getPassInstrumentation(IR, std::tuple(Args...)); + auto PA = PreservedAnalyses::all(); - for (int i = 0; i < Count; ++i) - PA.intersect(P.run(Arg, AM, std::forward(Args)...)); + for (int i = 0; i < Count; ++i) { + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns + // false). + if (!PI.runBeforePass(&P, IR)) + continue; + PA.intersect(P.run(IR, AM, std::forward(Args)...)); + PI.runAfterPass(&P, IR); + } return PA; } Index: include/llvm/IR/PassManagerInternal.h =================================================================== --- include/llvm/IR/PassManagerInternal.h +++ include/llvm/IR/PassManagerInternal.h @@ -32,6 +32,8 @@ /// Implementation details of the pass manager interfaces. namespace detail { +using PassInstancePtr = const void *; + /// Template for the abstract base class used to dispatch /// polymorphically over pass objects. template @@ -49,6 +51,8 @@ /// Polymorphic method to access the name of a pass. virtual StringRef name() = 0; + + virtual PassInstancePtr getPassInstance() const = 0; }; /// A template wrapper used to implement the polymorphic API. @@ -82,6 +86,8 @@ StringRef name() override { return PassT::name(); } + PassInstancePtr getPassInstance() const override { return &Pass; } + PassT Pass; }; @@ -290,7 +296,8 @@ AnalysisResultConcept> run(IRUnitT &IR, AnalysisManager &AM, ExtraArgTs... ExtraArgs) override { - return llvm::make_unique(Pass.run(IR, AM, ExtraArgs...)); + return llvm::make_unique( + Pass.run(IR, AM, std::forward(ExtraArgs)...)); } /// The model delegates to a static \c PassT::name method. Index: include/llvm/Passes/PassBuilder.h =================================================================== --- include/llvm/Passes/PassBuilder.h +++ include/llvm/Passes/PassBuilder.h @@ -58,6 +58,9 @@ class PassBuilder { TargetMachine *TM; Optional PGOOpt; + std::unique_ptr PIImpl; + + PassInstrumentationImpl *getPassInst() const { return PIImpl.get(); } public: /// A struct to capture parsed pass pipeline names. @@ -555,6 +558,15 @@ TopLevelPipelineParsingCallbacks.push_back(C); } + /// Manages \p PIImpl object and calls registration function \p C on it + /// to register pass instrumentation callbacks there. + void registerPassInstrumentation( + const std::function &C) { + if (!PIImpl.get()) + PIImpl = llvm::make_unique(); + C(*PIImpl.get()); + } + private: static Optional> parsePipelineText(StringRef Text); Index: include/llvm/Transforms/Scalar/LoopPassManager.h =================================================================== --- include/llvm/Transforms/Scalar/LoopPassManager.h +++ include/llvm/Transforms/Scalar/LoopPassManager.h @@ -71,6 +71,8 @@ extern template class PassManager; +extern template class PassInstrumentationAnalysis; + /// The Loop pass manager. /// /// See the documentation for the PassManager template for details. It runs @@ -276,8 +278,16 @@ // pass pipeline to put loops into their canonical form. Note that we can // directly build up function analyses after this as the function pass // manager handles all the invalidation at that layer. + PassInstrumentation PI = AM.getPassInstrumentation(F); + + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass. Canonicalization is not skippable, so ignore the return value. + (void)PI.runBeforePass(&LoopCanonicalizationFPM, F); + PreservedAnalyses PA = LoopCanonicalizationFPM.run(F, AM); + PI.runAfterPass(&LoopCanonicalizationFPM, F); + // Get the loop structure for this function LoopInfo &LI = AM.getResult(F); @@ -321,6 +331,9 @@ // FIXME: Consider changing the order in LoopInfo. internal::appendLoopsToWorklist(reverse(LI), Worklist); + // Copy PassInstrumentation to PassInstrumentation + PassInstrumentation PIL = PI; + do { Loop *L = Worklist.pop_back_val(); @@ -337,8 +350,14 @@ assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) && "Loops must remain in LCSSA form!"); #endif - + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns false). + if (!PIL.runBeforePass(&Pass, *L)) + continue; PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater); + + PIL.runAfterPass(&Pass, *L); + // FIXME: We should verify the set of analyses relevant to Loop passes // are preserved. Index: lib/Analysis/CGSCCPassManager.cpp =================================================================== --- lib/Analysis/CGSCCPassManager.cpp +++ lib/Analysis/CGSCCPassManager.cpp @@ -45,6 +45,7 @@ template class OuterAnalysisManagerProxy; template class OuterAnalysisManagerProxy; +template class PassInstrumentationAnalysis; /// Explicitly specialize the pass manager run method to handle call graph /// updates. @@ -54,6 +55,11 @@ CGSCCUpdateResult &>::run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM, LazyCallGraph &G, CGSCCUpdateResult &UR) { + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + PassInstrumentation PI = + AM.getPassInstrumentation(InitialC, G); + PreservedAnalyses PA = PreservedAnalyses::all(); if (DebugLogging) @@ -67,8 +73,15 @@ if (DebugLogging) dbgs() << "Running pass: " << Pass->name() << " on " << *C << "\n"; + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns false). + if (!PI.runBeforePass(Pass.get(), *C)) + continue; + PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR); + PI.runAfterPass(Pass.get(), *C); + // Update the SCC if necessary. C = UR.UpdatedC ? UR.UpdatedC : C; Index: lib/IR/CMakeLists.txt =================================================================== --- lib/IR/CMakeLists.txt +++ lib/IR/CMakeLists.txt @@ -42,6 +42,7 @@ Operator.cpp OptBisect.cpp Pass.cpp + PassInstrumentation.cpp PassManager.cpp PassRegistry.cpp PassTimingInfo.cpp Index: lib/IR/PassInstrumentation.cpp =================================================================== --- /dev/null +++ lib/IR/PassInstrumentation.cpp @@ -0,0 +1,68 @@ +//===- PassInstrumentation.h - Pass Instrumentation interface ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/PassInstrumentation.h" +#include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +template +bool PassInstrumentationImpl::runBeforePass(PassInstanceID PassID, + const IRUnitT &IR) const { + ++PC; + + bool shouldRun = true; + + for (auto &C : BeforePassCallbacks) + shouldRun &= C(PassID, llvm::Any(&IR), PC); + return shouldRun; +} + +template +void PassInstrumentationImpl::runAfterPass(PassInstanceID PassID, + const IRUnitT &IR) const { + for (auto &C : AfterPassCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + +void PassInstrumentationImpl::startPipeline() const { + for (auto &C : StartPipelineCallbacks) + C(); +} + +void PassInstrumentationImpl::endPipeline() const { + for (auto &C : EndPipelineCallbacks) + C(); +} + +template bool PassInstrumentationImpl::runBeforePass(PassInstanceID PassID, + const Module &IR) const; +template bool PassInstrumentationImpl::runBeforePass(PassInstanceID PassID, + const Function &IR) const; +template bool PassInstrumentationImpl::runBeforePass(PassInstanceID PassID, + const Loop &IR) const; +template bool +PassInstrumentationImpl::runBeforePass(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; +template void PassInstrumentationImpl::runAfterPass(PassInstanceID PassID, + const Module &IR) const; +template void PassInstrumentationImpl::runAfterPass(PassInstanceID PassID, + const Function &IR) const; +template void PassInstrumentationImpl::runAfterPass(PassInstanceID PassID, + const Loop &IR) const; +template void +PassInstrumentationImpl::runAfterPass(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; + +template class PassInstrumentationAnalysis; +template class PassInstrumentationAnalysis; + +} // namespace llvm Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -315,6 +315,10 @@ MAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + MAM.registerPass([&] { + return PassInstrumentationAnalysis(*this->getPassInst()); + }); + for (auto &C : ModuleAnalysisRegistrationCallbacks) C(MAM); } @@ -324,6 +328,11 @@ CGAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + CGAM.registerPass([&] { + return PassInstrumentationAnalysis( + *this->getPassInst()); + }); + for (auto &C : CGSCCAnalysisRegistrationCallbacks) C(CGAM); } @@ -333,6 +342,10 @@ FAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + FAM.registerPass([&] { + return PassInstrumentationAnalysis(*this->getPassInst()); + }); + for (auto &C : FunctionAnalysisRegistrationCallbacks) C(FAM); } @@ -342,6 +355,9 @@ LAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + LAM.registerPass( + [&] { return PassInstrumentationAnalysis(*this->getPassInst()); }); + for (auto &C : LoopAnalysisRegistrationCallbacks) C(LAM); } Index: lib/Transforms/Scalar/LoopPassManager.cpp =================================================================== --- lib/Transforms/Scalar/LoopPassManager.cpp +++ lib/Transforms/Scalar/LoopPassManager.cpp @@ -18,6 +18,8 @@ template class PassManager; +template class PassInstrumentationAnalysis; + /// Explicitly specialize the pass manager's run method to handle loop nest /// structure updates. template <> @@ -30,12 +32,22 @@ if (DebugLogging) dbgs() << "Starting Loop pass manager run.\n"; + // Request PassInstrumentation from analysis manager, will use it to run + // instrumenting callbacks for the passes later. + PassInstrumentation PI = AM.getPassInstrumentation(L, AR); for (auto &Pass : Passes) { if (DebugLogging) dbgs() << "Running pass: " << Pass->name() << " on " << L; + // Check the PassInstrumentation's BeforePass callbacks before running the + // pass, skip its execution completely if asked to (callback returns false). + if (!PI.runBeforePass(Pass.get(), L)) + continue; + PreservedAnalyses PassPA = Pass->run(L, AM, AR, U); + PI.runAfterPass(Pass.get(), L); + // If the loop was deleted, abort the run and return to the outer walk. if (U.skipCurrentLoop()) { PA.intersect(std::move(PassPA)); Index: test/Other/loop-pm-invalidation.ll =================================================================== --- test/Other/loop-pm-invalidation.ll +++ test/Other/loop-pm-invalidation.ll @@ -73,6 +73,7 @@ ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}LoopAnalysis @@ -90,6 +91,7 @@ ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run. @@ -108,6 +110,7 @@ ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis @@ -123,6 +126,7 @@ ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run. @@ -153,9 +157,11 @@ ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}LoopAnalysis @@ -174,9 +180,11 @@ ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run. @@ -195,9 +203,11 @@ ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis @@ -214,9 +224,11 @@ ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run. @@ -254,6 +266,7 @@ ; CHECK-LOOP-INV-NEXT: Running analysis: TargetIRAnalysis ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}LoopAnalysis @@ -271,6 +284,7 @@ ; CHECK-LOOP-INV-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-LOOP-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-LOOP-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-LOOP-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-LOOP-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-LOOP-INV-NEXT: Finished {{.*}}Function pass manager run. @@ -289,6 +303,7 @@ ; CHECK-SCEV-INV-NEXT: Running analysis: TargetIRAnalysis ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis @@ -304,6 +319,7 @@ ; CHECK-SCEV-INV-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-SCEV-INV-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Loop pass manager run. ; CHECK-SCEV-INV-NEXT: Finished {{.*}}Function pass manager run. @@ -322,6 +338,7 @@ ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: TargetIRAnalysis ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Loop ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Starting {{.*}}Loop pass manager run. +; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: NoOpLoopPass ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: LoopDeletionPass ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Clearing all analysis results for: Index: test/Other/new-pass-manager.ll =================================================================== --- test/Other/new-pass-manager.ll +++ test/Other/new-pass-manager.ll @@ -24,6 +24,7 @@ ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module> ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis ; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-CGSCC-PASS-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}LazyCallGraph::SCC> ; CHECK-CGSCC-PASS-NEXT: Starting CGSCC pass manager run ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass ; CHECK-CGSCC-PASS-NEXT: Finished CGSCC pass manager run @@ -38,6 +39,7 @@ ; CHECK-FUNCTION-PASS: Starting llvm::Module pass manager run ; CHECK-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor ; CHECK-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}> +; CHECK-FUNCTION-PASS-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run ; CHECK-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass ; CHECK-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run @@ -408,6 +410,7 @@ ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module> ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}LazyCallGraph::SCC> ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatedPass ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run @@ -428,6 +431,7 @@ ; CHECK-REPEAT-FUNCTION-PASS: Starting llvm::Module pass manager run ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}> +; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: RepeatedPass ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run @@ -448,6 +452,7 @@ ; CHECK-REPEAT-LOOP-PASS: Starting llvm::Module pass manager run ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}> +; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: FunctionToLoopPassAdaptor ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run @@ -464,6 +469,7 @@ ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetIRAnalysis ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}> ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run +; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: RepeatedPass ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting Loop pass manager run ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass Index: test/Other/new-pm-defaults.ll =================================================================== --- test/Other/new-pm-defaults.ll +++ test/Other/new-pm-defaults.ll @@ -67,7 +67,8 @@ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ ; RUN: --check-prefix=CHECK-EP-PIPELINE-START -; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O: Running analysis: PassInstrumentationAnalysis<{{.*}}Module> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass @@ -78,6 +79,7 @@ ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-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 @@ -110,6 +112,7 @@ ; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Starting CGSCC pass manager run. ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}> @@ -145,6 +148,7 @@ ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Starting Loop pass manager run. +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass ; CHECK-O-NEXT: Running pass: LoopRotatePass Index: test/Other/new-pm-lto-defaults.ll =================================================================== --- test/Other/new-pm-lto-defaults.ll +++ test/Other/new-pm-lto-defaults.ll @@ -23,7 +23,8 @@ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 \ ; RUN: --check-prefix=CHECK-O3 --check-prefix=CHECK-EP-Peephole -; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O: Running analysis: PassInstrumentationAnalysis<{{.*}}Module> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: GlobalDCEPass @@ -32,6 +33,7 @@ ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-O2-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Module +; CHECK-O2-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Function> ; CHECK-O2-NEXT: Starting llvm::Function pass manager run. ; CHECK-O2-NEXT: Running pass: CallSiteSplittingPass on foo ; CHECK-O2-NEXT: Running analysis: TargetLibraryAnalysis on foo Index: test/Other/new-pm-thinlto-defaults.ll =================================================================== --- test/Other/new-pm-thinlto-defaults.ll +++ test/Other/new-pm-thinlto-defaults.ll @@ -47,7 +47,8 @@ ; RUN: -passes='thinlto' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-POSTLINK-O,CHECK-POSTLINK-O2 ; -; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O: Running analysis: PassInstrumentationAnalysis<{{.*}}Module> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass @@ -64,6 +65,7 @@ ; 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-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis @@ -95,6 +97,7 @@ ; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}LazyCallGraph{{.*}}> ; CHECK-O-NEXT: Starting CGSCC pass manager run. ; CHECK-O-NEXT: Running pass: InlinerPass ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}> @@ -129,6 +132,7 @@ ; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Starting Loop pass manager run. +; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> ; CHECK-O-NEXT: Running pass: LoopInstSimplifyPass ; CHECK-O-NEXT: Running pass: LoopSimplifyCFGPass ; CHECK-O-NEXT: Running pass: LoopRotatePass Index: test/Transforms/Inline/cgscc-incremental-invalidate.ll =================================================================== --- test/Transforms/Inline/cgscc-incremental-invalidate.ll +++ test/Transforms/Inline/cgscc-incremental-invalidate.ll @@ -33,7 +33,8 @@ ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_g ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_g ; CHECK-NEXT: Finished llvm::Function pass manager run. -; CHECK-NEXT: Starting llvm::Function pass manager run. +; CHECK-NOT: Invalidating analysis: +; CHECK: Starting llvm::Function pass manager run. ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_h ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_h ; CHECK-NEXT: Finished llvm::Function pass manager run. Index: test/Transforms/LoopRotate/pr35210.ll =================================================================== --- test/Transforms/LoopRotate/pr35210.ll +++ test/Transforms/LoopRotate/pr35210.ll @@ -21,6 +21,7 @@ ; CHECK-NEXT: Running analysis: TargetIRAnalysis on f ; CHECK-NEXT: Running analysis: InnerAnalysisManagerProxy{{.*}} on f ; CHECK-NEXT: Starting Loop pass manager run. +; CHECK-NEXT: Running analysis: PassInstrumentationAnalysis<{{.*}}Loop> on bb ; CHECK-NEXT: Running pass: LoopRotatePass on Loop at depth 1 containing: %bb
,%bb4 ; CHECK-NEXT: Folding loop latch bb4 into bb ; CHECK-NEXT: Invalidating all non-preserved analyses for: bb