Start moving pass registration over to using the ManagedStatic mechanism.

This fixes issues where passes get unregistered before llvm_shutdown is
called, and is generally cleaner and simpler.  Analysis groups up next.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32108 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-12-01 23:27:45 +00:00
parent 0555122412
commit baf2ecda5f
3 changed files with 52 additions and 48 deletions

View File

@ -239,7 +239,6 @@ struct PassRegistrationListener {
/// or removed from the current executable. /// or removed from the current executable.
/// ///
virtual void passRegistered(const PassInfo *P) {} virtual void passRegistered(const PassInfo *P) {}
virtual void passUnregistered(const PassInfo *P) {}
/// enumeratePasses - Iterate over the registered passes, calling the /// enumeratePasses - Iterate over the registered passes, calling the
/// passEnumerate callback on each PassInfo object. /// passEnumerate callback on each PassInfo object.

View File

@ -74,14 +74,6 @@ public:
} }
virtual void passEnumerate(const PassInfo *P) { passRegistered(P); } virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
virtual void passUnregistered(const PassInfo *P) {
if (ignorablePass(P) || !Opt) return;
assert(findOption(P->getPassArgument()) != getNumOptions() &&
"Registered Pass not in the pass map!");
removeLiteralOption(P->getPassArgument());
Opt->removeArgument(P->getPassArgument());
}
// ValLessThan - Provide a sorting comparator for Values elements... // ValLessThan - Provide a sorting comparator for Values elements...
typedef std::pair<const char*, typedef std::pair<const char*,
std::pair<const PassInfo*, const char*> > ValType; std::pair<const PassInfo*, const char*> > ValType;

View File

@ -18,6 +18,7 @@
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/ModuleProvider.h" #include "llvm/ModuleProvider.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/TypeInfo.h" #include "llvm/Support/TypeInfo.h"
#include <iostream> #include <iostream>
#include <set> #include <set>
@ -285,7 +286,39 @@ void BasicBlockPass::addToPassManager(BasicBlockPassManager *PM,
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Pass Registration mechanism // Pass Registration mechanism
// //
static std::map<TypeInfo, PassInfo*> *PassInfoMap = 0; class PassRegistrar {
std::map<TypeInfo, PassInfo*> PassInfoMap;
public:
const PassInfo *GetPassInfo(const std::type_info &TI) const {
std::map<TypeInfo, PassInfo*>::const_iterator I = PassInfoMap.find(TI);
return I != PassInfoMap.end() ? I->second : 0;
}
void RegisterPass(PassInfo &PI) {
bool Inserted =
PassInfoMap.insert(std::make_pair(TypeInfo(PI.getTypeInfo()),&PI)).second;
assert(Inserted && "Pass registered multiple times!");
}
void UnregisterPass(PassInfo &PI) {
std::map<TypeInfo, PassInfo*>::iterator I =
PassInfoMap.find(PI.getTypeInfo());
assert(I != PassInfoMap.end() && "Pass registered but not in map!");
// Remove pass from the map.
PassInfoMap.erase(I);
}
void EnumerateWith(PassRegistrationListener *L) {
for (std::map<TypeInfo, PassInfo*>::const_iterator I = PassInfoMap.begin(),
E = PassInfoMap.end(); I != E; ++I)
L->passEnumerate(I->second);
}
};
static ManagedStatic<PassRegistrar> PassRegistrarObj;
static std::vector<PassRegistrationListener*> *Listeners = 0; static std::vector<PassRegistrationListener*> *Listeners = 0;
// getPassInfo - Return the PassInfo data structure that corresponds to this // getPassInfo - Return the PassInfo data structure that corresponds to this
@ -296,20 +329,13 @@ const PassInfo *Pass::getPassInfo() const {
} }
const PassInfo *Pass::lookupPassInfo(const std::type_info &TI) { const PassInfo *Pass::lookupPassInfo(const std::type_info &TI) {
if (PassInfoMap == 0) return 0; return PassRegistrarObj->GetPassInfo(TI);
std::map<TypeInfo, PassInfo*>::iterator I = PassInfoMap->find(TI);
return (I != PassInfoMap->end()) ? I->second : 0;
} }
void RegisterPassBase::registerPass() { void RegisterPassBase::registerPass() {
if (PassInfoMap == 0) PassRegistrarObj->RegisterPass(PIObj);
PassInfoMap = new std::map<TypeInfo, PassInfo*>();
assert(PassInfoMap->find(PIObj.getTypeInfo()) == PassInfoMap->end() && // Notify any listeners.
"Pass already registered!");
PassInfoMap->insert(std::make_pair(TypeInfo(PIObj.getTypeInfo()), &PIObj));
// Notify any listeners...
if (Listeners) if (Listeners)
for (std::vector<PassRegistrationListener*>::iterator for (std::vector<PassRegistrationListener*>::iterator
I = Listeners->begin(), E = Listeners->end(); I != E; ++I) I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
@ -317,23 +343,7 @@ void RegisterPassBase::registerPass() {
} }
void RegisterPassBase::unregisterPass() { void RegisterPassBase::unregisterPass() {
assert(PassInfoMap && "Pass registered but not in map!"); PassRegistrarObj->UnregisterPass(PIObj);
std::map<TypeInfo, PassInfo*>::iterator I =
PassInfoMap->find(PIObj.getTypeInfo());
assert(I != PassInfoMap->end() && "Pass registered but not in map!");
// Remove pass from the map...
PassInfoMap->erase(I);
if (PassInfoMap->empty()) {
delete PassInfoMap;
PassInfoMap = 0;
}
// Notify any listeners...
if (Listeners)
for (std::vector<PassRegistrationListener*>::iterator
I = Listeners->begin(), E = Listeners->end(); I != E; ++I)
(*I)->passUnregistered(&PIObj);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -457,16 +467,25 @@ PassRegistrationListener::~PassRegistrationListener() {
// passEnumerate callback on each PassInfo object. // passEnumerate callback on each PassInfo object.
// //
void PassRegistrationListener::enumeratePasses() { void PassRegistrationListener::enumeratePasses() {
if (PassInfoMap) PassRegistrarObj->EnumerateWith(this);
for (std::map<TypeInfo, PassInfo*>::iterator I = PassInfoMap->begin(),
E = PassInfoMap->end(); I != E; ++I)
passEnumerate(I->second);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// AnalysisUsage Class Implementation // AnalysisUsage Class Implementation
// //
namespace {
struct GetCFGOnlyPasses : public PassRegistrationListener {
std::vector<AnalysisID> &CFGOnlyList;
GetCFGOnlyPasses(std::vector<AnalysisID> &L) : CFGOnlyList(L) {}
void passEnumerate(const PassInfo *P) {
if (P->isCFGOnlyPass())
CFGOnlyList.push_back(P);
}
};
}
// setPreservesCFG - This function should be called to by the pass, iff they do // setPreservesCFG - This function should be called to by the pass, iff they do
// not: // not:
// //
@ -479,13 +498,7 @@ void PassRegistrationListener::enumeratePasses() {
void AnalysisUsage::setPreservesCFG() { void AnalysisUsage::setPreservesCFG() {
// Since this transformation doesn't modify the CFG, it preserves all analyses // Since this transformation doesn't modify the CFG, it preserves all analyses
// that only depend on the CFG (like dominators, loop info, etc...) // that only depend on the CFG (like dominators, loop info, etc...)
// GetCFGOnlyPasses(Preserved).enumeratePasses();
if (PassInfoMap) {
for (std::map<TypeInfo, PassInfo*>::iterator I = PassInfoMap->begin(),
E = PassInfoMap->end(); I != E; ++I)
if (I->second->isCFGOnlyPass())
Preserved.push_back(I->second);
}
} }