[llvm-commits] [llvm] r163814 - /llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp

Manman Ren mren at apple.com
Thu Sep 13 10:43:46 PDT 2012


Author: mren
Date: Thu Sep 13 12:43:46 2012
New Revision: 163814

URL: http://llvm.org/viewvc/llvm-project?rev=163814&view=rev
Log:
AsmWriterEmitter: increase the number of bits for OpcodeInfo from 32-bit to
48-bit if necessary, in order to reduce the generated code size.

We have 900 cases not covered by OpcodeInfo in ATT AsmWriter and more in Intel
AsmWriter and ARM AsmWriter.

This patch reduced the clang Release build size by 50k, running on a Mac Pro.

Modified:
    llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp

Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=163814&r1=163813&r2=163814&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Thu Sep 13 12:43:46 2012
@@ -313,7 +313,9 @@
 
   /// OpcodeInfo - This encodes the index of the string to use for the first
   /// chunk of the output as well as indices used for operand printing.
-  std::vector<unsigned> OpcodeInfo;
+  /// To reduce the number of unhandled cases, we expand the size from 32-bit
+  /// to 32+16 = 48-bit.
+  std::vector<std::pair<unsigned, uint16_t> > OpcodeInfo;
 
   // Add all strings to the string table upfront so it can generate an optimized
   // representation.
@@ -354,7 +356,7 @@
     }
 
     // Bias offset by one since we want 0 as a sentinel.
-    OpcodeInfo.push_back(Idx+1);
+    OpcodeInfo.push_back(std::make_pair(Idx+1, 0));
   }
 
   // Figure out how many bits we used for the string index.
@@ -362,7 +364,7 @@
 
   // To reduce code size, we compactify common instructions into a few bits
   // in the opcode-indexed table.
-  unsigned BitsLeft = 32-AsmStrBits;
+  unsigned BitsLeft = 32+16-AsmStrBits;
 
   std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
 
@@ -380,6 +382,13 @@
     // ceil(log2(numentries)).
     unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
 
+    // Check whether these Bits will fit in the first 32 bits.
+    if (BitsLeft > 16 && NumBits > BitsLeft - 16)
+      // We don't have enough bits in the first 32 bits, and we skip the
+      // left-over bits.
+      BitsLeft = 16;
+    bool UseSecond = (BitsLeft <= 16);
+
     // If we don't have enough bits for this operand, don't include it.
     if (NumBits > BitsLeft) {
       DEBUG(errs() << "Not enough bits to densely encode " << NumBits
@@ -390,8 +399,13 @@
     // Otherwise, we can include this in the initial lookup table.  Add it in.
     BitsLeft -= NumBits;
     for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i)
-      if (InstIdxs[i] != ~0U)
-        OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits);
+      // Update the first 32 bits or the second 16 bits.
+      if (InstIdxs[i] != ~0U) {
+        if (UseSecond)
+          OpcodeInfo[i].second |= InstIdxs[i] << BitsLeft;
+        else
+          OpcodeInfo[i].first |= InstIdxs[i] << (BitsLeft-16+AsmStrBits);
+      }
 
     // Remove the info about this operand.
     for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
@@ -413,13 +427,25 @@
 
   O<<"  static const unsigned OpInfo[] = {\n";
   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
-    O << "    " << OpcodeInfo[i] << "U,\t// "
+    O << "    " << OpcodeInfo[i].first << "U,\t// "
       << NumberedInstructions[i]->TheDef->getName() << "\n";
   }
   // Add a dummy entry so the array init doesn't end with a comma.
   O << "    0U\n";
   O << "  };\n\n";
 
+  if (BitsLeft < 16) {
+    // Add a second OpInfo table only when it is necessary.
+    O<<"  static const short OpInfo2[] = {\n";
+    for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+      O << "    " << OpcodeInfo[i].second << "U,\t// "
+        << NumberedInstructions[i]->TheDef->getName() << "\n";
+    }
+    // Add a dummy entry so the array init doesn't end with a comma.
+    O << "    0U\n";
+    O << "  };\n\n";
+  }
+
   // Emit the string itself.
   O << "  const char AsmStrs[] = {\n";
   StringTable.emit(O, printChar);
@@ -428,12 +454,14 @@
   O << "  O << \"\\t\";\n\n";
 
   O << "  // Emit the opcode for the instruction.\n"
-    << "  unsigned Bits = OpInfo[MI->getOpcode()];\n"
-    << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n"
+    << "  unsigned Bits = OpInfo[MI->getOpcode()];\n";
+  if (BitsLeft < 16)
+    O << "  unsigned short Bits2 = OpInfo2[MI->getOpcode()];\n";
+  O << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n"
     << "  O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
 
   // Output the table driven operand information.
-  BitsLeft = 32-AsmStrBits;
+  BitsLeft = 32+16-AsmStrBits;
   for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
     std::vector<std::string> &Commands = TableDrivenOperandPrinters[i];
 
@@ -442,6 +470,11 @@
     unsigned NumBits = Log2_32_Ceil(Commands.size());
     assert(NumBits <= BitsLeft && "consistency error");
 
+    // Check whether these Bits will fit in the first 32 bits.
+    if (BitsLeft > 16 && NumBits > BitsLeft - 16)
+      BitsLeft = 16;
+    bool UseSecond = (BitsLeft <= 16);
+
     // Emit code to extract this field from Bits.
     BitsLeft -= NumBits;
 
@@ -450,7 +483,8 @@
 
     if (Commands.size() == 2) {
       // Emit two possibilitys with if/else.
-      O << "  if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
+      O << (UseSecond ? "  if ((Bits2 >> " : "  if ((Bits >> ")
+        << (UseSecond ? BitsLeft : (BitsLeft-16+AsmStrBits)) << ") & "
         << ((1 << NumBits)-1) << ") {\n"
         << Commands[1]
         << "  } else {\n"
@@ -460,7 +494,8 @@
       // Emit a single possibility.
       O << Commands[0] << "\n\n";
     } else {
-      O << "  switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
+      O << (UseSecond ? "  switch ((Bits2 >> " : "  switch ((Bits >> ")
+        << (UseSecond ? BitsLeft : (BitsLeft-16+AsmStrBits)) << ") & "
         << ((1 << NumBits)-1) << ") {\n"
         << "  default:   // unreachable.\n";
 





More information about the llvm-commits mailing list