From f719c540bb09cb5bfe37bc6283ea68e31949b3f4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 11 Jan 2020 16:27:25 -0800 Subject: [PATCH] [X86][Disassembler] Shrink X86GenDisassemblerTables.inc from 36M to 6.1M In x86Disassembler{OneByte,TwoByte,...}Codes, "/* EmptyTable */" is very common. Omitting it saves lots of space. Also, there is no need to display a table entry in multiple lines. It is also common that the whole OpcodeDecision is { MODRM_ONEENTRY, 0}. Make use of zero-initialization. --- llvm/utils/TableGen/X86DisassemblerTables.cpp | 84 +++++++++---------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/llvm/utils/TableGen/X86DisassemblerTables.cpp b/llvm/utils/TableGen/X86DisassemblerTables.cpp index 14bce4c29446..5dc653ac3806 100644 --- a/llvm/utils/TableGen/X86DisassemblerTables.cpp +++ b/llvm/utils/TableGen/X86DisassemblerTables.cpp @@ -667,16 +667,9 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, static uint32_t sEntryNumber = 1; ModRMDecisionType dt = getDecisionType(decision); - if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) - { - o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; - i2++; - - o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; - o2.indent(i2) << 0 << " /* EmptyTable */\n"; - - i2--; - o2.indent(i2) << "}"; + if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) { + // Empty table. + o2 << "{ " << stringForDecisionType(dt) << ", 0 }"; return; } @@ -725,14 +718,8 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, i1--; } - o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; - i2++; - - o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; - o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n"; - - i2--; - o2.indent(i2) << "}"; + o2 << "{ " << stringForDecisionType(dt) << ", " << EntryNumber << " /* Table" + << EntryNumber << " */ }"; switch (dt) { default: @@ -764,30 +751,43 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, - OpcodeDecision &decision) const { - o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; - i2++; - o2.indent(i2) << "{" << "\n"; - i2++; + OpcodeDecision &opDecision) const { + o2 << "{"; + ++i2; - for (unsigned index = 0; index < 256; ++index) { - o2.indent(i2); - - o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; - - emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, - decision.modRMDecisions[index]); - - if (index < 255) - o2 << ","; - - o2 << "\n"; + unsigned index; + for (index = 0; index < 256; ++index) { + auto &decision = opDecision.modRMDecisions[index]; + ModRMDecisionType dt = getDecisionType(decision); + if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)) + break; } + if (index == 256) { + // If all 256 entries are MODRM_ONEENTRY, omit output. + assert(MODRM_ONEENTRY == 0); + --i2; + o2 << "},\n"; + } else { + o2 << " /* struct OpcodeDecision */ {\n"; + ++i2; + for (index = 0; index < 256; ++index) { + o2.indent(i2); - i2--; - o2.indent(i2) << "}" << "\n"; - i2--; - o2.indent(i2) << "}" << "\n"; + o2 << "/* 0x" << format("%02hhx", index) << " */ "; + + emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, + opDecision.modRMDecisions[index]); + + if (index < 255) + o2 << ","; + + o2 << "\n"; + } + --i2; + o2.indent(i2) << "}\n"; + --i2; + o2.indent(i2) << "},\n"; + } } void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, @@ -803,14 +803,10 @@ void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, for (unsigned index = 0; index < IC_max; ++index) { o2.indent(i2) << "/* "; o2 << stringForContext((InstructionContext)index); - o2 << " */"; - o2 << "\n"; + o2 << " */ "; emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, decision.opcodeDecisions[index]); - - if (index + 1 < IC_max) - o2 << ", "; } i2--;