aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-01-22 20:31:17 +0000
committerChris Lattner <sabre@nondot.org>2005-01-22 20:31:17 +0000
commit38c0751a128c0387c04c0f96a2f092340aaa7545 (patch)
tree6fa20f928e96fc51d08626b518022d9cae28591e
parentf876668518097413a904537ce9d249953987508c (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19760 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp42
1 files changed, 34 insertions, 8 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 327776b329..6fb322e2f2 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -55,6 +55,9 @@ namespace {
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 @@ unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
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 @@ static void EmitInstructions(std::vector<AsmWriterInst> &Insts,
// 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";