X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=utils%2FTableGen%2FAsmMatcherEmitter.cpp;h=3c73dcbdfeee84f1945e8a78153f05d1835d9e95;hp=5af7051e03fd18d14c43f005d77806183db5a7dd;hb=1159059a9126ddf7bc0b4caed475c1734899c054;hpb=503438e3f6d33d1d3dae69f6de202439a7145848 diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 5af7051e03f..3c73dcbdfee 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -296,9 +296,11 @@ public: class AsmVariantInfo { public: + std::string RegisterPrefix; std::string TokenizingCharacters; std::string SeparatorCharacters; std::string BreakCharacters; + int AsmVariantNo; }; /// MatchableInfo - Helper class for storing the necessary information for an @@ -491,7 +493,6 @@ struct MatchableInfo { void initialize(const AsmMatcherInfo &Info, SmallPtrSetImpl &SingletonRegisters, - int AsmVariantNo, StringRef RegisterPrefix, AsmVariantInfo const &Variant); /// validate - Return true if this matchable is a valid thing to match against @@ -594,8 +595,7 @@ struct MatchableInfo { private: void tokenizeAsmString(AsmMatcherInfo const &Info, AsmVariantInfo const &Variant); - void addAsmOperand(size_t Start, size_t End, - std::string const &SeparatorCharacters); + void addAsmOperand(StringRef Token, bool IsIsolatedToken = false); }; /// SubtargetFeatureInfo - Helper class for storing information on a subtarget @@ -774,8 +774,7 @@ void MatchableInfo::formTwoOperandAlias(StringRef Constraint) { // Find the ResOperand that refers to the operand we're aliasing away // and update it to refer to the combined operand instead. - for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) { - ResOperand &Op = ResOperands[i]; + for (ResOperand &Op : ResOperands) { if (Op.Kind == ResOperand::RenderAsmOperand && Op.AsmOperandNum == (unsigned)SrcAsmOperand) { Op.AsmOperandNum = DstAsmOperand; @@ -786,8 +785,7 @@ void MatchableInfo::formTwoOperandAlias(StringRef Constraint) { AsmOperands.erase(AsmOperands.begin() + SrcAsmOperand); // Adjust the ResOperand references to any AsmOperands that followed // the one we just deleted. - for (unsigned i = 0, e = ResOperands.size(); i != e; ++i) { - ResOperand &Op = ResOperands[i]; + for (ResOperand &Op : ResOperands) { switch(Op.Kind) { default: // Nothing to do for operands that don't reference AsmOperands. @@ -838,11 +836,11 @@ extractSingletonRegisterForAsmOperand(MatchableInfo::AsmOperand &Op, void MatchableInfo::initialize(const AsmMatcherInfo &Info, SmallPtrSetImpl &SingletonRegisters, - int AsmVariantNo, StringRef RegisterPrefix, AsmVariantInfo const &Variant) { - AsmVariantID = AsmVariantNo; + AsmVariantID = Variant.AsmVariantNo; AsmString = - CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo); + CodeGenInstruction::FlattenAsmStringVariants(AsmString, + Variant.AsmVariantNo); tokenizeAsmString(Info, Variant); @@ -854,7 +852,7 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, // Collect singleton registers, if used. for (MatchableInfo::AsmOperand &Op : AsmOperands) { - extractSingletonRegisterForAsmOperand(Op, Info, RegisterPrefix); + extractSingletonRegisterForAsmOperand(Op, Info, Variant.RegisterPrefix); if (Record *Reg = Op.SingletonReg) SingletonRegisters.insert(Reg); } @@ -868,68 +866,68 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, } /// Append an AsmOperand for the given substring of AsmString. -void MatchableInfo::addAsmOperand(size_t Start, size_t End, - std::string const &Separators) { - StringRef String = AsmString; - // Look for separators before and after to figure out is this token is - // isolated. Accept '$$' as that's how we escape '$'. - bool IsIsolatedToken = - (!Start || Separators.find(String[Start - 1]) != StringRef::npos || - String.substr(Start - 1, 2) == "$$") && - (End >= String.size() || Separators.find(String[End]) != StringRef::npos); - AsmOperands.push_back(AsmOperand(IsIsolatedToken, String.slice(Start, End))); +void MatchableInfo::addAsmOperand(StringRef Token, bool IsIsolatedToken) { + AsmOperands.push_back(AsmOperand(IsIsolatedToken, Token)); } /// tokenizeAsmString - Tokenize a simplified assembly string. void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info, AsmVariantInfo const &Variant) { StringRef String = AsmString; - unsigned Prev = 0; + size_t Prev = 0; bool InTok = false; - std::string Separators = Variant.TokenizingCharacters + - Variant.SeparatorCharacters; - for (unsigned i = 0, e = String.size(); i != e; ++i) { - if(Variant.BreakCharacters.find(String[i]) != std::string::npos) { - if(InTok) { - addAsmOperand(Prev, i, Separators); + bool IsIsolatedToken = true; + for (size_t i = 0, e = String.size(); i != e; ++i) { + char Char = String[i]; + if (Variant.BreakCharacters.find(Char) != std::string::npos) { + if (InTok) { + addAsmOperand(String.slice(Prev, i), false); Prev = i; + IsIsolatedToken = false; } InTok = true; continue; } - if(Variant.TokenizingCharacters.find(String[i]) != std::string::npos) { - if(InTok) { - addAsmOperand(Prev, i, Separators); + if (Variant.TokenizingCharacters.find(Char) != std::string::npos) { + if (InTok) { + addAsmOperand(String.slice(Prev, i), IsIsolatedToken); InTok = false; + IsIsolatedToken = false; } - addAsmOperand(i, i + 1, Separators); + addAsmOperand(String.slice(i, i + 1), IsIsolatedToken); Prev = i + 1; + IsIsolatedToken = true; continue; } - if(Variant.SeparatorCharacters.find(String[i]) != std::string::npos) { - if(InTok) { - addAsmOperand(Prev, i, Separators); + if (Variant.SeparatorCharacters.find(Char) != std::string::npos) { + if (InTok) { + addAsmOperand(String.slice(Prev, i), IsIsolatedToken); InTok = false; } Prev = i + 1; + IsIsolatedToken = true; continue; } - switch (String[i]) { + + switch (Char) { case '\\': if (InTok) { - addAsmOperand(Prev, i, Separators); + addAsmOperand(String.slice(Prev, i), false); InTok = false; + IsIsolatedToken = false; } ++i; assert(i != String.size() && "Invalid quoted character"); - addAsmOperand(i, i + 1, Separators); + addAsmOperand(String.slice(i, i + 1), IsIsolatedToken); Prev = i + 1; + IsIsolatedToken = false; break; case '$': { - if (InTok && Prev != i) { - addAsmOperand(Prev, i, Separators); + if (InTok) { + addAsmOperand(String.slice(Prev, i), false); InTok = false; + IsIsolatedToken = false; } // If this isn't "${", start new identifier looking like "$xxx" @@ -938,20 +936,23 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info, break; } - StringRef::iterator End = std::find(String.begin() + i, String.end(),'}'); - assert(End != String.end() && "Missing brace in operand reference!"); - size_t EndPos = End - String.begin(); - addAsmOperand(i, EndPos+1, Separators); + size_t EndPos = String.find('}', i); + assert(EndPos != StringRef::npos && + "Missing brace in operand reference!"); + addAsmOperand(String.slice(i, EndPos+1), IsIsolatedToken); Prev = EndPos + 1; i = EndPos; + IsIsolatedToken = false; break; } + default: InTok = true; + break; } } if (InTok && Prev != String.size()) - addAsmOperand(Prev, StringRef::npos, Separators); + addAsmOperand(String.substr(Prev), IsIsolatedToken); // The first token of the instruction is the mnemonic, which must be a // simple string, not a $foo variable or a singleton register. @@ -990,8 +991,8 @@ bool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const { // Also, check for instructions which reference the operand multiple times; // this implies a constraint we would not honor. std::set OperandNames; - for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { - StringRef Tok = AsmOperands[i].Token; + for (const AsmOperand &Op : AsmOperands) { + StringRef Tok = Op.Token; if (Tok[0] == '$' && Tok.find(':') != StringRef::npos) PrintFatalError(TheDef->getLoc(), "matchable with operand modifier '" + Tok + @@ -1376,15 +1377,15 @@ void AsmMatcherInfo::buildInfo() { Record *AsmVariant = Target.getAsmParserVariant(VC); std::string CommentDelimiter = AsmVariant->getValueAsString("CommentDelimiter"); - std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); AsmVariantInfo Variant; + Variant.RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); Variant.TokenizingCharacters = AsmVariant->getValueAsString("TokenizingCharacters"); Variant.SeparatorCharacters = AsmVariant->getValueAsString("SeparatorCharacters"); Variant.BreakCharacters = AsmVariant->getValueAsString("BreakCharacters"); - int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); + Variant.AsmVariantNo = AsmVariant->getValueAsInt("Variant"); for (const CodeGenInstruction *CGI : Target.instructions()) { @@ -1399,8 +1400,7 @@ void AsmMatcherInfo::buildInfo() { auto II = llvm::make_unique(*CGI); - II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix, - Variant); + II->initialize(*this, SingletonRegisters, Variant); // Ignore instructions which shouldn't be matched and diagnose invalid // instruction definitions with an error. @@ -1416,7 +1416,8 @@ void AsmMatcherInfo::buildInfo() { Records.getAllDerivedDefinitions("InstAlias"); for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { auto Alias = llvm::make_unique(AllInstAliases[i], - AsmVariantNo, Target); + Variant.AsmVariantNo, + Target); // If the tblgen -match-prefix option is specified (for tblgen hackers), // filter the set of instruction aliases we consider, based on the target @@ -1427,8 +1428,7 @@ void AsmMatcherInfo::buildInfo() { auto II = llvm::make_unique(std::move(Alias)); - II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix, - Variant); + II->initialize(*this, SingletonRegisters, Variant); // Validate the alias definitions. II->validate(CommentDelimiter, false); @@ -1455,7 +1455,7 @@ void AsmMatcherInfo::buildInfo() { StringRef Token = Op.Token; // Check for singleton registers. - if (Record *RegRecord = II->AsmOperands[i].SingletonReg) { + if (Record *RegRecord = Op.SingletonReg) { Op.Class = RegisterClasses[RegRecord]; assert(Op.Class && Op.Class->Registers.size() == 1 && "Unexpected class for singleton register"); @@ -1515,8 +1515,7 @@ void AsmMatcherInfo::buildInfo() { // information. std::vector AllTokenAliases = Records.getAllDerivedDefinitions("TokenAlias"); - for (unsigned i = 0, e = AllTokenAliases.size(); i != e; ++i) { - Record *Rec = AllTokenAliases[i]; + for (Record *Rec : AllTokenAliases) { ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken")); ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken")); if (FromClass == ToClass) @@ -1624,9 +1623,7 @@ void MatchableInfo::buildInstructionResultOperands() { // Loop over all operands of the result instruction, determining how to // populate them. - for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) { - const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i]; - + for (const CGIOperandList::OperandInfo &OpInfo : ResultInst->Operands) { // If this is a tied operand, just copy from the previously handled operand. int TiedOp = -1; if (OpInfo.MINumOperands == 1) @@ -1722,7 +1719,7 @@ void MatchableInfo::buildAliasResultOperands() { } static unsigned getConverterOperandID(const std::string &Name, - SetVector &Table, + SmallSetVector &Table, bool &IsNew) { IsNew = Table.insert(Name); @@ -1738,8 +1735,8 @@ static unsigned getConverterOperandID(const std::string &Name, static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, std::vector> &Infos, raw_ostream &OS) { - SetVector OperandConversionKinds; - SetVector InstructionConversionKinds; + SmallSetVector OperandConversionKinds; + SmallSetVector InstructionConversionKinds; std::vector > ConversionTable; size_t MaxRowLength = 2; // minimum is custom converter plus terminator. @@ -2124,12 +2121,7 @@ static void emitIsSubclass(CodeGenTarget &Target, OS << " if (A == B)\n"; OS << " return true;\n\n"; - std::string OStr; - raw_string_ostream SS(OStr); - unsigned Count = 0; - SS << " switch (A) {\n"; - SS << " default:\n"; - SS << " return false;\n"; + bool EmittedSwitch = false; for (const auto &A : Infos) { std::vector SuperClasses; for (const auto &B : Infos) { @@ -2139,33 +2131,38 @@ static void emitIsSubclass(CodeGenTarget &Target, if (SuperClasses.empty()) continue; - ++Count; - SS << "\n case " << A.Name << ":\n"; + // If this is the first SuperClass, emit the switch header. + if (!EmittedSwitch) { + OS << " switch (A) {\n"; + OS << " default:\n"; + OS << " return false;\n"; + EmittedSwitch = true; + } + + OS << "\n case " << A.Name << ":\n"; if (SuperClasses.size() == 1) { - SS << " return B == " << SuperClasses.back().str() << ";\n"; + OS << " return B == " << SuperClasses.back() << ";\n"; continue; } if (!SuperClasses.empty()) { - SS << " switch (B) {\n"; - SS << " default: return false;\n"; - for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) - SS << " case " << SuperClasses[i].str() << ": return true;\n"; - SS << " }\n"; + OS << " switch (B) {\n"; + OS << " default: return false;\n"; + for (StringRef SC : SuperClasses) + OS << " case " << SC << ": return true;\n"; + OS << " }\n"; } else { // No case statement to emit - SS << " return false;\n"; + OS << " return false;\n"; } } - SS << " }\n"; + OS << " }\n"; - // If there were case statements emitted into the string stream, write them - // to the output stream, otherwise write the default. - if (Count) - OS << SS.str(); - else + // If there were case statements emitted into the string stream write the + // default. + if (!EmittedSwitch) OS << " return false;\n"; OS << "}\n\n"; @@ -2477,10 +2474,8 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, 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; + for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) { + MaxMask |= OMI.OperandMask; } // Emit the static custom operand parsing table; @@ -2520,10 +2515,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, << Info.OperandMatchInfo.size() << "] = {\n"; OS << " /* Operand List Mask, Mnemonic, Operand Class, Features */\n"; - for (std::vector::const_iterator it = - Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end(); - it != ie; ++it) { - const OperandMatchEntry &OMI = *it; + for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) { const MatchableInfo &II = *OMI.MI; OS << " { "; @@ -2705,7 +2697,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << "&Operands);\n"; OS << " void convertToMapAndConstraints(unsigned Kind,\n "; OS << " const OperandVector &Operands) override;\n"; - OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n"; + OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n"; OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n" << " MCInst &Inst,\n" << " uint64_t &ErrorInfo," @@ -2957,7 +2949,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { } OS << " }\n"; OS << " // Search the table.\n"; - OS << " std::pair" + OS << " std::pair " "MnemonicRange(Start, End);\n"; OS << " unsigned SIndex = Mnemonic.empty() ? 0 : 1;\n"; OS << " if (!Mnemonic.empty())\n"; @@ -3052,7 +3044,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { if (HasDeprecation) { OS << " std::string Info;\n"; - OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, STI, Info)) {\n"; + OS << " if (MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, getSTI(), Info)) {\n"; OS << " SMLoc Loc = ((" << Target.getName() << "Operand&)*Operands[0]).getStartLoc();\n"; OS << " getParser().Warning(Loc, Info, None);\n";