diff options
-rw-r--r-- | llvm/include/llvm/IR/PassManager.h | 66 | ||||
-rw-r--r-- | llvm/lib/IR/PassManager.cpp | 4 | ||||
-rw-r--r-- | llvm/unittests/IR/PassManagerTest.cpp | 2 |
3 files changed, 54 insertions, 18 deletions
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h index 3ec4f6c..111d373 100644 --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -169,12 +169,13 @@ template <typename IRUnitT, typename AnalysisManagerT> struct PassConcept { /// \brief SFINAE metafunction for computing whether \c PassT has a run method /// accepting an \c AnalysisManagerT. -template <typename IRUnitT, typename AnalysisManagerT, typename PassT> +template <typename IRUnitT, typename AnalysisManagerT, typename PassT, + typename ResultT> class PassRunAcceptsAnalysisManager { typedef char SmallType; struct BigType { char a, b; }; - template <typename T, PreservedAnalyses (T::*)(IRUnitT, AnalysisManagerT *)> + template <typename T, ResultT (T::*)(IRUnitT, AnalysisManagerT *)> struct Checker; template <typename T> static SmallType f(Checker<T, &T::run> *); @@ -191,7 +192,7 @@ public: /// \c run method also accepts an \c AnalysisManagerT*, we pass it along. template <typename IRUnitT, typename AnalysisManagerT, typename PassT, bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager< - IRUnitT, AnalysisManagerT, PassT>::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<IRUnitT, PassT, ResultT, /// /// This concept is parameterized over the IR unit that it can run over and /// produce an analysis result. -template <typename IRUnitT> struct AnalysisPassConcept { +template <typename IRUnitT, typename AnalysisManagerT> +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<IRUnitT> *run(IRUnitT IR) = 0; + virtual AnalysisResultConcept<IRUnitT> *run(IRUnitT IR, + AnalysisManagerT *AM) = 0; }; /// \brief Wrapper to model the analysis pass concept. @@ -327,8 +330,40 @@ template <typename IRUnitT> 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 <typename IRUnitT, typename PassT> -struct AnalysisPassModel : AnalysisPassConcept<IRUnitT> { +template <typename IRUnitT, typename AnalysisManagerT, typename PassT, + bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager< + IRUnitT, AnalysisManagerT, PassT, + typename PassT::Result>::Value > struct AnalysisPassModel; + +/// \brief Specialization of \c AnalysisPassModel which passes an +/// \c AnalysisManager to PassT's run method. +template <typename IRUnitT, typename AnalysisManagerT, typename PassT> +struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, + true> : AnalysisPassConcept<IRUnitT, + AnalysisManagerT> { + 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<IRUnitT, PassT, typename PassT::Result> + 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 *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 <typename IRUnitT, typename AnalysisManagerT, typename PassT> +struct AnalysisPassModel<IRUnitT, AnalysisManagerT, PassT, + false> : AnalysisPassConcept<IRUnitT, + AnalysisManagerT> { AnalysisPassModel(PassT Pass) : Pass(llvm_move(Pass)) {} virtual AnalysisPassModel *clone() { return new AnalysisPassModel(Pass); } @@ -339,7 +374,7 @@ struct AnalysisPassModel : AnalysisPassConcept<IRUnitT> { /// \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 *) { 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<Module *, PassT>(llvm_move(Pass)); + new detail::AnalysisPassModel<Module *, ModuleAnalysisManager, PassT>( + 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<void *, - polymorphic_ptr<detail::AnalysisPassConcept<Module *> > > + typedef DenseMap<void *, polymorphic_ptr<detail::AnalysisPassConcept< + Module *, ModuleAnalysisManager> > > ModuleAnalysisPassMapT; /// \brief Collection of module analysis passes, indexed by ID. @@ -511,8 +547,8 @@ public: template <typename PassT> void registerPass(PassT Pass) { assert(!FunctionAnalysisPasses.count(PassT::ID()) && "Registered the same analysis pass twice!"); - FunctionAnalysisPasses[PassT::ID()] = - new detail::AnalysisPassModel<Function *, PassT>(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<void *, - polymorphic_ptr<detail::AnalysisPassConcept<Function *> > > + typedef DenseMap<void *, polymorphic_ptr<detail::AnalysisPassConcept< + Function *, FunctionAnalysisManager> > > FunctionAnalysisPassMapT; /// \brief Collection of function analysis passes, indexed by ID. diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp index f2d0cd9..fe16adc 100644 --- a/llvm/lib/IR/PassManager.cpp +++ b/llvm/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/llvm/unittests/IR/PassManagerTest.cpp b/llvm/unittests/IR/PassManagerTest.cpp index b0d4cbe..8115da8 100644 --- a/llvm/unittests/IR/PassManagerTest.cpp +++ b/llvm/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) |