From cb05af852f1d346ac07b84c74a930a5cdbd6d427 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 26 Sep 2006 03:38:18 +0000 Subject: [PATCH] Add support for targets that want to do something with the llvm.used list, because they have an aggressive linker that does dead code stripping. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30604 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 1 + include/llvm/Target/TargetAsmInfo.h | 8 ++++++++ lib/CodeGen/AsmPrinter.cpp | 23 +++++++++++++++++++++-- lib/Target/TargetAsmInfo.cpp | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 52e47faca48..386a8d53fd6 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -197,6 +197,7 @@ namespace llvm { void printDataDirective(const Type *type); private: + void EmitLLVMUsedList(Constant *List); void EmitXXStructorList(Constant *List); void EmitConstantPool(unsigned Alignment, const char *Section, std::vector > &CP); diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 82132c01850..9c3a5ab0f2c 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -199,6 +199,11 @@ namespace llvm { /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. + /// UsedDirective - This directive, if non-null, is used to declare a global + /// as being used somehow that the assembler can't see. This prevents dead + /// code elimination on some targets. + const char *UsedDirective; // Defaults to null. + //===--- Dwarf Emission Directives -----------------------------------===// /// HasLEB128 - True if target asm supports leb128 directives. @@ -387,6 +392,9 @@ namespace llvm { bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; } + const char *getUsedDirective() const { + return UsedDirective; + } bool hasLEB128() const { return HasLEB128; } diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index bcdb393c239..bfc0519806c 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -253,8 +253,11 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { assert(GV->hasInitializer() && "Not a special LLVM global!"); - if (GV->getName() == "llvm.used") - return true; // No need to emit this at all. + if (GV->getName() == "llvm.used") { + if (TAI->getUsedDirective() != 0) // No need to emit this at all. + EmitLLVMUsedList(GV->getInitializer()); + return true; + } if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) { SwitchToDataSection(TAI->getStaticCtorsSection(), 0); @@ -273,6 +276,22 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { return false; } +/// EmitLLVMUsedList - For targets that define a TAI::UsedDirective, mark each +/// global in the specified llvm.used list as being used with this directive. +void AsmPrinter::EmitLLVMUsedList(Constant *List) { + const char *Directive = TAI->getUsedDirective(); + + // Should be an array of 'sbyte*'. + ConstantArray *InitList = dyn_cast(List); + if (InitList == 0) return; + + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { + O << Directive; + EmitConstantValueOnly(InitList->getOperand(i)); + O << "\n"; + } +} + /// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the /// function pointers, ignoring the init priority. void AsmPrinter::EmitXXStructorList(Constant *List) { diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 6efcf4be245..c085eb4db02 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -58,6 +58,7 @@ TargetAsmInfo::TargetAsmInfo() : COMMDirective("\t.comm\t"), COMMDirectiveTakesAlignment(true), HasDotTypeDotSizeDirective(true), + UsedDirective(0), HasLEB128(false), HasDotLoc(false), HasDotFile(false), -- 2.34.1