Use llvm.global_ctors to locate global constructors instead
authorDan Gohman <gohman@apple.com>
Wed, 18 Jan 2012 21:19:38 +0000 (21:19 +0000)
committerDan Gohman <gohman@apple.com>
Wed, 18 Jan 2012 21:19:38 +0000 (21:19 +0000)
of recognizing them by name.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148416 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/ObjCARC.cpp
test/Transforms/ObjCARC/apelim.ll

index 87df83857b18ca5782a31eba8afd377accd027d0..a01676ab65b74129a4be8e55b27334469111b503 100644 (file)
@@ -887,6 +887,8 @@ bool ObjCARCExpand::runOnFunction(Function &F) {
 // ARC autorelease pool elimination.
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Constants.h"
+
 namespace {
   /// ObjCARCAPElim - Autorelease pool elimination.
   class ObjCARCAPElim : public ModulePass {
@@ -978,17 +980,28 @@ bool ObjCARCAPElim::runOnModule(Module &M) {
   if (!ModuleHasARC(M))
     return false;
 
+  // Find the llvm.global_ctors variable, as the first step in
+  // identifying the global constructors.
+  GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
+  if (!GV)
+    return false;
+
+  assert(GV->hasDefinitiveInitializer() &&
+         "llvm.global_ctors is uncooperative!");
+
   bool Changed = false;
 
-  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
-    Function *F = I;
+  // Dig the constructor functions out of GV's initializer.
+  ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
+  for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end();
+       OI != OE; ++OI) {
+    Value *Op = *OI;
+    // llvm.global_ctors is an array of pairs where the second members
+    // are constructor functions.
+    Function *F = cast<Function>(cast<ConstantStruct>(Op)->getOperand(1));
     // Only look at function definitions.
     if (F->isDeclaration())
       continue;
-    // Only look at global constructor functions. Unfortunately,
-    // the name is the most convenient way to recognize them.
-    if (!F->getName().startswith("_GLOBAL__I_"))
-      continue;
     // Only look at functions with one basic block.
     if (llvm::next(F->begin()) != F->end())
       continue;
index 5fefe53551c115ff99445d026e3251a7953e8683..8c7b5b1e654f47645bc57c20faad41993643cd79 100644 (file)
@@ -1,6 +1,8 @@
 ; RUN: opt -S -objc-arc-apelim < %s | FileCheck %s
 ; rdar://10227311
 
+@llvm.global_ctors = appending global [2 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_x }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_y }]
+
 @x = global i32 0
 
 declare i32 @bar() nounwind