diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 3ec4f6c71fb..111d3736841 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -169,12 +169,13 @@ template struct PassConcept { /// \brief SFINAE metafunction for computing whether \c PassT has a run method /// accepting an \c AnalysisManagerT. -template +template class PassRunAcceptsAnalysisManager { typedef char SmallType; struct BigType { char a, b; }; - template + template struct Checker; template static SmallType f(Checker *); @@ -191,7 +192,7 @@ public: /// \c run method also accepts an \c AnalysisManagerT*, we pass it along. template ::Value> + IRUnitT, AnalysisManagerT, PassT, PreservedAnalyses>::Value> struct PassModel; /// \brief Specialization of \c PassModel for passes that accept an analyis @@ -312,14 +313,16 @@ struct AnalysisResultModel struct AnalysisPassConcept { +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; + virtual AnalysisResultConcept *run(IRUnitT IR, + AnalysisManagerT *AM) = 0; }; /// \brief Wrapper to model the analysis pass concept. @@ -327,8 +330,17 @@ template struct AnalysisPassConcept { /// 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 { +template ::Value > struct AnalysisPassModel; + +/// \brief Specialization of \c AnalysisPassModel which passes an +/// \c AnalysisManager to PassT's run method. +template +struct AnalysisPassModel : AnalysisPassConcept { AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {} virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); } @@ -339,7 +351,30 @@ struct AnalysisPassModel : AnalysisPassConcept { /// \brief The model delegates to the \c PassT::run method. /// /// The return is wrapped in an \c AnalysisResultModel. - virtual ResultModelT *run(IRUnitT IR) { + virtual ResultModelT *run(IRUnitT IR, AnalysisManagerT *AM) { + return new ResultModelT(Pass.run(IR, AM)); + } + + PassT Pass; +}; + +/// \brief Specialization of \c AnalysisPassModel which does not pass an +/// \c AnalysisManager to PassT's run method. +template +struct AnalysisPassModel : AnalysisPassConcept { + AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {} + virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); } + + // 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, AnalysisManagerT *) { return new ResultModelT(Pass.run(IR)); } @@ -436,7 +471,8 @@ public: assert(!ModuleAnalysisPasses.count(PassT::ID()) && "Registered the same analysis pass twice!"); ModuleAnalysisPasses[PassT::ID()] = - new detail::AnalysisPassModel(llvm_move(Pass)); + new detail::AnalysisPassModel( + llvm_move(Pass)); } /// \brief Invalidate a specific analysis pass for an IR module. @@ -463,8 +499,8 @@ private: void invalidateImpl(void *PassID, Module *M); /// \brief Map type from module analysis pass ID to pass concept pointer. - typedef DenseMap > > + typedef DenseMap > > ModuleAnalysisPassMapT; /// \brief Collection of module analysis passes, indexed by ID. @@ -511,8 +547,8 @@ public: template void registerPass(PassT Pass) { assert(!FunctionAnalysisPasses.count(PassT::ID()) && "Registered the same analysis pass twice!"); - FunctionAnalysisPasses[PassT::ID()] = - new detail::AnalysisPassModel(llvm_move(Pass)); + FunctionAnalysisPasses[PassT::ID()] = new detail::AnalysisPassModel< + Function *, FunctionAnalysisManager, PassT>(llvm_move(Pass)); } /// \brief Invalidate a specific analysis pass for an IR module. @@ -551,8 +587,8 @@ private: void invalidateImpl(void *PassID, Function *F); /// \brief Map type from function analysis pass ID to pass concept pointer. - typedef DenseMap > > + typedef DenseMap > > FunctionAnalysisPassMapT; /// \brief Collection of function analysis passes, indexed by ID. diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index f2d0cd99e61..fe16adcaeb3 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -47,7 +47,7 @@ ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) { ModuleAnalysisPasses.find(PassID); assert(PI != ModuleAnalysisPasses.end() && "Analysis passes must be registered prior to being queried!"); - RI->second = PI->second->run(M); + RI->second = PI->second->run(M, this); } return *RI->second; @@ -115,7 +115,7 @@ FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) { assert(PI != FunctionAnalysisPasses.end() && "Analysis passes must be registered prior to being queried!"); FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F]; - ResultList.push_back(std::make_pair(PassID, PI->second->run(F))); + ResultList.push_back(std::make_pair(PassID, PI->second->run(F, this))); RI->second = llvm::prior(ResultList.end()); } diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp index b0d4cbe0318..8115da862dc 100644 --- a/unittests/IR/PassManagerTest.cpp +++ b/unittests/IR/PassManagerTest.cpp @@ -32,7 +32,7 @@ public: TestAnalysisPass(int &Runs) : Runs(Runs) {} /// \brief Run the analysis pass over the function and return a result. - Result run(Function *F) { + Result run(Function *F, FunctionAnalysisManager *AM) { ++Runs; int Count = 0; for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)