[llvm-commits] [llvm] r148416 - in /llvm/trunk: lib/Transforms/Scalar/ObjCARC.cpp test/Transforms/ObjCARC/apelim.ll

Dan Gohman gohman at apple.com
Wed Jan 18 13:19:38 PST 2012


Author: djg
Date: Wed Jan 18 15:19:38 2012
New Revision: 148416

URL: http://llvm.org/viewvc/llvm-project?rev=148416&view=rev
Log:
Use llvm.global_ctors to locate global constructors instead
of recognizing them by name.

Modified:
    llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
    llvm/trunk/test/Transforms/ObjCARC/apelim.ll

Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=148416&r1=148415&r2=148416&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Wed Jan 18 15:19:38 2012
@@ -887,6 +887,8 @@
 // ARC autorelease pool elimination.
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Constants.h"
+
 namespace {
   /// ObjCARCAPElim - Autorelease pool elimination.
   class ObjCARCAPElim : public ModulePass {
@@ -978,17 +980,28 @@
   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;

Modified: llvm/trunk/test/Transforms/ObjCARC/apelim.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ObjCARC/apelim.ll?rev=148416&r1=148415&r2=148416&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ObjCARC/apelim.ll (original)
+++ llvm/trunk/test/Transforms/ObjCARC/apelim.ll Wed Jan 18 15:19:38 2012
@@ -1,6 +1,8 @@
 ; RUN: opt -S -objc-arc-apelim < %s | FileCheck %s
 ; rdar://10227311
 
+ at 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





More information about the llvm-commits mailing list