aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-09-26 03:38:18 +0000
committerChris Lattner <sabre@nondot.org>2006-09-26 03:38:18 +0000
commitcb05af852f1d346ac07b84c74a930a5cdbd6d427 (patch)
treeb7a6f3a4174cff9614c3668b631a2dcbc5a7d1ee
parent384299ef45840acf7c43125dc935237b333e339a (diff)
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
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h1
-rw-r--r--include/llvm/Target/TargetAsmInfo.h8
-rw-r--r--lib/CodeGen/AsmPrinter.cpp23
-rw-r--r--lib/Target/TargetAsmInfo.cpp1
4 files changed, 31 insertions, 2 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 52e47faca4..386a8d53fd 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<std::pair<MachineConstantPoolEntry,unsigned> > &CP);
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index 82132c0185..9c3a5ab0f2 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 bcdb393c23..bfc0519806 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<ConstantArray>(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 6efcf4be24..c085eb4db0 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),