Rename some GC classes so that their roll will hopefully be clearer.
[oota-llvm.git] / include / llvm / PassAnalysisSupport.h
index d832485b833c925e763ade00cb997720c9c64b15..c6ed179af61f9a3516a562cede022d84d9752f42 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -20,6 +20,7 @@
 #define LLVM_PASS_ANALYSIS_SUPPORT_H
 
 #include <vector>
+#include "llvm/ADT/SmallVector.h"
 
 namespace llvm {
 
@@ -34,9 +35,14 @@ namespace llvm {
 // Pass infrastructure through the getAnalysisUsage virtual function.
 //
 class AnalysisUsage {
+public:
+  typedef SmallVector<AnalysisID, 32> VectorType;
+
+private:
   // Sets of analyses required and preserved by a pass
-  std::vector<AnalysisID> Required, RequiredTransitive, Preserved;
+  VectorType Required, RequiredTransitive, Preserved;
   bool PreservesAll;
+
 public:
   AnalysisUsage() : PreservesAll(false) {}
 
@@ -44,24 +50,26 @@ public:
   // for a pass.
   //
   AnalysisUsage &addRequiredID(AnalysisID ID) {
+    assert(ID && "Pass class not registered!");
     Required.push_back(ID);
     return *this;
   }
   template<class PassClass>
   AnalysisUsage &addRequired() {
-    assert(Pass::getClassPassInfo<PassClass>() && "Pass class not registered!");
-    Required.push_back(Pass::getClassPassInfo<PassClass>());
-    return *this;
+    return addRequiredID(Pass::getClassPassInfo<PassClass>());
   }
 
-  template<class PassClass>
-  AnalysisUsage &addRequiredTransitive() {
-    AnalysisID ID = Pass::getClassPassInfo<PassClass>();
+  AnalysisUsage &addRequiredTransitiveID(AnalysisID ID) {
     assert(ID && "Pass class not registered!");
     Required.push_back(ID);
     RequiredTransitive.push_back(ID);
     return *this;
   }
+  template<class PassClass>
+  AnalysisUsage &addRequiredTransitive() {
+    AnalysisID ID = Pass::getClassPassInfo<PassClass>();
+    return addRequiredTransitiveID(ID);
+  }
 
   // addPreserved - Add the specified ID to the set of analyses preserved by
   // this pass
@@ -93,11 +101,11 @@ public:
   ///
   void setPreservesCFG();
 
-  const std::vector<AnalysisID> &getRequiredSet() const { return Required; }
-  const std::vector<AnalysisID> &getRequiredTransitiveSet() const {
+  const VectorType &getRequiredSet() const { return Required; }
+  const VectorType &getRequiredTransitiveSet() const {
     return RequiredTransitive;
   }
-  const std::vector<AnalysisID> &getPreservedSet() const { return Preserved; }
+  const VectorType &getPreservedSet() const { return Preserved; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -111,7 +119,7 @@ private:
   AnalysisResolver();  // DO NOT IMPLEMENT
 
 public:
-  AnalysisResolver(PMDataManager &P) : PM(P) { }
+  explicit AnalysisResolver(PMDataManager &P) : PM(P) { }
   
   inline PMDataManager &getPMDataManager() { return PM; }
 
@@ -127,6 +135,9 @@ public:
     return ResultPass;
   }
 
+  // Find pass that is implementing PI. Initialize pass for Function F.
+  Pass *findImplPass(Pass *P, const PassInfo *PI, Function &F);
+
   void addAnalysisImplsPair(const PassInfo *PI, Pass *P) {
     std::pair<const PassInfo*, Pass*> pir = std::make_pair(PI,P);
     AnalysisImpls.push_back(pir);
@@ -197,6 +208,39 @@ AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const {
   return *Result;
 }
 
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis(Function &F) {
+  assert(Resolver &&"Pass has not been inserted into a PassManager object!");
+
+  return getAnalysisID<AnalysisType>(getClassPassInfo<AnalysisType>(), F);
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(const PassInfo *PI, Function &F) {
+  assert(PI && "getAnalysis for unregistered pass!");
+   assert(Resolver&&"Pass has not been inserted into a PassManager object!");
+   // 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 = Resolver->findImplPass(this, PI, F);
+   assert (ResultPass && 
+           "getAnalysis*() called on an analysis that was not "
+           "'required' by pass!");
+   // 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*>(ResultPass);
+   assert(Result && "Pass does not implement interface required!");
+   return *Result;
+}
+
 } // End llvm namespace
 
 #endif