- Implement the new AnalysisGroup feature, neccesary for Value#ing and pointer analysis
authorChris Lattner <sabre@nondot.org>
Wed, 21 Aug 2002 22:17:09 +0000 (22:17 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 21 Aug 2002 22:17:09 +0000 (22:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3426 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/Pass.cpp
lib/VMCore/PassManagerT.h

index b6f855d017e7e09371844a361e036e1667518d57..3d09d9d7e1c8b1d78724f00ab8ccf193db48439f 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <sys/resource.h>
 #include <sys/unistd.h>
+#include <set>
 
 //===----------------------------------------------------------------------===//
 //   AnalysisID Class Implementation
@@ -395,10 +396,10 @@ void RegisterPassBase::registerPass(PassInfo *PI) {
       (*I)->passRegistered(PI);
 }
 
-RegisterPassBase::~RegisterPassBase() {
+void RegisterPassBase::unregisterPass(PassInfo *PI) {
   assert(PassInfoMap && "Pass registered but not in map!");
   std::map<TypeInfo, PassInfo*>::iterator I =
-    PassInfoMap->find(PIObj->getTypeInfo());
+    PassInfoMap->find(PI->getTypeInfo());
   assert(I != PassInfoMap->end() && "Pass registered but not in map!");
 
   // Remove pass from the map...
@@ -412,12 +413,128 @@ RegisterPassBase::~RegisterPassBase() {
   if (Listeners)
     for (std::vector<PassRegistrationListener*>::iterator
            I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
-      (*I)->passUnregistered(PIObj);
+      (*I)->passUnregistered(PI);
 
   // Delete the PassInfo object itself...
-  delete PIObj;
+  delete PI;
 }
 
+//===----------------------------------------------------------------------===//
+//                  Analysis Group Implementation Code
+//===----------------------------------------------------------------------===//
+
+struct AnalysisGroupInfo {
+  const PassInfo *DefaultImpl;
+  std::set<const PassInfo *> Implementations;
+  AnalysisGroupInfo() : DefaultImpl(0) {}
+};
+
+static std::map<const PassInfo *, AnalysisGroupInfo> *AnalysisGroupInfoMap = 0;
+
+// RegisterAGBase implementation
+//
+RegisterAGBase::RegisterAGBase(const std::type_info &Interface,
+                               const std::type_info *Pass, bool isDefault)
+  : ImplementationInfo(0), isDefaultImplementation(isDefault) {
+
+  std::cerr << "Registering interface: " << Interface.name() << "\n";
+
+  InterfaceInfo = const_cast<PassInfo*>(Pass::lookupPassInfo(Interface));
+  if (InterfaceInfo == 0) {   // First reference to Interface, add it now.
+    InterfaceInfo =   // Create the new PassInfo for the interface...
+      new PassInfo("", "", Interface, PassInfo::AnalysisGroup, 0, 0);
+    registerPass(InterfaceInfo);
+    PIObj = 0;
+  }
+  assert(InterfaceInfo->getPassType() == PassInfo::AnalysisGroup &&
+         "Trying to join an analysis group that is a normal pass!");
+
+  if (Pass) {
+  std::cerr << "Registering interface impl: " << Pass->name() << "\n";
+
+    ImplementationInfo = Pass::lookupPassInfo(*Pass);
+    assert(ImplementationInfo &&
+           "Must register pass before adding to AnalysisGroup!");
+
+    // Lazily allocate to avoid nasty initialization order dependencies
+    if (AnalysisGroupInfoMap == 0)
+      AnalysisGroupInfoMap = new std::map<const PassInfo *,AnalysisGroupInfo>();
+
+    AnalysisGroupInfo &AGI = (*AnalysisGroupInfoMap)[InterfaceInfo];
+    assert(AGI.Implementations.count(ImplementationInfo) == 0 &&
+           "Cannot add a pass to the same analysis group more than once!");
+    AGI.Implementations.insert(ImplementationInfo);
+    if (isDefault) {
+      assert(AGI.DefaultImpl == 0 && InterfaceInfo->getNormalCtor() == 0 &&
+             "Default implementation for analysis group already specified!");
+      assert(ImplementationInfo->getNormalCtor() &&
+           "Cannot specify pass as default if it does not have a default ctor");
+      AGI.DefaultImpl = ImplementationInfo;
+      InterfaceInfo->setNormalCtor(ImplementationInfo->getNormalCtor());
+    }
+  }
+}
+
+void RegisterAGBase::setGroupName(const char *Name) {
+  assert(InterfaceInfo->getPassName()[0] == 0 && "Interface Name already set!");
+  InterfaceInfo->setPassName(Name);
+}
+
+RegisterAGBase::~RegisterAGBase() {
+  if (ImplementationInfo) {
+    assert(AnalysisGroupInfoMap && "Inserted into map, but map doesn't exist?");
+    AnalysisGroupInfo &AGI = (*AnalysisGroupInfoMap)[InterfaceInfo];
+
+    assert(AGI.Implementations.count(ImplementationInfo) &&
+           "Pass not a member of analysis group?");
+
+    if (AGI.DefaultImpl == ImplementationInfo)
+      AGI.DefaultImpl = 0;
+    
+    AGI.Implementations.erase(ImplementationInfo);
+
+    // Last member of this analysis group? Unregister PassInfo, delete map entry
+    if (AGI.Implementations.empty()) {
+      assert(AGI.DefaultImpl == 0 &&
+             "Default implementation didn't unregister?");
+      AnalysisGroupInfoMap->erase(InterfaceInfo);
+      if (AnalysisGroupInfoMap->empty()) {  // Delete map if empty
+        delete AnalysisGroupInfoMap;
+        AnalysisGroupInfoMap = 0;
+      }
+
+      unregisterPass(InterfaceInfo);
+    }
+  }
+}
+
+
+// findAnalysisGroupMember - Return an iterator pointing to one of the elements
+// of Map if there is a pass in Map that is a member of the analysis group for
+// the specified AnalysisGroupID.
+//
+static std::map<const PassInfo*, Pass*>::const_iterator
+findAnalysisGroupMember(const PassInfo *AnalysisGroupID,
+                        const std::map<const PassInfo*, Pass*> &Map) {
+  assert(AnalysisGroupID->getPassType() == PassInfo::AnalysisGroup &&
+         "AnalysisGroupID is not an analysis group!");
+  assert(AnalysisGroupInfoMap && AnalysisGroupInfoMap->count(AnalysisGroupID) &&
+         "Analysis Group does not have any registered members!");
+
+  // Get the set of all known implementations of this analysis group...
+  std::set<const PassInfo *> &Impls = 
+    (*AnalysisGroupInfoMap)[AnalysisGroupID].Implementations;
+
+  // Scan over available passes, checking to see if any is a valid analysis
+  for (std::map<const PassInfo*, Pass*>::const_iterator I = Map.begin(),
+         E = Map.end(); I != E; ++I)
+    if (Impls.count(I->first))  // This is a valid analysis, return it.
+      return I;
+
+  return Map.end();  // Nothing of use found.
+}
+
+
 
 
 //===----------------------------------------------------------------------===//
index 9f34f15cca5911c2024e209d48eacaf2ac11b120..4e0d6b24bf30e72f1608122cdb40f973d4ec154d 100644 (file)
@@ -106,6 +106,19 @@ public:
   void passEnded(Pass *P);
 };
 
+//===----------------------------------------------------------------------===//
+// Forward declarations of global functions defined in Pass.cpp.  These are
+// defined to be static functions because this header is *ONLY* included by
+// Pass.cpp.
+//
+
+// findAnalysisGroupMember - Return an iterator pointing to one of the elements
+// of Map if there is a pass in Map that is a member of the analysis group for
+// the specified AnalysisGroupID.
+//
+static std::map<const PassInfo*, Pass*>::const_iterator
+findAnalysisGroupMember(const PassInfo *AnalysisGroupID,
+                        const std::map<const PassInfo*, Pass*> &Map);
 
 
 //===----------------------------------------------------------------------===//
@@ -269,24 +282,36 @@ public:
     }
   }
 
-  Pass *getAnalysisOrNullDown(AnalysisID ID) const {
-    std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID);
-    if (I == CurrentAnalyses.end()) {
-      if (Batcher)
-        return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID);
-      return 0;
+  Pass *getAnalysisOrNullDown(const PassInfo *ID) const {
+    std::map<const PassInfo*, Pass*>::const_iterator I;
+
+    if (ID->getPassType() == PassInfo::AnalysisGroup) {
+      I = findAnalysisGroupMember(ID, CurrentAnalyses);
+    } else {
+      I = CurrentAnalyses.find(ID);
     }
-    return I->second;
+
+    if (I != CurrentAnalyses.end())
+      return I->second;  // Found it.
+
+    if (Batcher)
+      return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID);
+    return 0;
   }
 
-  Pass *getAnalysisOrNullUp(AnalysisID ID) const {
-    std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID);
-    if (I == CurrentAnalyses.end()) {
-      if (Parent)
-        return Parent->getAnalysisOrNullUp(ID);
-      return 0;
+  Pass *getAnalysisOrNullUp(const PassInfo *ID) const {
+    std::map<AnalysisID, Pass*>::const_iterator I;
+    if (ID->getPassType() == PassInfo::AnalysisGroup) {
+      I = findAnalysisGroupMember(ID, CurrentAnalyses);
+    } else {
+      I = CurrentAnalyses.find(ID);
     }
-    return I->second;
+    if (I != CurrentAnalyses.end())
+      return I->second;  // Found it.
+
+    if (Parent)          // Try scanning...
+      return Parent->getAnalysisOrNullUp(ID);
+    return 0;
   }
 
   // {start/end}Pass - Called when a pass is started, it just propogates
@@ -308,8 +333,15 @@ public:
   // make sure that analyses are not free'd before we have to use
   // them...
   //
-  void markPassUsed(AnalysisID P, Pass *User) {
-    std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.find(P);
+  void markPassUsed(const PassInfo *P, Pass *User) {
+    std::map<const PassInfo *, Pass*>::const_iterator I;
+
+    if (P->getPassType() == PassInfo::AnalysisGroup) {
+      I = findAnalysisGroupMember(P, CurrentAnalyses);
+    } else {
+      I = CurrentAnalyses.find(P);
+    }
+
     if (I != CurrentAnalyses.end()) {
       LastUseOf[I->second] = User;    // Local pass, extend the lifetime
     } else {
@@ -318,8 +350,7 @@ public:
       // parent that we (the passmanager) are using the analysis so that it
       // frees the analysis AFTER this pass manager runs.
       //
-      assert(Parent != 0 && "Pass available but not found! "
-             "Did your analysis pass 'Provide' itself?");
+      assert(Parent != 0 && "Pass available but not found!");
       Parent->markPassUsed(P, this);
     }
   }
@@ -336,7 +367,7 @@ public:
     return Passes[N];
   }
 
-  // add - Add a pass to the queue of passes to run.  This passes ownership of
+  // add - Add a pass to the queue of passes to run.  This gives ownership of
   // the Pass to the PassManager.  When the PassManager is destroyed, the pass
   // will be destroyed as well, so there is no need to delete the pass.  This
   // implies that all passes MUST be new'd.