From 52a51e38dc312aa262b0d771419afe1785f3cb22 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sat, 12 Aug 2006 21:29:52 +0000 Subject: [PATCH] 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 --- include/llvm/CodeGen/AsmPrinter.h | 10 ++++++- lib/CodeGen/AsmPrinter.cpp | 42 ++++++++++++++++++++++++++-- lib/Target/PowerPC/PPCAsmPrinter.cpp | 1 + lib/Target/X86/X86AsmPrinter.cpp | 1 + 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 802fe6db445..686a0755197 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -185,6 +185,10 @@ namespace llvm { //===--- 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 /// be used to efficiently declare a local (internal) block of zero /// initialized data in the .bss/.data section. The syntax expected is: @@ -193,7 +197,7 @@ namespace llvm { const char *LCOMMDirective; // Defaults to null. const char *COMMDirective; // Defaults to "\t.comm\t". - + /// COMMDirectiveTakesAlignment - True if COMMDirective take a third /// argument that specifies the alignment of the declaration. bool COMMDirectiveTakesAlignment; // Defaults to true. @@ -322,6 +326,10 @@ namespace llvm { virtual void printBasicBlockLabel(const MachineBasicBlock *MBB, bool printColon = false, bool printComment = true) const; + + /// printSetLabel - This method prints a set label for the specified + /// MachineBasicBlock + void printSetLabel(unsigned uid, const MachineBasicBlock *MBB) const; private: void EmitXXStructorList(Constant *List); diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index ca9b50bb812..266f82a0916 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -59,6 +59,7 @@ AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm) FourByteConstantSection(0), EightByteConstantSection(0), SixteenByteConstantSection(0), + SetDirective(0), LCOMMDirective(0), COMMDirective("\t.comm\t"), COMMDirectiveTakesAlignment(true), @@ -228,15 +229,36 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI) { EmitAlignment(Log2_32(TD->getPointerAlignment())); for (unsigned i = 0, e = JT.size(); i != e; ++i) { + const std::vector &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 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 << ":\n"; - const std::vector &JTBBs = JT[i].MBBs; + for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { O << JTEntryDirective << ' '; - printBasicBlockLabel(JTBBs[ii], false, false); - if (TM.getRelocationModel() == Reloc::PIC_) { + // If we have emitted set directives for the jump table entries, print + // 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() << '_' << i; + } else { + printBasicBlockLabel(JTBBs[ii], false, false); } O << '\n'; } @@ -818,3 +840,17 @@ void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB, if (printComment) 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'; +} diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index bf9c608d515..58506820052 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -276,6 +276,7 @@ namespace { GlobalPrefix = "_"; PrivateGlobalPrefix = "L"; // Marker for constant pool idxs ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. + SetDirective = "\t.set"; if (isPPC64) Data64bitsDirective = ".quad\t"; // we can't emit a 64-bit unit else diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 4981964094f..9e862e8c6fa 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -72,6 +72,7 @@ bool X86SharedAsmPrinter::doInitialization(Module &M) { StaticDtorsSection = ".mod_term_func"; InlineAsmStart = "# InlineAsm Start"; InlineAsmEnd = "# InlineAsm End"; + SetDirective = "\t.set"; break; case X86Subtarget::isCygwin: GlobalPrefix = "_";