- Pass now has AnalysisImpls class to implement getAnalysis() so that it is
authorChris Lattner <sabre@nondot.org>
Fri, 30 Aug 2002 20:19:49 +0000 (20:19 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 30 Aug 2002 20:19:49 +0000 (20:19 +0000)
    correct even when called back by another passes run method.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3531 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Pass.h

index 0f4b56fdbcc5692fc538ebff766b8cd0d276173c..6f5f8d63b462236cbcff492343bd0240fe2bb0e1 100644 (file)
@@ -47,6 +47,12 @@ class Pass {
   friend class AnalysisResolver;
   AnalysisResolver *Resolver;  // AnalysisResolver this pass is owned by...
   const PassInfo *PassInfoCache;
+
+  // AnalysisImpls - This keeps track of which passes implement the interfaces
+  // that are required by the current pass (to implement getAnalysis()).
+  //
+  std::vector<std::pair<const PassInfo*, Pass*> > AnalysisImpls;
+
   void operator=(const Pass&);  // DO NOT IMPLEMENT
   Pass(const Pass &);           // DO NOT IMPLEMENT
 public:
@@ -129,26 +135,38 @@ protected:
   AnalysisType &getAnalysis() const {
     assert(Resolver && "Pass has not been inserted into a PassManager object!");
     const PassInfo *PI = getClassPassInfo<AnalysisType>();
+    return getAnalysisID<AnalysisType>(PI);
+  }
+
+  template<typename AnalysisType>
+  AnalysisType &getAnalysisID(const PassInfo *PI) const {
+    assert(Resolver && "Pass has not been inserted into a PassManager object!");
     assert(PI && "getAnalysis for unregistered pass!");
 
+    // PI *must* appear in AnalysisImpls.  Because the number of passes used
+    // should be a small number, we just do a linear search over a (dense)
+    // vector.
+    Pass *ResultPass = 0;
+    for (unsigned i = 0; ; ++i) {
+      assert(i != AnalysisImpls.size() &&
+             "getAnalysis*() called on an analysis that we not "
+             "'required' by pass!");
+      if (AnalysisImpls[i].first == PI) {
+        ResultPass = AnalysisImpls[i].second;
+        break;
+      }
+    }
+
     // Because the AnalysisType may not be a subclass of pass (for
     // AnalysisGroups), we must use dynamic_cast here to potentially adjust the
     // return pointer (because the class may multiply inherit, once from pass,
     // once from AnalysisType).
     //
-    AnalysisType *Result =
-      dynamic_cast<AnalysisType*>(Resolver->getAnalysis(PI));
+    AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass);
     assert(Result && "Pass does not implement interface required!");
     return *Result;
   }
 
-  template<typename AnalysisType>
-  AnalysisType &getAnalysisID(const PassInfo *PI) const {
-    assert(Resolver && "Pass has not been inserted into a PassManager object!");
-    assert(PI && "getAnalysis for unregistered pass!");
-    return *dynamic_cast<AnalysisType*>(Resolver->getAnalysis(PI));
-  }
-
   /// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
   /// to get to the analysis information that might be around that needs to be
   /// updated.  This is different than getAnalysis in that it can fail (ie the