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

Manman Ren mren at apple.com
Thu Sep 13 13:40:36 PDT 2012


On Sep 13, 2012, at 1:21 PM, Manman Ren <mren at apple.com> wrote:

> 
> On Sep 13, 2012, at 11:32 AM, Evan Cheng <evan.cheng at apple.com> wrote:
> 
>> 
>> On Sep 13, 2012, at 10:43 AM, Manman Ren <mren at apple.com> wrote:
>> 
>>> 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.
>> 
>> How does this impact size of other targets?
> This will reduce code size for ARMAsmWriter, X86AsmWriter, Hexagon, and NVPTX, may increase code size for PowerPC (add a 1k bytes table, but removed a switch with 20 cases), and should not impact  other backends, since we only add 16 more bits if necessary.
> 
> I was not paying attention to targets not included in the clang release build. I will collect the size of the object files with and without the patch.
< 157856 libLLVMARMAsmPrinter.a
---
> 144376 libLLVMARMAsmPrinter.a
22c22
< 98072 libLLVMHexagonAsmPrinter.a
---
> 85848 libLLVMHexagonAsmPrinter.a
52c52
< 913224 libLLVMNVPTXCodeGen.a
---
> 886112 libLLVMNVPTXCodeGen.a
56c56
< 24784 libLLVMPowerPCAsmPrinter.a
---
> 25928 libLLVMPowerPCAsmPrinter.a
72c72
< 133760 libLLVMX86AsmPrinter.a
---
> 125904 libLLVMX86AsmPrinter.a

We did increase PowerPC by 1k using ls command.
Thanks,
Manman
> 
> Thanks,
> Manman
> 
>> 
>> 
>> Evan
>> 
>>> 
>>> 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";
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list