From: Craig Topper Date: Wed, 24 Jul 2013 07:33:14 +0000 (+0000) Subject: Split generated asm mnemonic matching table into a separate table for each asm variant. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f63ef914b67593e4b20a0b85e889380c20b41f55;p=oota-llvm.git Split generated asm mnemonic matching table into a separate table for each asm variant. This removes the need to store the asm variant in each row of the single table that existed before. Shaves ~16K off the size of X86AsmParser.o. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187026 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 6e878df3cb1..ebcbd5b30cd 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -143,7 +143,7 @@ public: /// mnemonicIsValid - This returns true if this is a valid mnemonic and false /// otherwise. - virtual bool mnemonicIsValid(StringRef Mnemonic) = 0; + virtual bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) = 0; /// MatchAndEmitInstruction - Recognize a series of operands of a parsed /// instruction as an actual MCInst and emit it to the specified MCStreamer. diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp index dda6e247ac4..2e9b3101d02 100644 --- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp +++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/MBlazeBaseInfo.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCExpr.h" diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 3e9b950494c..12ab2cae373 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -1501,7 +1501,7 @@ bool MipsAsmParser:: ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, SmallVectorImpl &Operands) { // Check if we have valid mnemonic - if (!mnemonicIsValid(Name)) { + if (!mnemonicIsValid(Name, 0)) { Parser.eatToEndOfStatement(); return Error(NameLoc, "Unknown instruction"); } diff --git a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index 3c677cc0a87..d75cb9552d4 100644 --- a/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" diff --git a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 25df0ecc3ea..58af2c4920f 100644 --- a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/SystemZMCTargetDesc.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 263eb5ed9c4..59e4dbde59b 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -9,6 +9,7 @@ #include "MCTargetDesc/X86BaseInfo.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 101d8b822f6..a7ae41ef0c1 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -2658,7 +2658,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << "&Operands);\n"; OS << " void convertToMapAndConstraints(unsigned Kind,\n "; OS << " const SmallVectorImpl &Operands);\n"; - OS << " bool mnemonicIsValid(StringRef Mnemonic);\n"; + OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n"; OS << " unsigned MatchInstructionImpl(\n"; OS.indent(27); OS << "const SmallVectorImpl &Operands,\n" @@ -2780,7 +2780,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange(Info.Classes.size()) << " Classes[" << MaxNumOperands << "];\n"; - OS << " uint8_t AsmVariantID;\n\n"; OS << " StringRef getMnemonic() const {\n"; OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; OS << " MnemonicTable[Mnemonic]);\n"; @@ -2802,51 +2801,73 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "} // end anonymous namespace.\n\n"; - OS << "static const MatchEntry MatchTable[" - << Info.Matchables.size() << "] = {\n"; + unsigned VariantCount = Target.getAsmParserVariantCount(); + for (unsigned VC = 0; VC != VariantCount; ++VC) { + Record *AsmVariant = Target.getAsmParserVariant(VC); + std::string CommentDelimiter = + AsmVariant->getValueAsString("CommentDelimiter"); + std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); + int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); - for (std::vector::const_iterator it = - Info.Matchables.begin(), ie = Info.Matchables.end(); - it != ie; ++it) { - MatchableInfo &II = **it; + OS << "static const MatchEntry MatchTable" << VC << "[] = {\n"; - // 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 << " */, " - << Target.getName() << "::" - << II.getResultInst()->TheDef->getName() << ", " - << II.ConversionFnKind << ", "; + for (std::vector::const_iterator it = + Info.Matchables.begin(), ie = Info.Matchables.end(); + it != ie; ++it) { + MatchableInfo &II = **it; + if (II.AsmVariantID != AsmVariantNo) + continue; - // 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 << " */, " + << Target.getName() << "::" + << II.getResultInst()->TheDef->getName() << ", " + << II.ConversionFnKind << ", "; + + // 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 << ", { "; - for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { - MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; + OS << ", { "; + for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { + MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; - if (i) OS << ", "; - OS << Op.Class->Name; + if (i) OS << ", "; + OS << Op.Class->Name; + } + OS << " }, },\n"; } - OS << " }, " << II.AsmVariantID; - OS << "},\n"; - } - OS << "};\n\n"; + OS << "};\n\n"; + } // A method to determine if a mnemonic is in the list. OS << "bool " << Target.getName() << ClassName << "::\n" - << "mnemonicIsValid(StringRef Mnemonic) {\n"; + << "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n"; + OS << " // Find the appropriate table for this asm variant.\n"; + OS << " const MatchEntry *Start, *End;\n"; + OS << " switch (VariantID) {\n"; + OS << " default: // unreachable\n"; + for (unsigned VC = 0; VC != VariantCount; ++VC) { + Record *AsmVariant = Target.getAsmParserVariant(VC); + std::string CommentDelimiter = + AsmVariant->getValueAsString("CommentDelimiter"); + std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); + int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); + OS << " case " << AsmVariantNo << ": Start = MatchTable" << VC + << "; End = array_endof(MatchTable" << VC << "); break;\n"; + } + OS << " }\n"; OS << " // Search the table.\n"; OS << " std::pair MnemonicRange =\n"; - OS << " std::equal_range(MatchTable, MatchTable+" - << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n"; + OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n"; OS << " return MnemonicRange.first != MnemonicRange.second;\n"; OS << "}\n\n"; @@ -2888,10 +2909,23 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " ErrorInfo = ~0U;\n"; // Emit code to search the table. + OS << " // Find the appropriate table for this asm variant.\n"; + OS << " const MatchEntry *Start, *End;\n"; + OS << " switch (VariantID) {\n"; + OS << " default: // unreachable\n"; + for (unsigned VC = 0; VC != VariantCount; ++VC) { + Record *AsmVariant = Target.getAsmParserVariant(VC); + std::string CommentDelimiter = + AsmVariant->getValueAsString("CommentDelimiter"); + std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); + int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); + OS << " case " << AsmVariantNo << ": Start = MatchTable" << VC + << "; End = array_endof(MatchTable" << VC << "); break;\n"; + } + OS << " }\n"; OS << " // Search the table.\n"; OS << " std::pair MnemonicRange =\n"; - OS << " std::equal_range(MatchTable, MatchTable+" - << Info.Matchables.size() << ", Mnemonic, LessOpcode());\n\n"; + OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n"; OS << " // Return a more specific error code if no mnemonics match.\n"; OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; @@ -2905,7 +2939,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " assert(Mnemonic == it->getMnemonic());\n"; // Emit check that the subclasses match. - OS << " if (VariantID != it->AsmVariantID) continue;\n"; OS << " bool OperandsValid = true;\n"; OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n"; OS << " if (i + 1 >= Operands.size()) {\n";