diff options
-rw-r--r-- | lib/VMCore/Pass.cpp | 125 | ||||
-rw-r--r-- | lib/VMCore/PassManagerT.h | 69 |
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. |