Since PassRegistry is currently a shared global object, it needs locking. While it might intuitively seem

that all the setup of this class currently happens at static initialization time, this misses the fact
that some later events can cause mutation of the PassRegistrationListeners list, and thus cause race issues.

llvm-svn: 114036
This commit is contained in:
Owen Anderson 2010-09-15 23:03:33 +00:00
parent f7f627104b
commit d4754971b4
2 changed files with 9 additions and 0 deletions

View File

@ -18,6 +18,7 @@
#define LLVM_PASSREGISTRY_H
#include "llvm/ADT/StringRef.h"
#include "llvm/System/Mutex.h"
namespace llvm {
@ -32,6 +33,7 @@ struct PassRegistrationListener;
/// each thread.
class PassRegistry {
mutable void *pImpl;
mutable sys::SmartMutex<true> Lock;
void *getImpl() const;
public:

View File

@ -88,6 +88,7 @@ const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const {
//
void PassRegistry::registerPass(const PassInfo &PI) {
sys::SmartScopedLock<true> Guard(Lock);
PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
bool Inserted =
Impl->PassInfoMap.insert(std::make_pair(PI.getTypeInfo(),&PI)).second;
@ -101,6 +102,7 @@ void PassRegistry::registerPass(const PassInfo &PI) {
}
void PassRegistry::unregisterPass(const PassInfo &PI) {
sys::SmartScopedLock<true> Guard(Lock);
PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
PassRegistryImpl::MapType::iterator I =
Impl->PassInfoMap.find(PI.getTypeInfo());
@ -112,6 +114,7 @@ void PassRegistry::unregisterPass(const PassInfo &PI) {
}
void PassRegistry::enumerateWith(PassRegistrationListener *L) {
sys::SmartScopedLock<true> Guard(Lock);
PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
for (PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.begin(),
E = Impl->PassInfoMap.end(); I != E; ++I)
@ -124,6 +127,7 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
const void *PassID,
PassInfo& Registeree,
bool isDefault) {
sys::SmartScopedLock<true> Guard(Lock);
PassInfo *InterfaceInfo = const_cast<PassInfo*>(getPassInfo(InterfaceID));
if (InterfaceInfo == 0) {
// First reference to Interface, register it now.
@ -159,11 +163,14 @@ void PassRegistry::registerAnalysisGroup(const void *InterfaceID,
}
void PassRegistry::addRegistrationListener(PassRegistrationListener *L) {
sys::SmartScopedLock<true> Guard(Lock);
PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
Impl->Listeners.push_back(L);
}
void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
sys::SmartScopedLock<true> Guard(Lock);
// NOTE: This is necessary, because removeRegistrationListener() can be called
// as part of the llvm_shutdown sequence. Since we have no control over the
// order of that sequence, we need to gracefully handle the case where the