diff --git a/llvm/include/llvm/IR/OptBisect.h b/llvm/include/llvm/IR/OptBisect.h index 14488bb1b37cfd..63fd98073b51b1 100644 --- a/llvm/include/llvm/IR/OptBisect.h +++ b/llvm/include/llvm/IR/OptBisect.h @@ -15,6 +15,7 @@ #define LLVM_IR_OPTBISECT_H #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ManagedStatic.h" #include namespace llvm { @@ -89,8 +90,7 @@ class OptBisect : public OptPassGate { /// Singleton instance of the OptBisect class, so multiple pass managers don't /// need to coordinate their uses of OptBisect. -OptBisect &getOptBisector(); - +extern ManagedStatic OptBisector; } // end namespace llvm #endif // LLVM_IR_OPTBISECT_H diff --git a/llvm/lib/Analysis/TFUtils.cpp b/llvm/lib/Analysis/TFUtils.cpp index 682fc095b0e914..203858c1cf06c4 100644 --- a/llvm/lib/Analysis/TFUtils.cpp +++ b/llvm/lib/Analysis/TFUtils.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/JSON.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -48,17 +49,19 @@ using TFStatusPtr = std::unique_ptr; struct TFInitializer { TFInitializer() { + assert(!IsInitialized && "TFInitialized should be called only once"); int Argc = 1; const char *Name = ""; const char **NamePtr = &Name; TF_InitMain(Name, &Argc, const_cast(&NamePtr)); + IsInitialized = true; } + bool IsInitialized = false; }; -bool ensureInitTF() { - static TFInitializer TFLibInitializer; - return true; -} +llvm::ManagedStatic TFLibInitializer; + +bool ensureInitTF() { return TFLibInitializer->IsInitialized; } TFGraphPtr createTFGraph() { return TFGraphPtr(TF_NewGraph(), &TF_DeleteGraph); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index f2e7b48c911f1f..47c79cdb849336 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -69,6 +69,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -7445,9 +7446,10 @@ class BitcodeErrorCategoryType : public std::error_category { } // end anonymous namespace +static ManagedStatic ErrorCategory; + const std::error_category &llvm::BitcodeErrorCategory() { - static BitcodeErrorCategoryType ErrorCategory; - return ErrorCategory; + return *ErrorCategory; } static Expected readBlobInRecord(BitstreamCursor &Stream, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 832fc3a564adff..dc0bb2e2578d98 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -60,6 +60,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/KnownBits.h" #include "llvm/Support/MachineValueType.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/raw_ostream.h" @@ -10753,19 +10754,19 @@ namespace { } // end anonymous namespace +static ManagedStatic> EVTs; +static ManagedStatic SimpleVTArray; +static ManagedStatic> VTMutex; + /// getValueTypeList - Return a pointer to the specified value type. /// const EVT *SDNode::getValueTypeList(EVT VT) { - static std::set EVTs; - static EVTArray SimpleVTArray; - static sys::SmartMutex VTMutex; - if (VT.isExtended()) { - sys::SmartScopedLock Lock(VTMutex); - return &(*EVTs.insert(VT).first); + sys::SmartScopedLock Lock(*VTMutex); + return &(*EVTs->insert(VT).first); } assert(VT.getSimpleVT() < MVT::VALUETYPE_SIZE && "Value type out of range!"); - return &SimpleVTArray.VTs[VT.getSimpleVT().SimpleTy]; + return &SimpleVTArray->VTs[VT.getSimpleVT().SimpleTy]; } /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp index 74803a3e495a91..d12f6c796e5000 100644 --- a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp +++ b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp @@ -8,6 +8,7 @@ #include "llvm/DebugInfo/CodeView/CodeViewError.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include using namespace llvm; @@ -41,9 +42,9 @@ class CodeViewErrorCategory : public std::error_category { }; } // namespace +static llvm::ManagedStatic CodeViewErrCategory; const std::error_category &llvm::codeview::CVErrorCategory() { - static CodeViewErrorCategory CodeViewErrCategory; - return CodeViewErrCategory; + return *CodeViewErrCategory; } char CodeViewError::ID; diff --git a/llvm/lib/DebugInfo/MSF/MSFError.cpp b/llvm/lib/DebugInfo/MSF/MSFError.cpp index fd93c3e726ccbe..9df2158423a405 100644 --- a/llvm/lib/DebugInfo/MSF/MSFError.cpp +++ b/llvm/lib/DebugInfo/MSF/MSFError.cpp @@ -8,6 +8,7 @@ #include "llvm/DebugInfo/MSF/MSFError.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include using namespace llvm; @@ -49,9 +50,7 @@ class MSFErrorCategory : public std::error_category { }; } // namespace -const std::error_category &llvm::msf::MSFErrCategory() { - static MSFErrorCategory MSFCategory; - return MSFCategory; -} +static llvm::ManagedStatic MSFCategory; +const std::error_category &llvm::msf::MSFErrCategory() { return *MSFCategory; } char MSFError::ID; diff --git a/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp b/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp index 0bd93a0e950611..819651f7778789 100644 --- a/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp +++ b/llvm/lib/DebugInfo/PDB/DIA/DIAError.cpp @@ -1,5 +1,6 @@ #include "llvm/DebugInfo/PDB/DIA/DIAError.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" using namespace llvm; using namespace llvm::pdb; @@ -30,9 +31,7 @@ class DIAErrorCategory : public std::error_category { } }; -const std::error_category &llvm::pdb::DIAErrCategory() { - static DIAErrorCategory DIACategory; - return DIACategory; -} +static llvm::ManagedStatic DIACategory; +const std::error_category &llvm::pdb::DIAErrCategory() { return *DIACategory; } char DIAError::ID; diff --git a/llvm/lib/DebugInfo/PDB/GenericError.cpp b/llvm/lib/DebugInfo/PDB/GenericError.cpp index d6da2dd6214008..0e4cba3174b26d 100644 --- a/llvm/lib/DebugInfo/PDB/GenericError.cpp +++ b/llvm/lib/DebugInfo/PDB/GenericError.cpp @@ -8,6 +8,7 @@ #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" using namespace llvm; using namespace llvm::pdb; @@ -41,9 +42,7 @@ class PDBErrorCategory : public std::error_category { }; } // namespace -const std::error_category &llvm::pdb::PDBErrCategory() { - static PDBErrorCategory PDBCategory; - return PDBCategory; -} +static llvm::ManagedStatic PDBCategory; +const std::error_category &llvm::pdb::PDBErrCategory() { return *PDBCategory; } char PDBError::ID; diff --git a/llvm/lib/DebugInfo/PDB/Native/RawError.cpp b/llvm/lib/DebugInfo/PDB/Native/RawError.cpp index 31320288a60308..ed6cf08396755a 100644 --- a/llvm/lib/DebugInfo/PDB/Native/RawError.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/RawError.cpp @@ -1,5 +1,6 @@ #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" using namespace llvm; using namespace llvm::pdb; @@ -46,9 +47,7 @@ class RawErrorCategory : public std::error_category { }; } // namespace -const std::error_category &llvm::pdb::RawErrCategory() { - static RawErrorCategory RawCategory; - return RawCategory; -} +static llvm::ManagedStatic RawCategory; +const std::error_category &llvm::pdb::RawErrCategory() { return *RawCategory; } char RawError::ID; diff --git a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp index b2e42a21bbd9d3..29a623ebe449f8 100644 --- a/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp +++ b/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp @@ -12,6 +12,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" #include @@ -122,10 +123,7 @@ class GDBJITRegistrationListener : public JITEventListener { /// Lock used to serialize all jit registration events, since they /// modify global variables. -sys::Mutex &getJITDebugLock() { - static sys::Mutex JITDebugLock; - return JITDebugLock; -} +ManagedStatic JITDebugLock; /// Do the registration. void NotifyDebugger(jit_code_entry* JITCodeEntry) { @@ -145,7 +143,7 @@ void NotifyDebugger(jit_code_entry* JITCodeEntry) { GDBJITRegistrationListener::~GDBJITRegistrationListener() { // Free all registered object files. - std::lock_guard locked(getJITDebugLock()); + std::lock_guard locked(*JITDebugLock); for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end(); I != E; ++I) { @@ -169,7 +167,7 @@ void GDBJITRegistrationListener::notifyObjectLoaded( const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart(); size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize(); - std::lock_guard locked(getJITDebugLock()); + std::lock_guard locked(*JITDebugLock); assert(ObjectBufferMap.find(K) == ObjectBufferMap.end() && "Second attempt to perform debug registration."); jit_code_entry* JITCodeEntry = new jit_code_entry(); @@ -188,7 +186,7 @@ void GDBJITRegistrationListener::notifyObjectLoaded( } void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) { - std::lock_guard locked(getJITDebugLock()); + std::lock_guard locked(*JITDebugLock); RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(K); if (I != ObjectBufferMap.end()) { @@ -230,13 +228,14 @@ void GDBJITRegistrationListener::deregisterObjectInternal( JITCodeEntry = nullptr; } +llvm::ManagedStatic GDBRegListener; + } // end namespace namespace llvm { JITEventListener* JITEventListener::createGDBRegistrationListener() { - static GDBJITRegistrationListener GDBRegListener; - return &GDBRegListener; + return &*GDBRegListener; } } // namespace llvm diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp index 3e8bfa35d16a3c..43efe0725cfee4 100644 --- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp @@ -12,6 +12,7 @@ #include "llvm/ExecutionEngine/JITLink/ELF.h" #include "llvm/ExecutionEngine/JITLink/MachO.h" #include "llvm/Support/Format.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -40,6 +41,8 @@ class JITLinkerErrorCategory : public std::error_category { } }; +static ManagedStatic JITLinkerErrorCategory; + } // namespace namespace llvm { @@ -50,8 +53,7 @@ char JITLinkError::ID = 0; void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg; } std::error_code JITLinkError::convertToErrorCode() const { - static JITLinkerErrorCategory TheJITLinkerErrorCategory; - return std::error_code(GenericJITLinkError, TheJITLinkerErrorCategory); + return std::error_code(GenericJITLinkError, *JITLinkerErrorCategory); } const char *getGenericEdgeKindName(Edge::Kind K) { diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp index 2cc2bddeb21a10..fdad90cbcfb747 100644 --- a/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Shared/OrcError.cpp @@ -12,6 +12,7 @@ #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include @@ -69,10 +70,7 @@ class OrcErrorCategory : public std::error_category { } }; -OrcErrorCategory &getOrcErrCat() { - static OrcErrorCategory OrcErrCat; - return OrcErrCat; -} +static ManagedStatic OrcErrCat; } // namespace namespace llvm { @@ -83,7 +81,7 @@ char JITSymbolNotFound::ID = 0; std::error_code orcError(OrcErrorCode ErrCode) { typedef std::underlying_type::type UT; - return std::error_code(static_cast(ErrCode), getOrcErrCat()); + return std::error_code(static_cast(ErrCode), *OrcErrCat); } DuplicateDefinition::DuplicateDefinition(std::string SymbolName) @@ -107,7 +105,7 @@ JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName) std::error_code JITSymbolNotFound::convertToErrorCode() const { typedef std::underlying_type::type UT; return std::error_code(static_cast(OrcErrorCode::JITSymbolNotFound), - getOrcErrCat()); + *OrcErrCat); } void JITSymbolNotFound::log(raw_ostream &OS) const { diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp index 8296b03398a05e..ffa2969536e7be 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.cpp @@ -11,6 +11,7 @@ #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/ManagedStatic.h" #include #include @@ -66,6 +67,9 @@ LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() { using namespace llvm; using namespace llvm::orc; +// Serialize rendezvous with the debugger as well as access to shared data. +ManagedStatic JITDebugLock; + // Register debug object, return error message or null for success. static void registerJITLoaderGDBImpl(const char *ObjAddr, size_t Size) { LLVM_DEBUG({ @@ -81,9 +85,7 @@ static void registerJITLoaderGDBImpl(const char *ObjAddr, size_t Size) { E->symfile_size = Size; E->prev_entry = nullptr; - // Serialize rendezvous with the debugger as well as access to shared data. - static std::mutex JITDebugLock; - std::lock_guard Lock(JITDebugLock); + std::lock_guard Lock(*JITDebugLock); // Insert this entry at the head of the list. jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry; diff --git a/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp b/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp index bb41bac3253489..4a236e183c8b69 100644 --- a/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp +++ b/llvm/lib/ExecutionEngine/PerfJITEvents/PerfJITEventListener.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/Path.h" @@ -487,14 +488,15 @@ void PerfJITEventListener::NotifyDebug(uint64_t CodeAddr, } } +// There should be only a single event listener per process, otherwise perf gets +// confused. +llvm::ManagedStatic PerfListener; + } // end anonymous namespace namespace llvm { JITEventListener *JITEventListener::createPerfJITEventListener() { - // There should be only a single event listener per process, otherwise perf - // gets confused. - static PerfJITEventListener PerfListener; - return &PerfListener; + return &*PerfListener; } } // namespace llvm diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 54ab007323302c..2e0cba84916534 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -19,6 +19,7 @@ #include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/MSVCErrorWorkarounds.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include @@ -50,6 +51,8 @@ class RuntimeDyldErrorCategory : public std::error_category { } }; +static ManagedStatic RTDyldErrorCategory; + } char RuntimeDyldError::ID = 0; @@ -59,8 +62,7 @@ void RuntimeDyldError::log(raw_ostream &OS) const { } std::error_code RuntimeDyldError::convertToErrorCode() const { - static RuntimeDyldErrorCategory RTDyldErrorCategory; - return std::error_code(GenericRTDyldError, RTDyldErrorCategory); + return std::error_code(GenericRTDyldError, *RTDyldErrorCategory); } // Empty out-of-line virtual destructor as the key function. diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 2d2bb67366708a..73f8c44b808c11 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -74,16 +74,13 @@ void LLVMDisposeMessage(char *Message) { /*===-- Operations on contexts --------------------------------------------===*/ -static LLVMContext &getGlobalContext() { - static LLVMContext GlobalContext; - return GlobalContext; -} +static ManagedStatic GlobalContext; LLVMContextRef LLVMContextCreate() { return wrap(new LLVMContext()); } -LLVMContextRef LLVMGetGlobalContext() { return wrap(&getGlobalContext()); } +LLVMContextRef LLVMGetGlobalContext() { return wrap(&*GlobalContext); } void LLVMContextSetDiagnosticHandler(LLVMContextRef C, LLVMDiagnosticHandler Handler, @@ -254,7 +251,7 @@ LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI) { /*===-- Operations on modules ---------------------------------------------===*/ LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) { - return wrap(new Module(ModuleID, getGlobalContext())); + return wrap(new Module(ModuleID, *GlobalContext)); } LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp index de970dd4c4cb5d..06b3a3afef9d9b 100644 --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -27,6 +27,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/TypeSize.h" #include #include @@ -240,7 +241,7 @@ void LLVMContextImpl::getSyncScopeNames( /// singleton OptBisect if not explicitly set. OptPassGate &LLVMContextImpl::getOptPassGate() const { if (!OPG) - OPG = &getOptBisector(); + OPG = &(*OptBisector); return *OPG; } diff --git a/llvm/lib/IR/OptBisect.cpp b/llvm/lib/IR/OptBisect.cpp index c9054dba344a79..418311eac814c1 100644 --- a/llvm/lib/IR/OptBisect.cpp +++ b/llvm/lib/IR/OptBisect.cpp @@ -23,7 +23,7 @@ using namespace llvm; static cl::opt OptBisectLimit("opt-bisect-limit", cl::Hidden, cl::init(OptBisect::Disabled), cl::Optional, cl::cb([](int Limit) { - llvm::getOptBisector().setLimit(Limit); + llvm::OptBisector->setLimit(Limit); }), cl::desc("Maximum optimization to perform")); @@ -52,7 +52,4 @@ bool OptBisect::checkPass(const StringRef PassName, const int OptBisect::Disabled; -OptBisect &llvm::getOptBisector() { - static OptBisect OptBisector; - return OptBisector; -} +ManagedStatic llvm::OptBisector; diff --git a/llvm/lib/IR/PassRegistry.cpp b/llvm/lib/IR/PassRegistry.cpp index 6c22fcd3476948..94f607afec47fc 100644 --- a/llvm/lib/IR/PassRegistry.cpp +++ b/llvm/lib/IR/PassRegistry.cpp @@ -15,15 +15,21 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Pass.h" #include "llvm/PassInfo.h" +#include "llvm/Support/ManagedStatic.h" #include #include #include using namespace llvm; +// FIXME: We use ManagedStatic to erase the pass registrar on shutdown. +// Unfortunately, passes are registered with static ctors, and having +// llvm_shutdown clear this map prevents successful resurrection after +// llvm_shutdown is run. Ideally we should find a solution so that we don't +// leak the map, AND can still resurrect after shutdown. +static ManagedStatic PassRegistryObj; PassRegistry *PassRegistry::getPassRegistry() { - static PassRegistry PassRegistryObj; - return &PassRegistryObj; + return &*PassRegistryObj; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Object/Error.cpp b/llvm/lib/Object/Error.cpp index 62cb51ca09e44a..6d1e3f2a59d04f 100644 --- a/llvm/lib/Object/Error.cpp +++ b/llvm/lib/Object/Error.cpp @@ -13,6 +13,7 @@ #include "llvm/Object/Error.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" using namespace llvm; using namespace object; @@ -74,9 +75,10 @@ void GenericBinaryError::log(raw_ostream &OS) const { OS << Msg; } +static ManagedStatic<_object_error_category> error_category; + const std::error_category &object::object_category() { - static _object_error_category error_category; - return error_category; + return *error_category; } llvm::Error llvm::object::isNotObjectErrorInvalidFileType(llvm::Error Err) { diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp index bad8184dffcf5b..ab9f8bf9c957c7 100644 --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -901,11 +901,10 @@ bool OptNoneInstrumentation::shouldRun(StringRef PassID, Any IR) { void OptBisectInstrumentation::registerCallbacks( PassInstrumentationCallbacks &PIC) { - if (!getOptBisector().isEnabled()) + if (!OptBisector->isEnabled()) return; PIC.registerShouldRunOptionalPassCallback([](StringRef PassID, Any IR) { - return isIgnored(PassID) || - getOptBisector().checkPass(PassID, getIRName(IR)); + return isIgnored(PassID) || OptBisector->checkPass(PassID, getIRName(IR)); }); } diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index f4f13bafb233a9..f9e58fd6afa506 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include @@ -896,9 +897,10 @@ std::string CoverageMapError::message() const { return getCoverageMapErrString(Err); } +static ManagedStatic ErrorCategory; + const std::error_category &llvm::coverage::coveragemap_category() { - static CoverageMappingErrorCategoryType ErrorCategory; - return ErrorCategory; + return *ErrorCategory; } char CoverageMapError::ID = 0; diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 370da8a0f5b18d..183f23058426c3 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/SwapByteOrder.h" @@ -176,9 +177,10 @@ class InstrProfErrorCategoryType : public std::error_category { } // end anonymous namespace +static ManagedStatic ErrorCategory; + const std::error_category &llvm::instrprof_category() { - static InstrProfErrorCategoryType ErrorCategory; - return ErrorCategory; + return *ErrorCategory; } namespace { diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp index b4d5550a172182..f794e64a13e739 100644 --- a/llvm/lib/ProfileData/SampleProf.cpp +++ b/llvm/lib/ProfileData/SampleProf.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -97,9 +98,10 @@ class SampleProfErrorCategoryType : public std::error_category { } // end anonymous namespace +static ManagedStatic ErrorCategory; + const std::error_category &llvm::sampleprof_category() { - static SampleProfErrorCategoryType ErrorCategory; - return ErrorCategory; + return *ErrorCategory; } void LineLocation::print(raw_ostream &OS) const { diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp index fbe86f2b59e122..8bfc8ee7a8cc6c 100644 --- a/llvm/lib/Support/Error.cpp +++ b/llvm/lib/Support/Error.cpp @@ -9,6 +9,7 @@ #include "llvm/Support/Error.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include using namespace llvm; @@ -45,10 +46,7 @@ namespace { } -ErrorErrorCategory &getErrorErrorCat() { - static ErrorErrorCategory ErrorErrorCat; - return ErrorErrorCat; -} +static ManagedStatic ErrorErrorCat; namespace llvm { @@ -73,19 +71,19 @@ void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner) { std::error_code ErrorList::convertToErrorCode() const { return std::error_code(static_cast(ErrorErrorCode::MultipleErrors), - getErrorErrorCat()); + *ErrorErrorCat); } std::error_code inconvertibleErrorCode() { return std::error_code(static_cast(ErrorErrorCode::InconvertibleError), - getErrorErrorCat()); + *ErrorErrorCat); } std::error_code FileError::convertToErrorCode() const { std::error_code NestedEC = Err->convertToErrorCode(); if (NestedEC == inconvertibleErrorCode()) return std::error_code(static_cast(ErrorErrorCode::FileError), - getErrorErrorCat()); + *ErrorErrorCat); return NestedEC; } diff --git a/llvm/lib/Support/Unix/Process.inc b/llvm/lib/Support/Unix/Process.inc index c1959b5cc2ae51..3c2d118977c52d 100644 --- a/llvm/lib/Support/Unix/Process.inc +++ b/llvm/lib/Support/Unix/Process.inc @@ -14,6 +14,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" +#include "llvm/Support/ManagedStatic.h" #include #if HAVE_FCNTL_H #include @@ -326,6 +327,10 @@ extern "C" int del_curterm(struct term *termp); extern "C" int tigetnum(char *capname); #endif +#ifdef LLVM_ENABLE_TERMINFO +static ManagedStatic TermColorMutex; +#endif + bool checkTerminalEnvironmentForColors() { if (const char *TermStr = std::getenv("TERM")) { return StringSwitch(TermStr) @@ -346,8 +351,7 @@ bool checkTerminalEnvironmentForColors() { static bool terminalHasColors(int fd) { #ifdef LLVM_ENABLE_TERMINFO // First, acquire a global lock because these C routines are thread hostile. - static std::mutex TermColorMutex; - std::lock_guard G(TermColorMutex); + std::lock_guard G(*TermColorMutex); struct term *previous_term = set_curterm(nullptr); int errret = 0; diff --git a/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp b/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp index 4e41515b997dbc..2d6d72777db22c 100644 --- a/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/InstIterator.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" #include #include @@ -31,27 +32,19 @@ namespace llvm { namespace { typedef std::map > key_val_pair_t; typedef std::map global_val_annot_t; - -struct AnnotationCache { - sys::Mutex Lock; - std::map Cache; -}; - -AnnotationCache &getAnnotationCache() { - static AnnotationCache AC; - return AC; -} +typedef std::map per_module_annot_t; } // anonymous namespace +static ManagedStatic annotationCache; +static sys::Mutex Lock; + void clearAnnotationCache(const Module *Mod) { - auto &AC = getAnnotationCache(); - std::lock_guard Guard(AC.Lock); - AC.Cache.erase(Mod); + std::lock_guard Guard(Lock); + annotationCache->erase(Mod); } static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { - auto &AC = getAnnotationCache(); - std::lock_guard Guard(AC.Lock); + std::lock_guard Guard(Lock); assert(md && "Invalid mdnode for annotation"); assert((md->getNumOperands() % 2) == 1 && "Invalid number of operands"); // start index = 1, to skip the global variable key @@ -77,8 +70,7 @@ static void cacheAnnotationFromMD(const MDNode *md, key_val_pair_t &retval) { } static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { - auto &AC = getAnnotationCache(); - std::lock_guard Guard(AC.Lock); + std::lock_guard Guard(Lock); NamedMDNode *NMD = m->getNamedMetadata("nvvm.annotations"); if (!NMD) return; @@ -101,42 +93,40 @@ static void cacheAnnotationFromMD(const Module *m, const GlobalValue *gv) { if (tmp.empty()) // no annotations for this gv return; - if (AC.Cache.find(m) != AC.Cache.end()) - AC.Cache[m][gv] = std::move(tmp); + if ((*annotationCache).find(m) != (*annotationCache).end()) + (*annotationCache)[m][gv] = std::move(tmp); else { global_val_annot_t tmp1; tmp1[gv] = std::move(tmp); - AC.Cache[m] = std::move(tmp1); + (*annotationCache)[m] = std::move(tmp1); } } bool findOneNVVMAnnotation(const GlobalValue *gv, const std::string &prop, unsigned &retval) { - auto &AC = getAnnotationCache(); - std::lock_guard Guard(AC.Lock); + std::lock_guard Guard(Lock); const Module *m = gv->getParent(); - if (AC.Cache.find(m) == AC.Cache.end()) + if ((*annotationCache).find(m) == (*annotationCache).end()) cacheAnnotationFromMD(m, gv); - else if (AC.Cache[m].find(gv) == AC.Cache[m].end()) + else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) cacheAnnotationFromMD(m, gv); - if (AC.Cache[m][gv].find(prop) == AC.Cache[m][gv].end()) + if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) return false; - retval = AC.Cache[m][gv][prop][0]; + retval = (*annotationCache)[m][gv][prop][0]; return true; } bool findAllNVVMAnnotation(const GlobalValue *gv, const std::string &prop, std::vector &retval) { - auto &AC = getAnnotationCache(); - std::lock_guard Guard(AC.Lock); + std::lock_guard Guard(Lock); const Module *m = gv->getParent(); - if (AC.Cache.find(m) == AC.Cache.end()) + if ((*annotationCache).find(m) == (*annotationCache).end()) cacheAnnotationFromMD(m, gv); - else if (AC.Cache[m].find(gv) == AC.Cache[m].end()) + else if ((*annotationCache)[m].find(gv) == (*annotationCache)[m].end()) cacheAnnotationFromMD(m, gv); - if (AC.Cache[m][gv].find(prop) == AC.Cache[m][gv].end()) + if ((*annotationCache)[m][gv].find(prop) == (*annotationCache)[m][gv].end()) return false; - retval = AC.Cache[m][gv][prop]; + retval = (*annotationCache)[m][gv][prop]; return true; } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp index 0b3e534315d5fd..388c0f9110b768 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp @@ -21,6 +21,7 @@ #include "WebAssemblyRuntimeLibcallSignatures.h" #include "WebAssemblySubtarget.h" #include "llvm/CodeGen/RuntimeLibcalls.h" +#include "llvm/Support/ManagedStatic.h" using namespace llvm; @@ -481,13 +482,10 @@ struct RuntimeLibcallSignatureTable { } }; -RuntimeLibcallSignatureTable &getRuntimeLibcallSignatures() { - static RuntimeLibcallSignatureTable RuntimeLibcallSignatures; - return RuntimeLibcallSignatures; -} +ManagedStatic RuntimeLibcallSignatures; // Maps libcall names to their RTLIB::Libcall number. Builds the map in a -// constructor for use with a static variable +// constructor for use with ManagedStatic struct StaticLibcallNameMap { StringMap Map; StaticLibcallNameMap() { @@ -498,8 +496,7 @@ struct StaticLibcallNameMap { }; for (const auto &NameLibcall : NameLibcalls) { if (NameLibcall.first != nullptr && - getRuntimeLibcallSignatures().Table[NameLibcall.second] != - unsupported) { + RuntimeLibcallSignatures->Table[NameLibcall.second] != unsupported) { assert(Map.find(NameLibcall.first) == Map.end() && "duplicate libcall names in name map"); Map[NameLibcall.first] = NameLibcall.second; @@ -526,7 +523,7 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget, wasm::ValType PtrTy = Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32; - auto &Table = getRuntimeLibcallSignatures().Table; + auto &Table = RuntimeLibcallSignatures->Table; switch (Table[LC]) { case func: break; @@ -888,14 +885,14 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget, } } +static ManagedStatic LibcallNameMap; // TODO: If the RTLIB::Libcall-taking flavor of GetSignature remains unsed // other than here, just roll its logic into this version. void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget, StringRef Name, SmallVectorImpl &Rets, SmallVectorImpl &Params) { - static StaticLibcallNameMap LibcallNameMap; - auto &Map = LibcallNameMap.Map; + auto &Map = LibcallNameMap->Map; auto Val = Map.find(Name); #ifndef NDEBUG if (Val == Map.end()) { diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86InstrRelaxTables.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86InstrRelaxTables.cpp index 640efd468135ff..901082ce6cf379 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86InstrRelaxTables.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86InstrRelaxTables.cpp @@ -13,7 +13,6 @@ #include "X86InstrRelaxTables.h" #include "X86InstrInfo.h" #include "llvm/ADT/STLExtras.h" -#include using namespace llvm; @@ -120,7 +119,7 @@ const X86InstrRelaxTableEntry *llvm::lookupRelaxTable(unsigned ShortOp) { namespace { // This class stores the short form tables. It is instantiated as a -// function scope static variable to lazily init the short form table. +// ManagedStatic to lazily init the short form table. struct X86ShortFormTable { // Stores relaxation table entries sorted by relaxed form opcode. SmallVector Table; @@ -138,9 +137,10 @@ struct X86ShortFormTable { }; } // namespace +static ManagedStatic ShortTable; + const X86InstrRelaxTableEntry *llvm::lookupShortTable(unsigned RelaxOp) { - static X86ShortFormTable ShortTable; - auto &Table = ShortTable.Table; + auto &Table = ShortTable->Table; auto I = llvm::lower_bound(Table, RelaxOp); if (I != Table.end() && I->KeyOp == RelaxOp) return &*I; diff --git a/llvm/lib/Target/X86/X86EvexToVex.cpp b/llvm/lib/Target/X86/X86EvexToVex.cpp index cff95d17c14c1d..c7a013a0b17a14 100644 --- a/llvm/lib/Target/X86/X86EvexToVex.cpp +++ b/llvm/lib/Target/X86/X86EvexToVex.cpp @@ -31,7 +31,6 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/Pass.h" -#include #include #include diff --git a/llvm/lib/Target/X86/X86InstrFoldTables.cpp b/llvm/lib/Target/X86/X86InstrFoldTables.cpp index 8aeb169929f2d2..27220a8d4d9984 100644 --- a/llvm/lib/Target/X86/X86InstrFoldTables.cpp +++ b/llvm/lib/Target/X86/X86InstrFoldTables.cpp @@ -13,7 +13,6 @@ #include "X86InstrFoldTables.h" #include "X86InstrInfo.h" #include "llvm/ADT/STLExtras.h" -#include #include using namespace llvm; @@ -6103,7 +6102,7 @@ llvm::lookupFoldTable(unsigned RegOp, unsigned OpNum) { namespace { // This class stores the memory unfolding tables. It is instantiated as a -// function scope static variable to lazily init the unfolding table. +// ManagedStatic to lazily init the unfolding table. struct X86MemUnfoldTable { // Stores memory unfolding tables entries sorted by opcode. std::vector Table; @@ -6160,10 +6159,11 @@ struct X86MemUnfoldTable { }; } +static ManagedStatic MemUnfoldTable; + const X86MemoryFoldTableEntry * llvm::lookupUnfoldTable(unsigned MemOp) { - static X86MemUnfoldTable MemUnfoldTable; - auto &Table = MemUnfoldTable.Table; + auto &Table = MemUnfoldTable->Table; auto I = llvm::lower_bound(Table, MemOp); if (I != Table.end() && I->KeyOp == MemOp) return &*I; diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index aaee45dc01a588..8d82d78b15b5e9 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -47,6 +47,7 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Host.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" @@ -191,11 +192,7 @@ static cl::opt RemarksFormat( cl::value_desc("format"), cl::init("yaml")); namespace { - -std::vector &getRunPassNames() { - static std::vector RunPassNames; - return RunPassNames; -} +static ManagedStatic> RunPassNames; struct RunPassOption { void operator=(const std::string &Val) const { @@ -204,7 +201,7 @@ struct RunPassOption { SmallVector PassNames; StringRef(Val).split(PassNames, ',', -1, false); for (auto PassName : PassNames) - getRunPassNames().push_back(std::string(PassName)); + RunPassNames->push_back(std::string(PassName)); } }; } @@ -679,7 +676,7 @@ static int compileModule(char **argv, LLVMContext &Context) { // Construct a custom pass pipeline that starts after instruction // selection. - if (!getRunPassNames().empty()) { + if (!RunPassNames->empty()) { if (!MIR) { WithColor::warning(errs(), argv[0]) << "run-pass is for .mir file only.\n"; @@ -697,7 +694,7 @@ static int compileModule(char **argv, LLVMContext &Context) { PM.add(&TPC); PM.add(MMIWP); TPC.printAndVerify(""); - for (const std::string &RunPassName : getRunPassNames()) { + for (const std::string &RunPassName : *RunPassNames) { if (addPass(PM, argv0, RunPassName, TPC)) return 1; } diff --git a/llvm/tools/llvm-xray/xray-registry.cpp b/llvm/tools/llvm-xray/xray-registry.cpp index 34ac07ebe45c1c..e5c253d2e8f10a 100644 --- a/llvm/tools/llvm-xray/xray-registry.cpp +++ b/llvm/tools/llvm-xray/xray-registry.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "xray-registry.h" +#include "llvm/Support/ManagedStatic.h" #include namespace llvm { @@ -18,22 +19,19 @@ namespace xray { using HandlerType = std::function; -static std::unordered_map &getCommands() { - static std::unordered_map Commands; - return Commands; -} +ManagedStatic> Commands; CommandRegistration::CommandRegistration(cl::SubCommand *SC, HandlerType Command) { - assert(getCommands().count(SC) == 0 && + assert(Commands->count(SC) == 0 && "Attempting to overwrite a command handler"); assert(Command && "Attempting to register an empty std::function"); - getCommands()[SC] = Command; + (*Commands)[SC] = Command; } HandlerType dispatch(cl::SubCommand *SC) { - auto It = getCommands().find(SC); - assert(It != getCommands().end() && + auto It = Commands->find(SC); + assert(It != Commands->end() && "Attempting to dispatch on un-registered SubCommand."); return It->second; } diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp index 57dda997db4013..547566cd09e367 100644 --- a/llvm/unittests/Support/ErrorTest.cpp +++ b/llvm/unittests/Support/ErrorTest.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest-spi.h" #include "gtest/gtest.h" @@ -1038,10 +1039,8 @@ class TestErrorCategory : public std::error_category { } }; -const std::error_category &TErrorCategory() { - static TestErrorCategory TestErrCategory; - return TestErrCategory; -} +static llvm::ManagedStatic TestErrCategory; +const std::error_category &TErrorCategory() { return *TestErrCategory; } char TestDebugError::ID;