Do not emit a UsedDirective for things in the llvm.used
authorDale Johannesen <dalej@apple.com>
Wed, 3 Sep 2008 20:34:58 +0000 (20:34 +0000)
committerDale Johannesen <dalej@apple.com>
Wed, 3 Sep 2008 20:34:58 +0000 (20:34 +0000)
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.

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

include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp

index 08c3197a7624f00146595c6ff854c03f5d9ae60b..6ccef8ca59b9cb76576273fb79dbb5450a567183 100644 (file)
@@ -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,
index dc88da954ab60af0c0909cdbebbc9efe974a1560..a720f04a9ae4f6a52d3f2b15a66b2740aa19cd3c 100644 (file)
@@ -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<GlobalValue>(CV))
+    return GV;
+  else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
+    const TargetData *TD = TM.getTargetData();
+    unsigned Opcode = CE->getOpcode();    
+    switch (Opcode) {
+    case Instruction::GetElementPtr: {
+      const Constant *ptrVal = CE->getOperand(0);
+      SmallVector<Value*, 8> 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';
+    }
   }
 }