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 PassInstrumentationProxy; + /// 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,18 @@ 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 && !PI->runBeforePass(&Pass, *C)) + continue; + PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR); + if (PI) + 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 +631,21 @@ if (CG.lookupSCC(*N) != CurrentC) continue; - PreservedAnalyses PassPA = Pass.run(N->getFunction(), FAM); + Function &F = N->getFunction(); + + PassInstrumentation *PI = FAM.getPassInstrumentation(F); + if (PI && !PI->runBeforePass(&Pass, F)) + continue; + + PreservedAnalyses PassPA = Pass.run(F, FAM); + + if (PI) + 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 +715,7 @@ 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 +759,15 @@ auto CallCounts = ScanSCC(*C, CallHandles); for (int Iteration = 0;; ++Iteration) { + + if (PI && !PI->runBeforePass(&Pass, *C)) + continue; + PreservedAnalyses PassPA = Pass.run(*C, AM, CG, UR); + if (PI) + 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,211 @@ +//===- 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 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 +/// +/// PassInstrumentation object is intended to have no copies, being +/// a single reference point for instrumentation throughout the compilation. +/// +/// 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 PassInstrumentationProxy analysis (see PassManager.h) with +/// Pass +/// Manager. PassBuilder provides helpers for that. +/// +/// - Pass Manager requests PassInstrumentationProxy from analysis manager +/// and gets a pointer to 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 (BeforePass) 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++; } +}; + +namespace detail { + +// Forward declaration for PassConcept, wrapper for pass instances in new pass +// manager. +template +struct PassConcept; + +} // namespace detail + +/// This class is an opaque wrapper over any 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(detail::PassConcept *P) + : Name(P->name()), Pass(P->getPassInstance()) {} + + /// Constructor that unwraps const PassConcept object by calling + /// getPassInstance member. + template + PassInstanceID(const detail::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) {} + + bool operator==(const PassInstanceID& P) const { + return Name == P.Name && Pass == P.Pass; + } + + /// Returns the name of the pass + StringRef getName() const { return Name; } + + /// Returns an opaque pointer that identifies the Pass Instance + /// in current pipeline. + /// NB: this pointer is not necessarily unique! use a pair of Name/Instance if you + /// need a unique identifier. + const void *getInstance() const { return Pass; } + + bool emptyInstance() const { return Pass == nullptr; } +}; + +/// This class provides 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 PassInstrumentation { +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: + PassInstrumentation() {} + + /// Copying PassInstrumentation is not intended. + PassInstrumentation(const PassInstrumentation &) = delete; + void operator=(const PassInstrumentation &) = delete; + + /// 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); + } + + bool empty() const; + +private: + mutable PassExecutionCounter PC; + + // instrumentation callbacks + + SmallVector, 4> BeforePassCallbacks; + SmallVector, 4> AfterPassCallbacks; + SmallVector, 2> StartPipelineCallbacks; + SmallVector, 2> EndPipelineCallbacks; +}; + +} // 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 PassInstrumentationProxy analysis template. +template class PassInstrumentationProxy; + /// 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,19 @@ 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 && !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. + if (PI) + PI->runAfterPass(Passes[Idx].get(), IR); + // Update the analysis manager as each pass runs and potentially // invalidates analyses. AM.invalidate(IR, PassPA); @@ -680,6 +700,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 + /// PassInstrumentationProxy. + PassInstrumentation *getPassInstrumentation(IRUnitT &IR, + ExtraArgTs... ExtraArgs) { + // avoid failing when analysis is not registered (mostly for tests). + if (!isRegisteredAnalysis>()) + return nullptr; + 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 +916,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 +1204,49 @@ const AnalysisManagerT *AM; }; +/// Pseudo-analysis pass that exposes the \c PassInstrumentation for IRUnit +/// being processed. +template +class PassInstrumentationProxy + : public AnalysisInfoMixin> { + friend AnalysisInfoMixin>; + static AnalysisKey Key; + + /// Shared PassInstrumentation object. Owned by something else, not this + /// analysis. + PassInstrumentation *PI; + +public: + PassInstrumentationProxy(PassInstrumentation *_PI) : PI(_PI) {} + + /// A simple result object that passes pointer to PassInstrumentation. + class Result { + PassInstrumentation *PI; + + public: + explicit Result(PassInstrumentation *_PI) : PI(_PI) {} + operator PassInstrumentation *() const { return PI; } + + /// 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; + } + }; + + template + Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) { + return Result(PI); + } +}; + +template AnalysisKey PassInstrumentationProxy::Key; + +extern template class PassInstrumentationProxy; +extern template class PassInstrumentationProxy; + template AnalysisKey OuterAnalysisManagerProxy::Key; @@ -1192,13 +1292,25 @@ 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 && !PI->runBeforePass(&Pass, F)) + continue; PreservedAnalyses PassPA = Pass.run(F, FAM); + if (PI) + 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 +1414,26 @@ 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 && !PI->runBeforePass(&P, IR)) + continue; + PA.intersect(P.run(IR, AM, std::forward(Args)...)); + if (PI) + 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,11 @@ class PassBuilder { TargetMachine *TM; Optional PGOOpt; + PassInstrumentation *PI; + + PassInstrumentation *getPassInstrumentationIfNotEmpty() const { + return PI && !PI->empty() ? PI : nullptr; + } public: /// A struct to capture parsed pass pipeline names. @@ -172,8 +177,9 @@ }; explicit PassBuilder(TargetMachine *TM = nullptr, - Optional PGOOpt = None) - : TM(TM), PGOOpt(PGOOpt) {} + Optional PGOOpt = None, + PassInstrumentation *PI = nullptr) + : TM(TM), PGOOpt(PGOOpt), PI(PI) {} /// Cross register the analysis managers through their proxies. /// @@ -555,6 +561,15 @@ TopLevelPipelineParsingCallbacks.push_back(C); } + /// Calls registration function \p C on PassInstrumentation object + /// to register pass instrumentation callbacks there. + void registerPassInstrumentation( + const std::function &C) { + assert(PI && + "PassInstrumentation object is not available for registration"); + C(*PI); + } + 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 PassInstrumentationProxy; + /// The Loop pass manager. /// /// See the documentation for the PassManager template for details. It runs @@ -276,7 +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. - PreservedAnalyses PA = LoopCanonicalizationFPM.run(F, AM); + PassInstrumentation *PI = AM.getPassInstrumentation(F); + + PreservedAnalyses PA = PreservedAnalyses::all(); + // Check the PassInstrumentation's BeforePass callbacks before running the + // canonicalization pipeline. + if (!PI || PI->runBeforePass(&LoopCanonicalizationFPM, F)) { + PA = LoopCanonicalizationFPM.run(F, AM); + if (PI) + PI->runAfterPass(&LoopCanonicalizationFPM, F); + } // Get the loop structure for this function LoopInfo &LI = AM.getResult(F); @@ -337,8 +348,16 @@ 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 (PI && !PI->runBeforePass(&Pass, *L)) + continue; PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater); + + if (PI) + PI->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 PassInstrumentationProxy; /// Explicitly specialize the pass manager run method to handle call graph /// updates. @@ -54,6 +55,10 @@ 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 +72,16 @@ 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 && !PI->runBeforePass(Pass.get(), *C)) + continue; + PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR); + if (PI) + 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,73 @@ +//===- 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 PassInstrumentation::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 PassInstrumentation::runAfterPass(PassInstanceID PassID, + const IRUnitT &IR) const { + for (auto &C : AfterPassCallbacks) + C(PassID, llvm::Any(&IR), PC); +} + +void PassInstrumentation::startPipeline() const { + for (auto &C : StartPipelineCallbacks) + C(); +} + +void PassInstrumentation::endPipeline() const { + for (auto &C : EndPipelineCallbacks) + C(); +} + +bool PassInstrumentation::empty() const { + return BeforePassCallbacks.empty() && AfterPassCallbacks.empty() && + StartPipelineCallbacks.empty() && EndPipelineCallbacks.empty(); +} + +template bool PassInstrumentation::runBeforePass(PassInstanceID PassID, + const Module &IR) const; +template bool PassInstrumentation::runBeforePass(PassInstanceID PassID, + const Function &IR) const; +template bool PassInstrumentation::runBeforePass(PassInstanceID PassID, + const Loop &IR) const; +template bool +PassInstrumentation::runBeforePass(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; +template void PassInstrumentation::runAfterPass(PassInstanceID PassID, + const Module &IR) const; +template void PassInstrumentation::runAfterPass(PassInstanceID PassID, + const Function &IR) const; +template void PassInstrumentation::runAfterPass(PassInstanceID PassID, + const Loop &IR) const; +template void +PassInstrumentation::runAfterPass(PassInstanceID PassID, + const LazyCallGraph::SCC &IR) const; + +template class PassInstrumentationProxy; +template class PassInstrumentationProxy; + +} // namespace llvm Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -315,6 +315,11 @@ MAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + MAM.registerPass([&] { + return PassInstrumentationProxy( + this->getPassInstrumentationIfNotEmpty()); + }); + for (auto &C : ModuleAnalysisRegistrationCallbacks) C(MAM); } @@ -324,6 +329,11 @@ CGAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + CGAM.registerPass([&] { + return PassInstrumentationProxy( + this->getPassInstrumentationIfNotEmpty()); + }); + for (auto &C : CGSCCAnalysisRegistrationCallbacks) C(CGAM); } @@ -333,6 +343,11 @@ FAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + FAM.registerPass([&] { + return PassInstrumentationProxy( + this->getPassInstrumentationIfNotEmpty()); + }); + for (auto &C : FunctionAnalysisRegistrationCallbacks) C(FAM); } @@ -342,6 +357,11 @@ LAM.registerPass([&] { return CREATE_PASS; }); #include "PassRegistry.def" + LAM.registerPass([&] { + return PassInstrumentationProxy( + this->getPassInstrumentationIfNotEmpty()); + }); + 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 PassInstrumentationProxy; + /// Explicitly specialize the pass manager's run method to handle loop nest /// structure updates. template <> @@ -30,12 +32,23 @@ 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 && !PI->runBeforePass(Pass.get(), L)) + continue; + PreservedAnalyses PassPA = Pass->run(L, AM, AR, U); + if (PI) + 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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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: PassInstrumentationProxy<{{.*}}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