mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
- Implement the new AnalysisGroup feature, neccesary for Value#ing and pointer analysis
llvm-svn: 3426
This commit is contained in:
parent
c5c1d9ad89
commit
02221dc679
@ -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.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user