Index: include/llvm/PassRegistry.h =================================================================== --- include/llvm/PassRegistry.h +++ include/llvm/PassRegistry.h @@ -41,6 +41,9 @@ class PassRegistry { mutable sys::SmartRWMutex Lock; + /// Only if false, synchronization must use the Lock mutex. + std::atomic locked; + /// PassInfoMap - Keep track of the PassInfo object for each registered pass. typedef DenseMap MapType; MapType PassInfoMap; @@ -52,7 +55,7 @@ std::vector Listeners; public: - PassRegistry() {} + PassRegistry() : locked(false) {} ~PassRegistry(); /// getPassRegistry - Access the global registry object, which is @@ -60,6 +63,10 @@ /// llvm_shutdown. static PassRegistry *getPassRegistry(); + /// Enables fast thread synchronization in getPassInfo(). + /// After calling lock() no more passes may be registered. + void lock() { locked = true; } + /// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass' /// type identifier (&MyPass::ID). const PassInfo *getPassInfo(const void *TI) const; Index: lib/IR/PassRegistry.cpp =================================================================== --- lib/IR/PassRegistry.cpp +++ lib/IR/PassRegistry.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/PassRegistry.h" +#include "llvm/ADT/Optional.h" #include "llvm/IR/Function.h" #include "llvm/PassSupport.h" #include "llvm/Support/Compiler.h" @@ -39,13 +40,23 @@ PassRegistry::~PassRegistry() {} const PassInfo *PassRegistry::getPassInfo(const void *TI) const { - sys::SmartScopedReader Guard(Lock); + // We don't need thread synchronization after the PassRegistry is locked + // (that means: is read-only). + Optional> Guard; + if (!locked) + Guard.emplace(Lock); + MapType::const_iterator I = PassInfoMap.find(TI); return I != PassInfoMap.end() ? I->second : nullptr; } const PassInfo *PassRegistry::getPassInfo(StringRef Arg) const { - sys::SmartScopedReader Guard(Lock); + // We don't need thread synchronization after the PassRegistry is locked + // (that means: is read-only). + Optional> Guard; + if (!locked) + Guard.emplace(Lock); + StringMapType::const_iterator I = PassInfoStringMap.find(Arg); return I != PassInfoStringMap.end() ? I->second : nullptr; } @@ -55,6 +66,9 @@ // void PassRegistry::registerPass(const PassInfo &PI, bool ShouldFree) { + + assert(!locked && "Trying to register a pass in a locked PassRegistry"); + sys::SmartScopedWriter Guard(Lock); bool Inserted = PassInfoMap.insert(std::make_pair(PI.getTypeInfo(), &PI)).second; @@ -68,6 +82,8 @@ if (ShouldFree) ToFree.push_back(std::unique_ptr(&PI)); + + assert(!locked && "PassRegistry locked during registering a pass"); } void PassRegistry::enumerateWith(PassRegistrationListener *L) {