aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/VMCore/Pass.cpp125
-rw-r--r--lib/VMCore/PassManagerT.h69
2 files changed, 171 insertions, 23 deletions
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp
index b6f855d..3d09d9d 100644
--- a/lib/VMCore/Pass.cpp
+++ b/lib/VMCore/Pass.cpp
@@ -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.
+}
+
+
//===----------------------------------------------------------------------===//
diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h
index 9f34f15..4e0d6b2 100644
--- a/lib/VMCore/PassManagerT.h
+++ b/lib/VMCore/PassManagerT.h
@@ -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.