1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

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.

llvm-svn: 30604
This commit is contained in:
Chris Lattner 2006-09-26 03:38:18 +00:00
parent bab51c66fc
commit 167aa73273
4 changed files with 31 additions and 2 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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) {

View File

@ -58,6 +58,7 @@ TargetAsmInfo::TargetAsmInfo() :
COMMDirective("\t.comm\t"),
COMMDirectiveTakesAlignment(true),
HasDotTypeDotSizeDirective(true),
UsedDirective(0),
HasLEB128(false),
HasDotLoc(false),
HasDotFile(false),