[PATCH] Don't register and de-register all PassRegistrationListeners automatically

Zachary Turner zturner at google.com
Wed Jun 11 16:01:15 PDT 2014


Hi dblaikie, rnk,

PassRegistrationListener is intended for use as a generic listener.
In some cases, PassRegistrationListener-derived classes were being
created, and automatically registered and de-registered in static
constructors and destructors.  Since ManagedStatics are destroyed
prior to program shutdown, this leads to errors where an attempt is
made to access a ManagedStatic that has already been destroyed.
This patch addresses this by removing automatic de-registration
on destruction entirely.

In other cases, registering / de-registering a PassRegistrationListener
is not even necessarily desired, as they can be used for enumeration
without being registered.  So this change additionally moves the 
automatic registration out of the base class and into those concrete
implementations which desire this behavior.

http://reviews.llvm.org/D4106

Files:
  include/llvm/IR/LegacyPassNameParser.h
  include/llvm/PassSupport.h
  lib/IR/Pass.cpp

Index: include/llvm/IR/LegacyPassNameParser.h
===================================================================
--- include/llvm/IR/LegacyPassNameParser.h
+++ include/llvm/IR/LegacyPassNameParser.h
@@ -43,7 +43,7 @@
                        public cl::parser<const PassInfo*> {
   cl::Option *Opt;
 public:
-  PassNameParser() : Opt(nullptr) {}
+  PassNameParser();
   virtual ~PassNameParser();
 
   void initialize(cl::Option &O) {
Index: include/llvm/PassSupport.h
===================================================================
--- include/llvm/PassSupport.h
+++ include/llvm/PassSupport.h
@@ -337,19 +337,12 @@
 /// clients that are interested in which passes get registered and unregistered
 /// at runtime (which can be because of the RegisterPass constructors being run
 /// as the program starts up, or may be because a shared object just got
-/// loaded).  Deriving from the PassRegistrationListener class automatically
-/// registers your object to receive callbacks indicating when passes are loaded
-/// and removed.
+/// loaded).
 ///
 struct PassRegistrationListener {
 
-  /// PassRegistrationListener ctor - Add the current object to the list of
-  /// PassRegistrationListeners...
-  PassRegistrationListener();
-
-  /// dtor - Remove object from list of listeners...
-  ///
-  virtual ~PassRegistrationListener();
+  PassRegistrationListener() {}
+  virtual ~PassRegistrationListener() {}
 
   /// Callback functions - These functions are invoked whenever a pass is loaded
   /// or removed from the current executable.
Index: lib/IR/Pass.cpp
===================================================================
--- lib/IR/Pass.cpp
+++ lib/IR/Pass.cpp
@@ -224,25 +224,23 @@
 // PassRegistrationListener implementation
 //
 
-// PassRegistrationListener ctor - Add the current object to the list of
-// PassRegistrationListeners...
-PassRegistrationListener::PassRegistrationListener() {
-  PassRegistry::getPassRegistry()->addRegistrationListener(this);
-}
-
-// dtor - Remove object from list of listeners...
-PassRegistrationListener::~PassRegistrationListener() {
-  PassRegistry::getPassRegistry()->removeRegistrationListener(this);
-}
-
 // enumeratePasses - Iterate over the registered passes, calling the
 // passEnumerate callback on each PassInfo object.
 //
 void PassRegistrationListener::enumeratePasses() {
   PassRegistry::getPassRegistry()->enumerateWith(this);
 }
 
-PassNameParser::~PassNameParser() {}
+PassNameParser::PassNameParser()
+    : Opt(nullptr) {
+  PassRegistry::getPassRegistry()->addRegistrationListener(this);
+}
+
+PassNameParser::~PassNameParser() {
+  // This only gets called during static destruction, in which case the
+  // PassRegistry will have already been destroyed by llvm_shutdown().  So
+  // attempting to remove the registration listener is an error.
+}
 
 //===----------------------------------------------------------------------===//
 //   AnalysisUsage Class Implementation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4106.10337.patch
Type: text/x-patch
Size: 2951 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140611/d86a5a63/attachment.bin>


More information about the llvm-commits mailing list