Use llvm.global_ctors to locate global constructors instead

of recognizing them by name.

llvm-svn: 148416
This commit is contained in:
Dan Gohman 2012-01-18 21:19:38 +00:00
parent edd8e46c61
commit 48f4e5752e
2 changed files with 21 additions and 6 deletions

View 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;

View 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