[llvm-commits] [llvm] r113283 - in /llvm/trunk: include/llvm/PassRegistry.h lib/VMCore/PassRegistry.cpp

Owen Anderson resistor at mac.com
Tue Sep 7 13:48:10 PDT 2010


Author: resistor
Date: Tue Sep  7 15:48:10 2010
New Revision: 113283

URL: http://llvm.org/viewvc/llvm-project?rev=113283&view=rev
Log:
Fix PR7972, in which the PassRegistry was being leaked.  As part of this,
switch to using a ManagedStatic for the global PassRegistry instead of a
ManagedCleanup, and fix a destruction ordering bug this exposed.

Modified:
    llvm/trunk/include/llvm/PassRegistry.h
    llvm/trunk/lib/VMCore/PassRegistry.cpp

Modified: llvm/trunk/include/llvm/PassRegistry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassRegistry.h?rev=113283&r1=113282&r2=113283&view=diff
==============================================================================
--- llvm/trunk/include/llvm/PassRegistry.h (original)
+++ llvm/trunk/include/llvm/PassRegistry.h Tue Sep  7 15:48:10 2010
@@ -37,6 +37,7 @@
    
 public:
   PassRegistry() : pImpl(0) { }
+  ~PassRegistry();
   
   /// getPassRegistry - Access the global registry object, which is 
   /// automatically initialized at application launch and destroyed by

Modified: llvm/trunk/lib/VMCore/PassRegistry.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassRegistry.cpp?rev=113283&r1=113282&r2=113283&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/PassRegistry.cpp (original)
+++ llvm/trunk/lib/VMCore/PassRegistry.cpp Tue Sep  7 15:48:10 2010
@@ -22,45 +22,14 @@
 
 using namespace llvm;
 
-static PassRegistry *PassRegistryObj = 0;
-PassRegistry *PassRegistry::getPassRegistry() {
-  // Use double-checked locking to safely initialize the registrar when
-  // we're running in multithreaded mode.
-  PassRegistry* tmp = PassRegistryObj;
-  if (llvm_is_multithreaded()) {
-    sys::MemoryFence();
-    if (!tmp) {
-      llvm_acquire_global_lock();
-      tmp = PassRegistryObj;
-      if (!tmp) {
-        tmp = new PassRegistry();
-        sys::MemoryFence();
-        PassRegistryObj = tmp;
-      }
-      llvm_release_global_lock();
-    }
-  } else if (!tmp) {
-    PassRegistryObj = new PassRegistry();
-  }
-  
-  return PassRegistryObj;
-}
-
-namespace {
-
-// FIXME: We use ManagedCleanup to erase the pass registrar on shutdown.
+// 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 ressurection 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.
-void cleanupPassRegistry(void*) {
-  if (PassRegistryObj) {
-    delete PassRegistryObj;
-    PassRegistryObj = 0;
-  }
-}
-ManagedCleanup<&cleanupPassRegistry> registryCleanup ATTRIBUTE_USED;
-
+static ManagedStatic<PassRegistry> PassRegistryObj;
+PassRegistry *PassRegistry::getPassRegistry() {
+  return &*PassRegistryObj;
 }
 
 //===----------------------------------------------------------------------===//
@@ -94,6 +63,12 @@
 // Accessors
 //
 
+PassRegistry::~PassRegistry() {
+  PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(pImpl);
+  if (Impl) delete Impl;
+  pImpl = 0;
+}
+
 const PassInfo *PassRegistry::getPassInfo(const void *TI) const {
   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
   PassRegistryImpl::MapType::const_iterator I = Impl->PassInfoMap.find(TI);
@@ -188,6 +163,12 @@
 }
 
 void PassRegistry::removeRegistrationListener(PassRegistrationListener *L) {
+  // 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
+  // PassRegistry is destructed before the object that triggers this call.
+  if (!pImpl) return;
+  
   PassRegistryImpl *Impl = static_cast<PassRegistryImpl*>(getImpl());
   std::vector<PassRegistrationListener*>::iterator I =
     std::find(Impl->Listeners.begin(), Impl->Listeners.end(), L);





More information about the llvm-commits mailing list