Emit .set directives for jump table entries when possible, which reduces
authorNate Begeman <natebegeman@mac.com>
Sat, 12 Aug 2006 21:29:52 +0000 (21:29 +0000)
committerNate Begeman <natebegeman@mac.com>
Sat, 12 Aug 2006 21:29:52 +0000 (21:29 +0000)
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
lib/CodeGen/AsmPrinter.cpp
lib/Target/PowerPC/PPCAsmPrinter.cpp
lib/Target/X86/X86AsmPrinter.cpp

index 802fe6db445e85cc230cf7317af7b9c276846704..686a0755197a9c7af11537f59a9c9f337972a230 100644 (file)
@@ -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);
index ca9b50bb81229ebe917bcb245d602ac206dbded9..266f82a0916409897f2d3230f41bbaa3c6fc2446 100644 (file)
@@ -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<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 
       << ":\n";
-    const std::vector<MachineBasicBlock*> &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';
+}
index bf9c608d51545a063634d26257ce21447aaf039c..5850682005278e5dad4db5caaef6cb67056d56b7 100644 (file)
@@ -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
index 4981964094f88f3d2a416c39d5024340ac0a5470..9e862e8c6fa92e6a22101008e706262d70fb051e 100644 (file)
@@ -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 = "_";