From 3a3644436695d835bb4e1e2a0c7f3cc82a2807c2 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 18 Sep 2012 07:02:21 +0000 Subject: [PATCH] Make custom operand parsing mnemonic indices use the same mnemonic table as the match table. Reorder fields in OperandMatchEntry to provide the least amount of padding for in tree targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164109 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 73 +++++++++++++++------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 338a0b2fd24..89cc1380c3a 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -2379,17 +2379,27 @@ static const char *getMinimalTypeForRange(uint64_t Range) { } static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, - const AsmMatcherInfo &Info, StringRef ClassName) { + const AsmMatcherInfo &Info, StringRef ClassName, + StringToOffsetTable &StringTable, + unsigned MaxMnemonicIndex) { + unsigned MaxMask = 0; + for (std::vector::const_iterator it = + Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); + it != ie; ++it) { + MaxMask |= it->OperandMask; + } + // Emit the static custom operand parsing table; OS << "namespace {\n"; OS << " struct OperandMatchEntry {\n"; - OS << " static const char *const MnemonicTable;\n"; - OS << " uint32_t OperandMask;\n"; - OS << " uint32_t Mnemonic;\n"; OS << " " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size()) << " RequiredFeatures;\n"; + OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) + << " Mnemonic;\n"; OS << " " << getMinimalTypeForRange(Info.Classes.size()) - << " Class;\n\n"; + << " Class;\n"; + OS << " " << getMinimalTypeForRange(MaxMask) + << " OperandMask;\n\n"; OS << " StringRef getMnemonic() const {\n"; OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; OS << " MnemonicTable[Mnemonic]);\n"; @@ -2412,8 +2422,6 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, OS << "} // end anonymous namespace.\n\n"; - StringToOffsetTable StringTable; - OS << "static const OperandMatchEntry OperandMatchTable[" << Info.OperandMatchInfo.size() << "] = {\n"; @@ -2424,8 +2432,25 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, const OperandMatchEntry &OMI = *it; const MatchableInfo &II = *OMI.MI; - OS << " { " << OMI.OperandMask; + OS << " { "; + + // Write the required features mask. + if (!II.RequiredFeatures.empty()) { + for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { + if (i) OS << "|"; + OS << II.RequiredFeatures[i]->getEnumName(); + } + } else + OS << "0"; + + // Store a pascal-style length byte in the mnemonic. + std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); + OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false) + << " /* " << II.Mnemonic << " */, "; + + OS << OMI.CI->Name; + OS << ", " << OMI.OperandMask; OS << " /* "; bool printComma = false; for (int i = 0, e = 31; i !=e; ++i) @@ -2437,30 +2462,10 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, } OS << " */"; - // Store a pascal-style length byte in the mnemonic. - std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); - OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false) - << " /* " << II.Mnemonic << " */, "; - - // Write the required features mask. - if (!II.RequiredFeatures.empty()) { - for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { - if (i) OS << "|"; - OS << II.RequiredFeatures[i]->getEnumName(); - } - } else - OS << "0"; - - OS << ", " << OMI.CI->Name; - OS << " },\n"; } OS << "};\n\n"; - OS << "const char *const OperandMatchEntry::MnemonicTable =\n"; - StringTable.EmitString(OS); - OS << ";\n\n"; - // Emit the operand class switch to call the correct custom parser for // the found operand class. OS << Target.getName() << ClassName << "::OperandMatchResultTy " @@ -2697,6 +2702,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { StringTable.GetOrAddStringOffset(LenMnemonic, false)); } + OS << "static const char *const MnemonicTable =\n"; + StringTable.EmitString(OS); + OS << ";\n\n"; + // Emit the static match table; unused classes get initalized to 0 which is // guaranteed to be InvalidMatchClass. // @@ -2709,7 +2718,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // following the mnemonic. OS << "namespace {\n"; OS << " struct MatchEntry {\n"; - OS << " static const char *const MnemonicTable;\n"; OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) << " Mnemonic;\n"; OS << " uint16_t Opcode;\n"; @@ -2779,10 +2787,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "};\n\n"; - OS << "const char *const MatchEntry::MnemonicTable =\n"; - StringTable.EmitString(OS); - OS << ";\n\n"; - // A method to determine if a mnemonic is in the list. OS << "bool " << Target.getName() << ClassName << "::\n" << "MnemonicIsValid(StringRef Mnemonic) {\n"; @@ -2929,7 +2933,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "}\n\n"; if (Info.OperandMatchInfo.size()) - emitCustomOperandParsing(OS, Target, Info, ClassName); + emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable, + MaxMnemonicIndex); OS << "#endif // GET_MATCHER_IMPLEMENTATION\n\n"; } -- 2.34.1