From: Chandler Carruth Date: Wed, 20 Nov 2013 04:01:38 +0000 (+0000) Subject: [PM] Split the analysis manager into a function-specific interface and X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=523d929368829b5157748f46f85b4577b7fd6ca1;p=oota-llvm.git [PM] Split the analysis manager into a function-specific interface and a module-specific interface. This is the first of many steps necessary to generalize the infrastructure such that we can support both a Module-to-Function and Module-to-SCC-to-Function pass manager nestings. After a *lot* of attempts that never worked and didn't even make it to a committable state, it became clear that I had gotten the layering design of analyses flat out wrong. Four days later, I think I have most of the plan for how to correct this, and I'm starting to reshape the code into it. This is just a baby step I'm afraid, but starts separating the fundamentally distinct concepts of function analysis passes and module analysis passes so that in subsequent steps we can effectively layer them, and have a consistent design for the eventual SCC layer. As part of this, I've started some interface changes to make passes more regular. The module pass accepts the module in the run method, and some of the constructor parameters are gone. I'm still working out exactly where constructor parameters vs. method parameters will be used, so I expect this to fluctuate a bit. This actually makes the invalidation less "correct" at this phase, because now function passes don't invalidate module analysis passes, but that was actually somewhat of a misfeature. It will return in a better factored form which can scale to other units of IR. The documentation has gotten less verbose and helpful. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195189 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 833547a23ac..4a64f20c49a 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -74,20 +74,99 @@ template struct PassModel : PassConcept { PassT Pass; }; +/// \brief Abstract concept of an analysis result. +/// +/// This concept is parameterized over the IR unit that this result pertains +/// to. +template struct AnalysisResultConcept { + virtual ~AnalysisResultConcept() {} + virtual AnalysisResultConcept *clone() = 0; + + /// \brief Method to try and mark a result as invalid. + /// + /// When the outer \c AnalysisManager detects a change in some underlying + /// unit of the IR, it will call this method on all of the results cached. + /// + /// \returns true if the result should indeed be invalidated (the default). + virtual bool invalidate(IRUnitT *IR) = 0; +}; + +/// \brief Wrapper to model the analysis result concept. +/// +/// Can wrap any type which implements a suitable invalidate member and model +/// the AnalysisResultConcept for the AnalysisManager. +template +struct AnalysisResultModel : AnalysisResultConcept { + AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {} + virtual AnalysisResultModel *clone() { + return new AnalysisResultModel(Result); + } + + /// \brief The model delegates to the \c ResultT method. + virtual bool invalidate(IRUnitT *IR) { return Result.invalidate(IR); } + + ResultT Result; +}; + +/// \brief Abstract concept of an analysis pass. +/// +/// This concept is parameterized over the IR unit that it can run over and +/// produce an analysis result. +template struct AnalysisPassConcept { + virtual ~AnalysisPassConcept() {} + virtual AnalysisPassConcept *clone() = 0; + + /// \brief Method to run this analysis over a unit of IR. + /// \returns The analysis result object to be queried by users, the caller + /// takes ownership. + virtual AnalysisResultConcept *run(IRUnitT *IR) = 0; +}; + +/// \brief Wrapper to model the analysis pass concept. +/// +/// Can wrap any type which implements a suitable \c run method. The method +/// must accept the IRUnitT as an argument and produce an object which can be +/// wrapped in a \c AnalysisResultModel. +template +struct AnalysisPassModel : AnalysisPassConcept { + AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {} + virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); } + + // FIXME: Replace PassT::IRUnitT with type traits when we use C++11. + typedef typename PassT::IRUnitT IRUnitT; + + // FIXME: Replace PassT::Result with type traits when we use C++11. + typedef AnalysisResultModel ResultModelT; + + /// \brief The model delegates to the \c PassT::run method. + /// + /// The return is wrapped in an \c AnalysisResultModel. + virtual ResultModelT *run(IRUnitT *IR) { + return new ResultModelT(Pass.run(IR)); + } + + PassT Pass; +}; + } -class AnalysisManager; +class ModuleAnalysisManager; class ModulePassManager { public: - ModulePassManager(Module *M, AnalysisManager *AM = 0) : M(M), AM(AM) {} + explicit ModulePassManager(ModuleAnalysisManager *AM = 0) : AM(AM) {} + + /// \brief Run all of the module passes in this module pass manager over + /// a module. + /// + /// This method should only be called for a single module as there is the + /// expectation that the lifetime of a pass is bounded to that of a module. + void run(Module *M); template void addPass(ModulePassT Pass) { Passes.push_back(new ModulePassModel(llvm_move(Pass))); } - void run(); - private: // Pull in the concept type and model template specialized for modules. typedef detail::PassConcept ModulePassConcept; @@ -96,14 +175,15 @@ private: ModulePassModel(PassT Pass) : detail::PassModel(Pass) {} }; - Module *M; - AnalysisManager *AM; + ModuleAnalysisManager *AM; std::vector > Passes; }; +class FunctionAnalysisManager; + class FunctionPassManager { public: - FunctionPassManager(AnalysisManager *AM = 0) : AM(AM) {} + explicit FunctionPassManager(FunctionAnalysisManager *AM = 0) : AM(AM) {} template void addPass(FunctionPassT Pass) { Passes.push_back(new FunctionPassModel(llvm_move(Pass))); @@ -120,58 +200,30 @@ private: : detail::PassModel(Pass) {} }; - AnalysisManager *AM; + FunctionAnalysisManager *AM; std::vector > Passes; }; - -/// \brief An analysis manager to coordinate and cache analyses run over -/// a module. -/// -/// The analysis manager is typically used by passes in a pass pipeline -/// (consisting potentially of several individual pass managers) over a module -/// of IR. It provides registration of available analyses, declaring -/// requirements on support for specific analyses, running of an specific -/// analysis over a specific unit of IR to compute an analysis result, and -/// caching of the analysis results to reuse them across multiple passes. -/// -/// It is the responsibility of callers to use the invalidation API to -/// invalidate analysis results when the IR they correspond to changes. The -/// \c ModulePassManager and \c FunctionPassManager do this automatically. -class AnalysisManager { +/// \brief A module analysis pass manager with lazy running and caching of +/// results. +class ModuleAnalysisManager { public: - AnalysisManager(Module *M) : M(M) {} + ModuleAnalysisManager() {} /// \brief Get the result of an analysis pass for this module. /// /// If there is not a valid cached result in the manager already, this will /// re-run the analysis to produce a valid result. - /// - /// The module passed in must be the same module as the analysis manager was - /// constructed around. - template - const typename PassT::Result &getResult(Module *M) { + template const typename PassT::Result &getResult(Module *M) { + LLVM_STATIC_ASSERT((is_same::value), + "The analysis pass must be over a Module."); assert(ModuleAnalysisPasses.count(PassT::ID()) && "This analysis pass was not registered prior to being queried"); - const AnalysisResultConcept &ResultConcept = + const detail::AnalysisResultConcept &ResultConcept = getResultImpl(PassT::ID(), M); - typedef AnalysisResultModel ResultModelT; - return static_cast(ResultConcept).Result; - } - - /// \brief Get the result of an analysis pass for a function. - /// - /// If there is not a valid cached result in the manager already, this will - /// re-run the analysis to produce a valid result. - template - const typename PassT::Result &getResult(Function *F) { - assert(FunctionAnalysisPasses.count(PassT::ID()) && - "This analysis pass was not registered prior to being queried"); - - const AnalysisResultConcept &ResultConcept = - getResultImpl(PassT::ID(), F); - typedef AnalysisResultModel ResultModelT; + typedef detail::AnalysisResultModel + ResultModelT; return static_cast(ResultConcept).Result; } @@ -182,24 +234,26 @@ public: /// manager. Whomever is setting up analysis passes must use this to /// populate /// the manager with all of the analysis passes available. - template void registerAnalysisPass(PassT Pass) { - registerAnalysisPassImpl(llvm_move(Pass)); + template void registerPass(PassT Pass) { + LLVM_STATIC_ASSERT((is_same::value), + "The analysis pass must be over a Module."); + assert(!ModuleAnalysisPasses.count(PassT::ID()) && + "Registered the same analysis pass twice!"); + ModuleAnalysisPasses[PassT::ID()] = + new detail::AnalysisPassModel(llvm_move(Pass)); } /// \brief Invalidate a specific analysis pass for an IR module. /// /// Note that the analysis result can disregard invalidation. template void invalidate(Module *M) { + LLVM_STATIC_ASSERT((is_same::value), + "The analysis pass must be over a Module."); + assert(ModuleAnalysisPasses.count(PassT::ID()) && + "This analysis pass was not registered prior to being invalidated"); invalidateImpl(PassT::ID(), M); } - /// \brief Invalidate a specific analysis pass for an IR function. - /// - /// Note that the analysis result can disregard invalidation. - template void invalidate(Function *F) { - invalidateImpl(PassT::ID(), F); - } - /// \brief Invalidate analyses cached for an IR Module. /// /// Note that specific analysis results can disregard invalidation by @@ -209,141 +263,100 @@ public: /// around. void invalidateAll(Module *M); - /// \brief Invalidate analyses cached for an IR Function. - /// - /// Note that specific analysis results can disregard invalidation by - /// overriding the invalidate method. - void invalidateAll(Function *F); - private: - /// \brief Abstract concept of an analysis result. - /// - /// This concept is parameterized over the IR unit that this result pertains - /// to. - template struct AnalysisResultConcept { - virtual ~AnalysisResultConcept() {} - virtual AnalysisResultConcept *clone() = 0; - - /// \brief Method to try and mark a result as invalid. - /// - /// When the outer \c AnalysisManager detects a change in some underlying - /// unit of the IR, it will call this method on all of the results cached. - /// - /// \returns true if the result should indeed be invalidated (the default). - virtual bool invalidate(IRUnitT *IR) = 0; - }; - - /// \brief Wrapper to model the analysis result concept. - /// - /// Can wrap any type which implements a suitable invalidate member and model - /// the AnalysisResultConcept for the AnalysisManager. - template - struct AnalysisResultModel : AnalysisResultConcept { - AnalysisResultModel(ResultT Result) : Result(llvm_move(Result)) {} - virtual AnalysisResultModel *clone() { - return new AnalysisResultModel(Result); - } - - /// \brief The model delegates to the \c ResultT method. - virtual bool invalidate(IRUnitT *IR) { return Result.invalidate(IR); } - - ResultT Result; - }; - - /// \brief Abstract concept of an analysis pass. - /// - /// This concept is parameterized over the IR unit that it can run over and - /// produce an analysis result. - template struct AnalysisPassConcept { - virtual ~AnalysisPassConcept() {} - virtual AnalysisPassConcept *clone() = 0; - - /// \brief Method to run this analysis over a unit of IR. - /// \returns The analysis result object to be queried by users, the caller - /// takes ownership. - virtual AnalysisResultConcept *run(IRUnitT *IR) = 0; - }; - - /// \brief Wrapper to model the analysis pass concept. - /// - /// Can wrap any type which implements a suitable \c run method. The method - /// must accept the IRUnitT as an argument and produce an object which can be - /// wrapped in a \c AnalysisResultModel. - template - struct AnalysisPassModel : AnalysisPassConcept { - AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {} - virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); } - - // FIXME: Replace PassT::IRUnitT with type traits when we use C++11. - typedef typename PassT::IRUnitT IRUnitT; - - // FIXME: Replace PassT::Result with type traits when we use C++11. - typedef AnalysisResultModel ResultModelT; - - /// \brief The model delegates to the \c PassT::run method. - /// - /// The return is wrapped in an \c AnalysisResultModel. - virtual ResultModelT *run(IRUnitT *IR) { - return new ResultModelT(Pass.run(IR)); - } - - PassT Pass; - }; - - /// \brief Get a module pass result, running the pass if necessary. - const AnalysisResultConcept &getResultImpl(void *PassID, Module *M); - - /// \brief Get a function pass result, running the pass if necessary. - const AnalysisResultConcept &getResultImpl(void *PassID, - Function *F); + const detail::AnalysisResultConcept &getResultImpl(void *PassID, + Module *M); /// \brief Invalidate a module pass result. void invalidateImpl(void *PassID, Module *M); - /// \brief Invalidate a function pass result. - void invalidateImpl(void *PassID, Function *F); + /// \brief Map type from module analysis pass ID to pass concept pointer. + typedef DenseMap > > + ModuleAnalysisPassMapT; + + /// \brief Collection of module analysis passes, indexed by ID. + ModuleAnalysisPassMapT ModuleAnalysisPasses; + /// \brief Map type from module analysis pass ID to pass result concept pointer. + typedef DenseMap > > + ModuleAnalysisResultMapT; + + /// \brief Cache of computed module analysis results for this module. + ModuleAnalysisResultMapT ModuleAnalysisResults; +}; - /// \brief Module pass specific implementation of registration. +/// \brief A function analysis manager to coordinate and cache analyses run over +/// a module. +class FunctionAnalysisManager { +public: + FunctionAnalysisManager() {} + + /// \brief Get the result of an analysis pass for a function. + /// + /// If there is not a valid cached result in the manager already, this will + /// re-run the analysis to produce a valid result. template - typename enable_if >::type - registerAnalysisPassImpl(PassT Pass) { - assert(!ModuleAnalysisPasses.count(PassT::ID()) && - "Registered the same analysis pass twice!"); - ModuleAnalysisPasses[PassT::ID()] = - new AnalysisPassModel(llvm_move(Pass)); + const typename PassT::Result &getResult(Function *F) { + LLVM_STATIC_ASSERT((is_same::value), + "The analysis pass must be over a Function."); + assert(FunctionAnalysisPasses.count(PassT::ID()) && + "This analysis pass was not registered prior to being queried"); + + const detail::AnalysisResultConcept &ResultConcept = + getResultImpl(PassT::ID(), F); + typedef detail::AnalysisResultModel + ResultModelT; + return static_cast(ResultConcept).Result; } - /// \brief Function pass specific implementation of registration. - template - typename enable_if >::type - registerAnalysisPassImpl(PassT Pass) { + /// \brief Register an analysis pass with the manager. + /// + /// This provides an initialized and set-up analysis pass to the + /// analysis + /// manager. Whomever is setting up analysis passes must use this to + /// populate + /// the manager with all of the analysis passes available. + template void registerPass(PassT Pass) { + LLVM_STATIC_ASSERT((is_same::value), + "The analysis pass must be over a Function."); assert(!FunctionAnalysisPasses.count(PassT::ID()) && "Registered the same analysis pass twice!"); FunctionAnalysisPasses[PassT::ID()] = - new AnalysisPassModel(llvm_move(Pass)); + new detail::AnalysisPassModel(llvm_move(Pass)); } + /// \brief Invalidate a specific analysis pass for an IR module. + /// + /// Note that the analysis result can disregard invalidation. + template void invalidate(Function *F) { + LLVM_STATIC_ASSERT((is_same::value), + "The analysis pass must be over a Function."); + assert(FunctionAnalysisPasses.count(PassT::ID()) && + "This analysis pass was not registered prior to being invalidated"); + invalidateImpl(PassT::ID(), F); + } - /// \brief Map type from module analysis pass ID to pass concept pointer. - typedef DenseMap > > - ModuleAnalysisPassMapT; - - /// \brief Collection of module analysis passes, indexed by ID. - ModuleAnalysisPassMapT ModuleAnalysisPasses; - - /// \brief Map type from module analysis pass ID to pass result concept pointer. - typedef DenseMap > > - ModuleAnalysisResultMapT; + /// \brief Invalidate analyses cached for an IR Function. + /// + /// Note that specific analysis results can disregard invalidation by + /// overriding the invalidate method. + void invalidateAll(Function *F); - /// \brief Cache of computed module analysis results for this module. - ModuleAnalysisResultMapT ModuleAnalysisResults; +private: + /// \brief Get a function pass result, running the pass if necessary. + const detail::AnalysisResultConcept &getResultImpl(void *PassID, + Function *F); + /// \brief Invalidate a function pass result. + void invalidateImpl(void *PassID, Function *F); /// \brief Map type from function analysis pass ID to pass concept pointer. - typedef DenseMap > > - FunctionAnalysisPassMapT; + typedef DenseMap > > + FunctionAnalysisPassMapT; /// \brief Collection of function analysis passes, indexed by ID. FunctionAnalysisPassMapT FunctionAnalysisPasses; @@ -353,12 +366,13 @@ private: /// Requires iterators to be valid across appending new entries and arbitrary /// erases. Provides both the pass ID and concept pointer such that it is /// half of a bijection and provides storage for the actual result concept. - typedef std::list< - std::pair > > > - FunctionAnalysisResultListT; + typedef std::list > > > + FunctionAnalysisResultListT; /// \brief Map type from function pointer to our custom list type. - typedef DenseMap FunctionAnalysisResultListMapT; + typedef DenseMap + FunctionAnalysisResultListMapT; /// \brief Map from function to a list of function analysis results. /// @@ -370,14 +384,11 @@ private: /// iterator into a particular result list. typedef DenseMap, FunctionAnalysisResultListT::iterator> - FunctionAnalysisResultMapT; + FunctionAnalysisResultMapT; /// \brief Map from an analysis ID and function to a particular cached /// analysis result. FunctionAnalysisResultMapT FunctionAnalysisResults; - - /// \brief Module handle for the \c AnalysisManager. - Module *M; }; } diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index 966af7debc7..b53a2b9671d 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -12,27 +12,14 @@ using namespace llvm; -void ModulePassManager::run() { +void ModulePassManager::run(Module *M) { for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) if (Passes[Idx]->run(M)) - if (AM) AM->invalidateAll(M); + if (AM) + AM->invalidateAll(M); } -bool FunctionPassManager::run(Module *M) { - bool Changed = false; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) - if (Passes[Idx]->run(I)) { - Changed = true; - if (AM) AM->invalidateAll(I); - } - return Changed; -} - -void AnalysisManager::invalidateAll(Function *F) { - assert(F->getParent() == M && "Invalidating a function from another module!"); - - // First invalidate any module results we still have laying about. +void ModuleAnalysisManager::invalidateAll(Module *M) { // FIXME: This is a total hack based on the fact that erasure doesn't // invalidate iteration for DenseMap. for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), @@ -40,67 +27,14 @@ void AnalysisManager::invalidateAll(Function *F) { I != E; ++I) if (I->second->invalidate(M)) ModuleAnalysisResults.erase(I); - - // Now clear all the invalidated results associated specifically with this - // function. - SmallVector InvalidatedPassIDs; - FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; - for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), - E = ResultsList.end(); - I != E;) - if (I->second->invalidate(F)) { - InvalidatedPassIDs.push_back(I->first); - I = ResultsList.erase(I); - } else { - ++I; - } - while (!InvalidatedPassIDs.empty()) - FunctionAnalysisResults.erase( - std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); } -void AnalysisManager::invalidateAll(Module *M) { - // First invalidate any module results we still have laying about. - // FIXME: This is a total hack based on the fact that erasure doesn't - // invalidate iteration for DenseMap. - for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(), - E = ModuleAnalysisResults.end(); - I != E; ++I) - if (I->second->invalidate(M)) - ModuleAnalysisResults.erase(I); - - // Now walk all of the functions for which there are cached results, and - // attempt to invalidate each of those as the entire module may have changed. - // FIXME: How do we handle functions which have been deleted or RAUWed? - SmallVector InvalidatedPassIDs; - for (FunctionAnalysisResultListMapT::iterator - FI = FunctionAnalysisResultLists.begin(), - FE = FunctionAnalysisResultLists.end(); - FI != FE; ++FI) { - Function *F = FI->first; - FunctionAnalysisResultListT &ResultsList = FI->second; - for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), - E = ResultsList.end(); - I != E;) - if (I->second->invalidate(F)) { - InvalidatedPassIDs.push_back(I->first); - I = ResultsList.erase(I); - } else { - ++I; - } - while (!InvalidatedPassIDs.empty()) - FunctionAnalysisResults.erase( - std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); - } -} - -const AnalysisManager::AnalysisResultConcept & -AnalysisManager::getResultImpl(void *PassID, Module *M) { - assert(M == this->M && "Wrong module used when querying the AnalysisManager"); +const detail::AnalysisResultConcept & +ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { ModuleAnalysisResultMapT::iterator RI; bool Inserted; llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair( - PassID, polymorphic_ptr >())); + PassID, polymorphic_ptr >())); if (Inserted) { // We don't have a cached result for this result. Look up the pass and run @@ -115,10 +49,43 @@ AnalysisManager::getResultImpl(void *PassID, Module *M) { return *RI->second; } -const AnalysisManager::AnalysisResultConcept & -AnalysisManager::getResultImpl(void *PassID, Function *F) { - assert(F->getParent() == M && "Analyzing a function from another module!"); +void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { + ModuleAnalysisResults.erase(PassID); +} + +bool FunctionPassManager::run(Module *M) { + bool Changed = false; + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) + if (Passes[Idx]->run(I)) { + Changed = true; + if (AM) + AM->invalidateAll(I); + } + return Changed; +} + +void FunctionAnalysisManager::invalidateAll(Function *F) { + // Clear all the invalidated results associated specifically with this + // function. + SmallVector InvalidatedPassIDs; + FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F]; + for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(), + E = ResultsList.end(); + I != E;) + if (I->second->invalidate(F)) { + InvalidatedPassIDs.push_back(I->first); + I = ResultsList.erase(I); + } else { + ++I; + } + while (!InvalidatedPassIDs.empty()) + FunctionAnalysisResults.erase( + std::make_pair(InvalidatedPassIDs.pop_back_val(), F)); +} +const detail::AnalysisResultConcept & +FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { FunctionAnalysisResultMapT::iterator RI; bool Inserted; llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair( @@ -139,15 +106,7 @@ AnalysisManager::getResultImpl(void *PassID, Function *F) { return *RI->second->second; } -void AnalysisManager::invalidateImpl(void *PassID, Module *M) { - assert(M == this->M && "Invalidating a pass over a different module!"); - ModuleAnalysisResults.erase(PassID); -} - -void AnalysisManager::invalidateImpl(void *PassID, Function *F) { - assert(F->getParent() == M && - "Invalidating a pass over a function from another module!"); - +void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) { FunctionAnalysisResultMapT::iterator RI = FunctionAnalysisResults.find(std::make_pair(PassID, F)); if (RI == FunctionAnalysisResults.end()) diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp index 7b60e3899a0..cf7b6e47488 100644 --- a/unittests/IR/PassManagerTest.cpp +++ b/unittests/IR/PassManagerTest.cpp @@ -61,9 +61,9 @@ struct TestModulePass { }; struct TestFunctionPass { - TestFunctionPass(AnalysisManager &AM, int &RunCount, int &AnalyzedInstrCount) - : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) { - } + TestFunctionPass(FunctionAnalysisManager &AM, int &RunCount, + int &AnalyzedInstrCount) + : AM(AM), RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount) {} bool run(Function *F) { ++RunCount; @@ -74,7 +74,7 @@ struct TestFunctionPass { return true; } - AnalysisManager &AM; + FunctionAnalysisManager &AM; int &RunCount; int &AnalyzedInstrCount; }; @@ -106,10 +106,10 @@ public: }; TEST_F(PassManagerTest, Basic) { - AnalysisManager AM(M.get()); - AM.registerAnalysisPass(TestAnalysisPass()); + FunctionAnalysisManager AM; + AM.registerPass(TestAnalysisPass()); - ModulePassManager MPM(M.get(), &AM); + ModulePassManager MPM; FunctionPassManager FPM(&AM); // Count the runs over a module. @@ -122,10 +122,9 @@ TEST_F(PassManagerTest, Basic) { FPM.addPass(TestFunctionPass(AM, FunctionPassRunCount, AnalyzedInstrCount)); MPM.addPass(FPM); - MPM.run(); + MPM.run(M.get()); EXPECT_EQ(1, ModulePassRunCount); EXPECT_EQ(3, FunctionPassRunCount); EXPECT_EQ(5, AnalyzedInstrCount); } - }