[llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Jan 22 12:31:32 PST 2005



Changes in directory llvm/utils/TableGen:

AsmWriterEmitter.cpp updated: 1.16 -> 1.17
---
Log message:

This is the final big of factoring.  This shares cases in suboperand 
differences, which means that identical instructions (after stripping off
the first literal string) do not run any different code at all.  On the X86,
this turns this code:

    switch (MI->getOpcode()) {
    case X86::ADC32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::ADC32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::ADC32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::ADD32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::ADD32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::ADD32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::AND32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::AND32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::AND32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::CMP32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::CMP32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::MOV32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::MOV32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::OR32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::OR32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::OR32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::ROL32mi: printOperand(MI, 4, MVT::i8); break;
    case X86::ROR32mi: printOperand(MI, 4, MVT::i8); break;
    case X86::SAR32mi: printOperand(MI, 4, MVT::i8); break;
    case X86::SBB32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::SBB32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::SBB32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::SHL32mi: printOperand(MI, 4, MVT::i8); break;
    case X86::SHLD32mrCL: printOperand(MI, 4, MVT::i32); break;
    case X86::SHR32mi: printOperand(MI, 4, MVT::i8); break;
    case X86::SHRD32mrCL: printOperand(MI, 4, MVT::i32); break;
    case X86::SUB32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::SUB32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::SUB32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::TEST32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::TEST32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::TEST8mi: printOperand(MI, 4, MVT::i8); break;
    case X86::XCHG32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::XOR32mi: printOperand(MI, 4, MVT::i32); break;
    case X86::XOR32mi8: printOperand(MI, 4, MVT::i8); break;
    case X86::XOR32mr: printOperand(MI, 4, MVT::i32); break;
    }

into this:

    switch (MI->getOpcode()) {
    case X86::ADC32mi: 
    case X86::ADC32mr: 
    case X86::ADD32mi: 
    case X86::ADD32mr: 
    case X86::AND32mi: 
    case X86::AND32mr: 
    case X86::CMP32mi: 
    case X86::CMP32mr: 
    case X86::MOV32mi: 
    case X86::MOV32mr: 
    case X86::OR32mi: 
    case X86::OR32mr: 
    case X86::SBB32mi: 
    case X86::SBB32mr: 
    case X86::SHLD32mrCL: 
    case X86::SHRD32mrCL: 
    case X86::SUB32mi: 
    case X86::SUB32mr: 
    case X86::TEST32mi: 
    case X86::TEST32mr: 
    case X86::XCHG32mr: 
    case X86::XOR32mi: 
    case X86::XOR32mr: printOperand(MI, 4, MVT::i32); break;
    case X86::ADC32mi8: 
    case X86::ADD32mi8: 
    case X86::AND32mi8: 
    case X86::OR32mi8: 
    case X86::ROL32mi: 
    case X86::ROR32mi: 
    case X86::SAR32mi: 
    case X86::SBB32mi8: 
    case X86::SHL32mi: 
    case X86::SHR32mi: 
    case X86::SUB32mi8: 
    case X86::TEST8mi: 
    case X86::XOR32mi8: printOperand(MI, 4, MVT::i8); break;
    }

After this, the generated asmwriters look pretty much as though they were 
generated by hand.  This shrinks the X86 asmwriter.inc files from 55101->39669
and 55429->39551 bytes each, and PPC from 16766->12859 bytes.



---
Diffs of the changes:  (+34 -8)

 AsmWriterEmitter.cpp |   42 ++++++++++++++++++++++++++++++++++--------
 1 files changed, 34 insertions(+), 8 deletions(-)


Index: llvm/utils/TableGen/AsmWriterEmitter.cpp
diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.16 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.17
--- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.16	Sat Jan 22 13:22:23 2005
+++ llvm/utils/TableGen/AsmWriterEmitter.cpp	Sat Jan 22 14:31:17 2005
@@ -55,6 +55,9 @@
         return MIOpNo != Other.MIOpNo || OpVT != Other.OpVT;
       return false;
     }
+    bool operator==(const AsmWriterOperand &Other) const {
+      return !operator!=(Other);
+    }
     void EmitCode(std::ostream &OS) const;
   };
 
@@ -201,6 +204,25 @@
   return MismatchOperand;
 }
 
+static void PrintCases(std::vector<std::pair<std::string,
+                       AsmWriterOperand> > &OpsToPrint, std::ostream &O) {
+  O << "    case " << OpsToPrint.back().first << ": ";
+  AsmWriterOperand TheOp = OpsToPrint.back().second;
+  OpsToPrint.pop_back();
+
+  // Check to see if any other operands are identical in this list, and if so,
+  // emit a case label for them.
+  for (unsigned i = OpsToPrint.size(); i != 0; --i)
+    if (OpsToPrint[i-1].second == TheOp) {
+      O << "\n    case " << OpsToPrint[i-1].first << ": ";
+      OpsToPrint.erase(OpsToPrint.begin()+i-1);
+    }
+
+  // Finally, emit the code.
+  TheOp.EmitCode(O);
+  O << "break;\n";
+}
+
 
 /// EmitInstructions - Emit the last instruction in the vector and any other
 /// instructions that are suitably similar to it.
@@ -242,16 +264,20 @@
       // If this is the operand that varies between all of the instructions,
       // emit a switch for just this operand now.
       O << "    switch (MI->getOpcode()) {\n";
-      O << "    case " << Namespace << "::"
-        << FirstInst.CGI->TheDef->getName() << ": ";
-      FirstInst.Operands[i].EmitCode(O);
-      O << "break;\n";
+      std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint;
+      OpsToPrint.push_back(std::make_pair(Namespace+"::"+
+                                          FirstInst.CGI->TheDef->getName(),
+                                          FirstInst.Operands[i]));
+                                          
       for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) {
-        O << "    case " << Namespace << "::"
-          << SimilarInsts[si].CGI->TheDef->getName() << ": ";
-        SimilarInsts[si].Operands[i].EmitCode(O);
-        O << "break;\n";
+        AsmWriterInst &AWI = SimilarInsts[si];
+        OpsToPrint.push_back(std::make_pair(Namespace+"::"+
+                                            AWI.CGI->TheDef->getName(),
+                                            AWI.Operands[i]));
       }
+      std::reverse(OpsToPrint.begin(), OpsToPrint.end());
+      while (!OpsToPrint.empty())
+        PrintCases(OpsToPrint, O);
       O << "    }";
     }
     O << "\n";






More information about the llvm-commits mailing list