Emit .set directives for jump table entries when possible, which reduces

the number of relocations in object files, shrinkifying them.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29650 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nate Begeman 2006-08-12 21:29:52 +00:00
parent f6e190fae0
commit 52a51e38dc
4 changed files with 50 additions and 4 deletions

View File

@ -185,6 +185,10 @@ namespace llvm {
//===--- Global Variable Emission Directives --------------------------===// //===--- Global Variable Emission Directives --------------------------===//
/// SetDirective - This is the name of a directive that can be used to tell
/// the assembler to set the value of a variable to some expression.
const char *SetDirective; // Defaults to null.
/// LCOMMDirective - This is the name of a directive (if supported) that can /// LCOMMDirective - This is the name of a directive (if supported) that can
/// be used to efficiently declare a local (internal) block of zero /// be used to efficiently declare a local (internal) block of zero
/// initialized data in the .bss/.data section. The syntax expected is: /// initialized data in the .bss/.data section. The syntax expected is:
@ -323,6 +327,10 @@ namespace llvm {
bool printColon = false, bool printColon = false,
bool printComment = true) const; bool printComment = true) const;
/// printSetLabel - This method prints a set label for the specified
/// MachineBasicBlock
void printSetLabel(unsigned uid, const MachineBasicBlock *MBB) const;
private: private:
void EmitXXStructorList(Constant *List); void EmitXXStructorList(Constant *List);
void EmitConstantPool(unsigned Alignment, const char *Section, void EmitConstantPool(unsigned Alignment, const char *Section,

View File

@ -59,6 +59,7 @@ AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm)
FourByteConstantSection(0), FourByteConstantSection(0),
EightByteConstantSection(0), EightByteConstantSection(0),
SixteenByteConstantSection(0), SixteenByteConstantSection(0),
SetDirective(0),
LCOMMDirective(0), LCOMMDirective(0),
COMMDirective("\t.comm\t"), COMMDirective("\t.comm\t"),
COMMDirectiveTakesAlignment(true), COMMDirectiveTakesAlignment(true),
@ -228,15 +229,36 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) {
EmitAlignment(Log2_32(TD->getPointerAlignment())); EmitAlignment(Log2_32(TD->getPointerAlignment()));
for (unsigned i = 0, e = JT.size(); i != e; ++i) { for (unsigned i = 0, e = JT.size(); i != e; ++i) {
const std::vector<MachineBasicBlock*> &JTBBs = JT[i].MBBs;
// For PIC codegen, if possible we want to use the SetDirective to reduce
// the number of relocations the assembler will generate for the jump table.
// Set directives are all printed before the jump table itself.
std::set<MachineBasicBlock*> EmittedSets;
if (SetDirective && TM.getRelocationModel() == Reloc::PIC_)
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
if (EmittedSets.insert(JTBBs[ii]).second)
printSetLabel(i, JTBBs[ii]);
O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i
<< ":\n"; << ":\n";
const std::vector<MachineBasicBlock*> &JTBBs = JT[i].MBBs;
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
O << JTEntryDirective << ' '; O << JTEntryDirective << ' ';
printBasicBlockLabel(JTBBs[ii], false, false); // If we have emitted set directives for the jump table entries, print
if (TM.getRelocationModel() == Reloc::PIC_) { // them rather than the entries themselves. If we're emitting PIC, then
// emit the table entries as differences between two text section labels.
// If we're emitting non-PIC code, then emit the entries as direct
// references to the target basic blocks.
if (!EmittedSets.empty()) {
O << PrivateGlobalPrefix << getFunctionNumber() << '_' << i << "_set_"
<< JTBBs[ii]->getNumber();
} else if (TM.getRelocationModel() == Reloc::PIC_) {
printBasicBlockLabel(JTBBs[ii], false, false);
O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber() O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber()
<< '_' << i; << '_' << i;
} else {
printBasicBlockLabel(JTBBs[ii], false, false);
} }
O << '\n'; O << '\n';
} }
@ -818,3 +840,17 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB,
if (printComment) if (printComment)
O << '\t' << CommentString << MBB->getBasicBlock()->getName(); O << '\t' << CommentString << MBB->getBasicBlock()->getName();
} }
/// printSetLabel - This method prints a set label for the specified
/// MachineBasicBlock
void AsmPrinter::printSetLabel(unsigned uid,
const MachineBasicBlock *MBB) const {
if (!SetDirective)
return;
O << SetDirective << ' ' << PrivateGlobalPrefix << getFunctionNumber()
<< '_' << uid << "_set_" << MBB->getNumber() << ',';
printBasicBlockLabel(MBB, false, false);
O << '-' << PrivateGlobalPrefix << "JTI" << getFunctionNumber()
<< '_' << uid << '\n';
}

View File

@ -276,6 +276,7 @@ namespace {
GlobalPrefix = "_"; GlobalPrefix = "_";
PrivateGlobalPrefix = "L"; // Marker for constant pool idxs PrivateGlobalPrefix = "L"; // Marker for constant pool idxs
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
SetDirective = "\t.set";
if (isPPC64) if (isPPC64)
Data64bitsDirective = ".quad\t"; // we can't emit a 64-bit unit Data64bitsDirective = ".quad\t"; // we can't emit a 64-bit unit
else else

View File

@ -72,6 +72,7 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) {
StaticDtorsSection = ".mod_term_func"; StaticDtorsSection = ".mod_term_func";
InlineAsmStart = "# InlineAsm Start"; InlineAsmStart = "# InlineAsm Start";
InlineAsmEnd = "# InlineAsm End"; InlineAsmEnd = "# InlineAsm End";
SetDirective = "\t.set";
break; break;
case X86Subtarget::isCygwin: case X86Subtarget::isCygwin:
GlobalPrefix = "_"; GlobalPrefix = "_";