From 5c1ff11fc326a56899e1843186f0d04007fef888 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Wed, 3 Sep 2008 20:34:58 +0000 Subject: [PATCH] Do not emit a UsedDirective for things in the llvm.used list that have internal linkage; the linker doesn't need or want this. (These objects must still be preserved at compile time, so just removing them from the llvm.used list doesn't work.) Should affect only Darwin. llvm-svn: 55722 --- llvm/include/llvm/CodeGen/AsmPrinter.h | 1 + llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 35 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index 08c3197a7624..6ccef8ca59b9 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -363,6 +363,7 @@ namespace llvm { void printVisibility(const std::string& Name, unsigned Visibility) const; private: + const GlobalValue *findGlobalValue(const Constant* CV); void EmitLLVMUsedList(Constant *List); void EmitXXStructorList(Constant *List); void EmitConstantPool(unsigned Alignment, const char *Section, diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index dc88da954ab6..a720f04a9ae4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -425,8 +425,34 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { return false; } +/// findGlobalValue - if CV is an expression equivalent to a single +/// global value, return that value. +const GlobalValue * AsmPrinter::findGlobalValue(const Constant *CV) { + if (const GlobalValue *GV = dyn_cast(CV)) + return GV; + else if (const ConstantExpr *CE = dyn_cast(CV)) { + const TargetData *TD = TM.getTargetData(); + unsigned Opcode = CE->getOpcode(); + switch (Opcode) { + case Instruction::GetElementPtr: { + const Constant *ptrVal = CE->getOperand(0); + SmallVector idxVec(CE->op_begin()+1, CE->op_end()); + if (TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], idxVec.size())) + return 0; + return findGlobalValue(ptrVal); + } + case Instruction::BitCast: + return findGlobalValue(CE->getOperand(0)); + default: + return 0; + } + } + return 0; +} + /// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each /// global in the specified llvm.used list as being used with this directive. +/// Non-globals (i.e. internal linkage) should not be emitted. void AsmPrinter::EmitLLVMUsedList(Constant *List) { const char *Directive = TAI->getUsedDirective(); @@ -435,9 +461,12 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) { if (InitList == 0) return; for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { - O << Directive; - EmitConstantValueOnly(InitList->getOperand(i)); - O << '\n'; + const GlobalValue *GV = findGlobalValue(InitList->getOperand(i)); + if (GV && !GV->hasInternalLinkage()) { + O << Directive; + EmitConstantValueOnly(InitList->getOperand(i)); + O << '\n'; + } } }