[llvm] r195451 - [PM] Teach the analysis managers to pass themselves as arguments to the

Chandler Carruth chandlerc at gmail.com
Fri Nov 22 04:11:02 PST 2013


Author: chandlerc
Date: Fri Nov 22 06:11:02 2013
New Revision: 195451

URL: http://llvm.org/viewvc/llvm-project?rev=195451&view=rev
Log:
[PM] Teach the analysis managers to pass themselves as arguments to the
run methods of the analysis passes.

Also generalizes and re-uses the SFINAE for transformation passes so
that users can write an analysis pass and only accept an analysis
manager if that is useful to their pass.

This completes the plumbing to make an analysis manager available
through every pass's run method if desired so that passes no longer need
to be constructed around them.

Modified:
    llvm/trunk/include/llvm/IR/PassManager.h
    llvm/trunk/lib/IR/PassManager.cpp
    llvm/trunk/unittests/IR/PassManagerTest.cpp

Modified: llvm/trunk/include/llvm/IR/PassManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=195451&r1=195450&r2=195451&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/PassManager.h (original)
+++ llvm/trunk/include/llvm/IR/PassManager.h Fri Nov 22 06:11:02 2013
@@ -169,12 +169,13 @@ template <typename IRUnitT, typename Ana
 
 /// \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, Pass
 ///
 /// 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 Analy
 /// 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 : AnalysisPassC
   /// \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.

Modified: llvm/trunk/lib/IR/PassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/PassManager.cpp?rev=195451&r1=195450&r2=195451&view=diff
==============================================================================
--- llvm/trunk/lib/IR/PassManager.cpp (original)
+++ llvm/trunk/lib/IR/PassManager.cpp Fri Nov 22 06:11:02 2013
@@ -47,7 +47,7 @@ ModuleAnalysisManager::getResultImpl(voi
         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(v
     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());
   }
 

Modified: llvm/trunk/unittests/IR/PassManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassManagerTest.cpp?rev=195451&r1=195450&r2=195451&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/PassManagerTest.cpp (original)
+++ llvm/trunk/unittests/IR/PassManagerTest.cpp Fri Nov 22 06:11:02 2013
@@ -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)





More information about the llvm-commits mailing list