Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" @@ -62,6 +63,7 @@ class AArch64AsmParser : public MCTargetAsmParser { private: StringRef Mnemonic; ///< Instruction mnemonic. + const MCInstrInfo MII; // Map of register aliases registers via the .req directive. StringMap> RegisterReqs; @@ -139,7 +141,7 @@ AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(Options, STI) { + : MCTargetAsmParser(Options, STI), MII(MII) { IsILP32 = Options.getABIName() == "ilp32"; MCAsmParserExtension::Initialize(Parser); MCStreamer &S = getParser().getStreamer(); Index: lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp =================================================================== --- lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCAsmParserExtension.h" @@ -96,7 +97,7 @@ MCAsmParser &Parser; MCAssembler *Assembler; - MCInstrInfo const &MCII; + MCInstrInfo const &MII; MCInst MCB; bool InBrackets; @@ -156,7 +157,7 @@ HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options, _STI), Parser(_Parser), - MCII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) { + MII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) { setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); MCAsmParserExtension::Initialize(_Parser); @@ -461,9 +462,9 @@ // Check the bundle for errors. const MCRegisterInfo *RI = getContext().getRegisterInfo(); - HexagonMCChecker Check(MCII, getSTI(), MCB, MCB, *RI); + HexagonMCChecker Check(MII, getSTI(), MCB, MCB, *RI); - bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, getSTI(), + bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MII, getSTI(), getContext(), MCB, &Check); @@ -686,7 +687,7 @@ MatchingInlineAsm)) return true; HexagonMCInstrInfo::extendIfNeeded( - getParser().getContext(), MCII, MCB, *SubInst); + getParser().getContext(), MII, MCB, *SubInst); MCB.addOperand(MCOperand::createInst(SubInst)); if (!InBrackets) return finishBundle(IDLoc, Out); Index: lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp =================================================================== --- lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp +++ lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp @@ -17,6 +17,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" @@ -36,7 +37,7 @@ #include #include -namespace llvm { +using namespace llvm; // Auto-generated by TableGen static unsigned MatchRegisterName(StringRef Name); @@ -86,7 +87,7 @@ LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options, STI), Parser(Parser), - Lexer(Parser.getLexer()), SubtargetInfo(STI) { + Lexer(Parser.getLexer()), SubtargetInfo(STI), MII(MII) { setAvailableFeatures( ComputeAvailableFeatures(SubtargetInfo.getFeatureBits())); } @@ -96,6 +97,7 @@ MCAsmLexer &Lexer; const MCSubtargetInfo &SubtargetInfo; + const MCInstrInfo MII; }; // LanaiOperand - Instances of this class represented a parsed machine @@ -1225,5 +1227,3 @@ extern "C" void LLVMInitializeLanaiAsmParser() { RegisterMCAsmParser x(getTheLanaiTarget()); } - -} // end namespace llvm Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -23,6 +23,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -144,6 +145,7 @@ unsigned CpSaveLocation; /// If true, then CpSaveLocation is a register, otherwise it's an offset. bool CpSaveLocationIsRegister; + const MCInstrInfo MII; // Print a warning along with its fix-it message at the given range. void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg, @@ -462,7 +464,8 @@ const MCInstrInfo &MII, const MCTargetOptions &Options) : MCTargetAsmParser(Options, sti), ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()), - sti.getCPU(), Options)) { + sti.getCPU(), Options)), + MII(MII) { MCAsmParserExtension::Initialize(parser); parser.addAliasForDirective(".asciiz", ".asciz"); Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp =================================================================== --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -16,6 +16,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -53,6 +54,7 @@ class SparcAsmParser : public MCTargetAsmParser { MCAsmParser &Parser; + const MCInstrInfo MII; /// @name Auto-generated Match Functions /// { @@ -108,7 +110,7 @@ SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(Options, sti), Parser(parser) { + : MCTargetAsmParser(Options, sti), Parser(parser), MII(MII) { // Initialize the set of available features. setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits())); } Index: lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp =================================================================== --- lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -15,6 +15,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCAsmParserExtension.h" @@ -371,6 +372,7 @@ private: MCAsmParser &Parser; + const MCInstrInfo MII; enum RegisterGroup { RegGR, RegFP, @@ -414,7 +416,7 @@ SystemZAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(Options, sti), Parser(parser) { + : MCTargetAsmParser(Options, sti), Parser(parser), MII(MII) { MCAsmParserExtension::Initialize(Parser); // Alias the .word directive to .short. Index: utils/TableGen/AsmMatcherEmitter.cpp =================================================================== --- utils/TableGen/AsmMatcherEmitter.cpp +++ utils/TableGen/AsmMatcherEmitter.cpp @@ -2746,6 +2746,26 @@ OS << "}\n\n"; } +// Emit a function mapping match classes to strings, for debugging. +static void emitMatchClassKindNames(std::forward_list &Infos, + raw_ostream &OS) { + OS << "#ifndef NDEBUG\n"; + OS << "const char *getMatchClassName(MatchClassKind Kind) {\n"; + OS << " switch (Kind) {\n"; + + OS << " case InvalidMatchClass: return \"InvalidMatchClass\";\n"; + OS << " case OptionalMatchClass: return \"OptionalMatchClass\";\n"; + for (const auto &CI : Infos) { + OS << " case " << CI.Name << ": return \"" << CI.Name << "\";\n"; + } + OS << " case NumMatchClassKinds: return \"NumMatchClassKinds\";\n"; + + OS << " }\n"; + OS << " llvm_unreachable(\"unhandled MatchClassKind!\");\n"; + OS << "}\n\n"; + OS << "#endif // NDEBUG\n"; +} + void AsmMatcherEmitter::run(raw_ostream &OS) { CodeGenTarget Target(Records); Record *AsmParser = Target.getAsmParser(); @@ -2910,6 +2930,8 @@ // Emit the routine to validate an operand against a match class. emitValidateOperandClass(Info, OS); + emitMatchClassKindNames(Info.Classes, OS); + // Emit the available features compute function. SubtargetFeatureInfo::emitComputeAvailableFeatures( Info.Target.getName(), ClassName, "ComputeAvailableFeatures", @@ -3018,6 +3040,9 @@ OS << "};\n\n"; } + OS << "#include \"llvm/Support/Debug.h\"\n"; + OS << "#include \"llvm/Support/Format.h\"\n\n"; + // Finally, build the match function. OS << "unsigned " << Target.getName() << ClassName << "::\n" << "MatchInstructionImpl(const OperandVector &Operands,\n"; @@ -3099,6 +3124,10 @@ "std::equal_range(Start, End, Mnemonic.lower(), LessOpcode());\n\n"; } + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"AsmMatcher: found \" <<\n" + << " std::distance(MnemonicRange.first, MnemonicRange.second) << \n" + << " \" encodings with mnemonic '\" << Mnemonic << \"'\\n\");\n\n"; + OS << " // Return a more specific error code if no mnemonics match.\n"; OS << " if (MnemonicRange.first == MnemonicRange.second)\n"; OS << " return Match_MnemonicFail;\n\n"; @@ -3107,6 +3136,9 @@ << "*ie = MnemonicRange.second;\n"; OS << " it != ie; ++it) {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Trying to match opcode \"\n"; + OS << " << MII.getName(it->Opcode) << \"\\n\");\n"; + if (ReportMultipleNearMisses) { OS << " // Some state to record ways in which this instruction did not match.\n"; OS << " NearMissInfo OperandNearMiss = NearMissInfo::getSuccess();\n"; @@ -3132,20 +3164,35 @@ << "; FormalIdx != " << MaxNumOperands << "; ++FormalIdx) {\n"; OS << " auto Formal = " << "static_cast(it->Classes[FormalIdx]);\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\",\n"; + OS << " dbgs() << \" Matching formal operand class \" << getMatchClassName(Formal)\n"; + OS << " << \" against actual operand at index \" << ActualIdx);\n"; + OS << " if (ActualIdx < Operands.size())\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \" (\";\n"; + OS << " Operands[ActualIdx]->print(dbgs()); dbgs() << \"): \");\n"; + OS << " else\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \": \");\n"; OS << " if (ActualIdx >= Operands.size()) {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand index out of range \");\n"; if (ReportMultipleNearMisses) { OS << " bool ThisOperandValid = (Formal == " <<"InvalidMatchClass) || " "isSubclass(Formal, OptionalMatchClass);\n"; OS << " if (!ThisOperandValid) {\n"; OS << " if (!OperandNearMiss) {\n"; OS << " // Record info about match failure for later use.\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"recording too-few-operands near miss\\n\");\n"; OS << " OperandNearMiss =\n"; OS << " NearMissInfo::getTooFewOperands(Formal, it->Opcode);\n"; OS << " } else {\n"; OS << " // If more than one operand is invalid, give up on this match entry.\n"; + OS << " DEBUG_WITH_TYPE(\n"; + OS << " \"asm-matcher\",\n"; + OS << " dbgs() << \"second invalid operand, giving up on this opcode\\n\");\n"; OS << " MultipleInvalidOperands = true;\n"; OS << " break;\n"; OS << " }\n"; + OS << " } else {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"but formal operand not required\\n\");\n"; OS << " }\n"; OS << " continue;\n"; } else { @@ -3161,6 +3208,8 @@ OS << " MCParsedAsmOperand &Actual = *Operands[ActualIdx];\n"; OS << " unsigned Diag = validateOperandClass(Actual, Formal);\n"; OS << " if (Diag == Match_Success) {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\",\n"; + OS << " dbgs() << \"match success using generic matcher\\n\");\n"; OS << " ++ActualIdx;\n"; OS << " continue;\n"; OS << " }\n"; @@ -3169,6 +3218,8 @@ OS << " if (Diag == Match_InvalidOperand) {\n"; OS << " Diag = validateTargetOperandClass(Actual, Formal);\n"; OS << " if (Diag == Match_Success) {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\",\n"; + OS << " dbgs() << \"match success using target matcher\\n\");\n"; OS << " ++ActualIdx;\n"; OS << " continue;\n"; OS << " }\n"; @@ -3180,6 +3231,7 @@ if (HasOptionalOperands) { OS << " OptionalOperandsMask.set(FormalIdx);\n"; } + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"ignoring optional operand\\n\");\n"; OS << " continue;\n"; OS << " }\n"; @@ -3187,11 +3239,19 @@ OS << " if (!OperandNearMiss) {\n"; OS << " // If this is the first invalid operand we have seen, record some\n"; OS << " // information about it.\n"; + OS << " DEBUG_WITH_TYPE(\n"; + OS << " \"asm-matcher\",\n"; + OS << " dbgs()\n"; + OS << " << \"operand match failed, recording near-miss with diag code \"\n"; + OS << " << Diag << \"\\n\");\n"; OS << " OperandNearMiss =\n"; OS << " NearMissInfo::getMissedOperand(Diag, Formal, it->Opcode, ActualIdx);\n"; OS << " ++ActualIdx;\n"; OS << " } else {\n"; OS << " // If more than one operand is invalid, give up on this match entry.\n"; + OS << " DEBUG_WITH_TYPE(\n"; + OS << " \"asm-matcher\",\n"; + OS << " dbgs() << \"second operand mismatch, skipping this opcode\\n\");\n"; OS << " MultipleInvalidOperands = true;\n"; OS << " break;\n"; OS << " }\n"; @@ -3215,9 +3275,14 @@ } if (ReportMultipleNearMisses) - OS << " if (MultipleInvalidOperands) continue;\n\n"; + OS << " if (MultipleInvalidOperands) {\n"; else - OS << " if (!OperandsValid) continue;\n\n"; + OS << " if (!OperandsValid) {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: multiple \"\n"; + OS << " \"operand mismatches, ignoring \"\n"; + OS << " \"this opcode\\n\");\n"; + OS << " continue;\n"; + OS << " }\n"; // Emit check that the required features are available. OS << " if ((AvailableFeatures & it->RequiredFeatures) " @@ -3226,6 +3291,9 @@ OS << " HadMatchOtherThanFeatures = true;\n"; OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & " "~AvailableFeatures;\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Missing target features: \"\n"; + OS << " << format_hex(NewMissingFeatures, 18)\n"; + OS << " << \"\\n\");\n"; if (ReportMultipleNearMisses) { OS << " FeaturesNearMiss = NearMissInfo::getMissedFeature(NewMissingFeatures);\n"; } else { @@ -3250,6 +3318,10 @@ << " if ((MatchResult = checkEarlyTargetMatchPredicate(Inst, " "Operands)) != Match_Success) {\n" << " Inst.clear();\n"; + OS << " DEBUG_WITH_TYPE(\n"; + OS << " \"asm-matcher\",\n"; + OS << " dbgs() << \"Early target match predicate failed with diag code \"\n"; + OS << " << MatchResult << \"\\n\");\n"; if (ReportMultipleNearMisses) { OS << " EarlyPredicateNearMiss = NearMissInfo::getMissedPredicate(MatchResult);\n"; } else { @@ -3265,7 +3337,15 @@ OS << " if (OperandNearMiss) {\n"; OS << " // If the operand mismatch was the only problem, reprrt it as a near-miss.\n"; OS << " if (NearMisses && !FeaturesNearMiss && !EarlyPredicateNearMiss) {\n"; + OS << " DEBUG_WITH_TYPE(\n"; + OS << " \"asm-matcher\",\n"; + OS << " dbgs()\n"; + OS << " << \"Opcode result: one mismatched operand, adding near-miss\\n\");\n"; OS << " NearMisses->push_back(OperandNearMiss);\n"; + OS << " } else {\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: multiple \"\n"; + OS << " \"types of mismatch, so not \"\n"; + OS << " \"reporting near-miss\\n\");\n"; OS << " }\n"; OS << " continue;\n"; OS << " }\n\n"; @@ -3290,6 +3370,9 @@ << " // handle any context sensitive constraints.\n" << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" << " Match_Success) {\n" + << " DEBUG_WITH_TYPE(\"asm-matcher\",\n" + << " dbgs() << \"Target match predicate failed with diag code \"\n" + << " << MatchResult << \"\\n\");\n" << " Inst.clear();\n"; if (ReportMultipleNearMisses) { OS << " LatePredicateNearMiss = NearMissInfo::getMissedPredicate(MatchResult);\n"; @@ -3308,6 +3391,9 @@ OS << " if (NumNearMisses == 1) {\n"; OS << " // We had exactly one type of near-miss, so add that to the list.\n"; OS << " assert(!OperandNearMiss && \"OperandNearMiss was handled earlier\");\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: found one type of \"\n"; + OS << " \"mismatch, so reporting a \"\n"; + OS << " \"near-miss\\n\");\n"; OS << " if (NearMisses && FeaturesNearMiss)\n"; OS << " NearMisses->push_back(FeaturesNearMiss);\n"; OS << " else if (NearMisses && EarlyPredicateNearMiss)\n"; @@ -3318,6 +3404,9 @@ OS << " continue;\n"; OS << " } else if (NumNearMisses > 1) {\n"; OS << " // This instruction missed in more than one way, so ignore it.\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"Opcode result: multiple \"\n"; + OS << " \"types of mismatch, so not \"\n"; + OS << " \"reporting near-miss\\n\");\n"; OS << " continue;\n"; OS << " }\n"; } @@ -3339,6 +3428,9 @@ OS << " }\n"; } + OS << " DEBUG_WITH_TYPE(\n"; + OS << " \"asm-matcher\",\n"; + OS << " dbgs() << \"Opcode result: complete match, selecting this opcode\\n\");\n"; OS << " return Match_Success;\n"; OS << " }\n\n";