X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FAsmMatcherEmitter.cpp;h=3964330a4a84ab793007a8759cf54dd054e0d202;hb=47f0e3f434e2e43f951c3a826c40906cb15b7285;hp=b4fc78f0f8fc3e6ce72aa1d1f8003fec04ee9ce0;hpb=a5106ca54d0dc01437533e38ae23b7370c85b6c0;p=oota-llvm.git diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index b4fc78f0f8f..3964330a4a8 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -460,6 +460,20 @@ struct MatchableInfo { TheDef->getValueAsBit("UseInstAsmMatchConverter")) { } + // Could remove this and the dtor if PointerUnion supported unique_ptr + // elements with a dynamic failure/assertion (like the one below) in the case + // where it was copied while being in an owning state. + MatchableInfo(const MatchableInfo &RHS) + : AsmVariantID(RHS.AsmVariantID), AsmString(RHS.AsmString), + TheDef(RHS.TheDef), DefRec(RHS.DefRec), ResOperands(RHS.ResOperands), + Mnemonic(RHS.Mnemonic), AsmOperands(RHS.AsmOperands), + RequiredFeatures(RHS.RequiredFeatures), + ConversionFnKind(RHS.ConversionFnKind), + HasDeprecation(RHS.HasDeprecation), + UseInstAsmMatchConverter(RHS.UseInstAsmMatchConverter) { + assert(!DefRec.is()); + } + ~MatchableInfo() { delete DefRec.dyn_cast(); } @@ -470,18 +484,12 @@ struct MatchableInfo { void initialize(const AsmMatcherInfo &Info, SmallPtrSetImpl &SingletonRegisters, - int AsmVariantNo, std::string &RegisterPrefix); + int AsmVariantNo, StringRef RegisterPrefix); /// validate - Return true if this matchable is a valid thing to match against /// and perform a bunch of validity checking. bool validate(StringRef CommentDelimiter, bool Hack) const; - /// extractSingletonRegisterForAsmOperand - Extract singleton register, - /// if present, from specified token. - void - extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info, - std::string &RegisterPrefix); - /// findAsmOperand - Find the AsmOperand with the specified name and /// suboperand index. int findAsmOperand(StringRef N, int SubOpIdx) const { @@ -786,9 +794,41 @@ void MatchableInfo::formTwoOperandAlias(StringRef Constraint) { } } +/// extractSingletonRegisterForAsmOperand - Extract singleton register, +/// if present, from specified token. +static void +extractSingletonRegisterForAsmOperand(MatchableInfo::AsmOperand &Op, + const AsmMatcherInfo &Info, + StringRef RegisterPrefix) { + StringRef Tok = Op.Token; + + // If this token is not an isolated token, i.e., it isn't separated from + // other tokens (e.g. with whitespace), don't interpret it as a register name. + if (!Op.IsIsolatedToken) + return; + + if (RegisterPrefix.empty()) { + std::string LoweredTok = Tok.lower(); + if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok)) + Op.SingletonReg = Reg->TheDef; + return; + } + + if (!Tok.startswith(RegisterPrefix)) + return; + + StringRef RegName = Tok.substr(RegisterPrefix.size()); + if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) + Op.SingletonReg = Reg->TheDef; + + // If there is no register prefix (i.e. "%" in "%eax"), then this may + // be some random non-register token, just ignore it. + return; +} + void MatchableInfo::initialize(const AsmMatcherInfo &Info, SmallPtrSetImpl &SingletonRegisters, - int AsmVariantNo, std::string &RegisterPrefix) { + int AsmVariantNo, StringRef RegisterPrefix) { AsmVariantID = AsmVariantNo; AsmString = CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo); @@ -796,16 +836,15 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, tokenizeAsmString(Info); // Compute the require features. - std::vector Predicates =TheDef->getValueAsListOfDefs("Predicates"); - for (unsigned i = 0, e = Predicates.size(); i != e; ++i) + for (Record *Predicate : TheDef->getValueAsListOfDefs("Predicates")) if (const SubtargetFeatureInfo *Feature = - Info.getSubtargetFeature(Predicates[i])) + Info.getSubtargetFeature(Predicate)) RequiredFeatures.push_back(Feature); // Collect singleton registers, if used. - for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { - extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix); - if (Record *Reg = AsmOperands[i].SingletonReg) + for (MatchableInfo::AsmOperand &Op : AsmOperands) { + extractSingletonRegisterForAsmOperand(Op, Info, RegisterPrefix); + if (Record *Reg = Op.SingletonReg) SingletonRegisters.insert(Reg); } @@ -833,9 +872,9 @@ void MatchableInfo::addAsmOperand(size_t Start, size_t End) { /// tokenizeAsmString - Tokenize a simplified assembly string. void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { StringRef String = AsmString; - unsigned Prev = 0; + size_t Prev = 0; bool InTok = true; - for (unsigned i = 0, e = String.size(); i != e; ++i) { + for (size_t i = 0, e = String.size(); i != e; ++i) { switch (String[i]) { case '[': case ']': @@ -870,15 +909,16 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { InTok = false; } - // If this isn't "${", treat like a normal token. + // If this isn't "${", start new identifier looking like "$xxx" if (i + 1 == String.size() || String[i + 1] != '{') { Prev = i; 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(); + // If this is "${" find the next "}" and make an identifier like "${xxx}" + size_t EndPos = String.find('}', i); + assert(EndPos != StringRef::npos && + "Missing brace in operand reference!"); addAsmOperand(i, EndPos+1); Prev = EndPos + 1; i = EndPos; @@ -974,38 +1014,6 @@ bool MatchableInfo::validate(StringRef CommentDelimiter, bool Hack) const { return true; } -/// extractSingletonRegisterForAsmOperand - Extract singleton register, -/// if present, from specified token. -void MatchableInfo:: -extractSingletonRegisterForAsmOperand(unsigned OperandNo, - const AsmMatcherInfo &Info, - std::string &RegisterPrefix) { - StringRef Tok = AsmOperands[OperandNo].Token; - - // If this token is not an isolated token, i.e., it isn't separated from - // other tokens (e.g. with whitespace), don't interpret it as a register name. - if (!AsmOperands[OperandNo].IsIsolatedToken) - return; - - if (RegisterPrefix.empty()) { - std::string LoweredTok = Tok.lower(); - if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok)) - AsmOperands[OperandNo].SingletonReg = Reg->TheDef; - return; - } - - if (!Tok.startswith(RegisterPrefix)) - return; - - StringRef RegName = Tok.substr(RegisterPrefix.size()); - if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) - AsmOperands[OperandNo].SingletonReg = Reg->TheDef; - - // If there is no register prefix (i.e. "%" in "%eax"), then this may - // be some random non-register token, just ignore it. - return; -} - static std::string getEnumNameForToken(StringRef Str) { std::string Res; @@ -1378,7 +1386,7 @@ void AsmMatcherInfo::buildInfo() { if (CGI->TheDef->getValueAsBit("isCodeGenOnly")) continue; - std::unique_ptr II(new MatchableInfo(*CGI)); + auto II = llvm::make_unique(*CGI); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); @@ -1405,7 +1413,7 @@ void AsmMatcherInfo::buildInfo() { .startswith( MatchPrefix)) continue; - std::unique_ptr II(new MatchableInfo(std::move(Alias))); + auto II = llvm::make_unique(std::move(Alias)); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); @@ -1474,7 +1482,7 @@ void AsmMatcherInfo::buildInfo() { II->TheDef->getValueAsString("TwoOperandAliasConstraint"); if (Constraint != "") { // Start by making a copy of the original matchable. - std::unique_ptr AliasII(new MatchableInfo(*II)); + auto AliasII = llvm::make_unique(*II); // Adjust it to be a two-operand alias. AliasII->formTwoOperandAlias(Constraint); @@ -1959,7 +1967,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, continue; // Add the row to the table. - ConversionTable.push_back(ConversionRow); + ConversionTable.push_back(std::move(ConversionRow)); } // Finish up the converter driver function. @@ -1979,10 +1987,8 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, // Output the instruction conversion kind enum. OS << "enum InstructionConversionKind {\n"; - for (SetVector::const_iterator - i = InstructionConversionKinds.begin(), - e = InstructionConversionKinds.end(); i != e; ++i) - OS << " " << *i << ",\n"; + for (const std::string &Signature : InstructionConversionKinds) + OS << " " << Signature << ",\n"; OS << " CVT_NUM_SIGNATURES\n"; OS << "};\n\n"; @@ -2223,7 +2229,7 @@ static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, << " {\n"; for (const auto &SF : Info.SubtargetFeatures) { const SubtargetFeatureInfo &SFI = SF.second; - OS << " " << SFI.getEnumName() << " = " << SFI.Index << ",\n"; + OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n"; } OS << " Feature_None = 0\n"; OS << "};\n\n"; @@ -2254,9 +2260,9 @@ static void emitOperandDiagnosticTypes(AsmMatcherInfo &Info, raw_ostream &OS) { static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) { OS << "// User-level names for subtarget features that participate in\n" << "// instruction matching.\n" - << "static const char *getSubtargetFeatureName(uint64_t Feature) {\n"; + << "static const char *getSubtargetFeatureName(uint64_t Val) {\n"; if (!Info.SubtargetFeatures.empty()) { - OS << " switch(Feature) {\n"; + OS << " switch(Val) {\n"; for (const auto &SF : Info.SubtargetFeatures) { const SubtargetFeatureInfo &SFI = SF.second; // FIXME: Totally just a placeholder name to get the algorithm working. @@ -2279,9 +2285,9 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info, std::string ClassName = Info.AsmParser->getValueAsString("AsmParserClassName"); - OS << "FeatureBitset " << Info.Target.getName() << ClassName << "::\n" + OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n" << "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n"; - OS << " FeatureBitset Features;\n"; + OS << " uint64_t Features = 0;\n"; for (const auto &SF : Info.SubtargetFeatures) { const SubtargetFeatureInfo &SFI = SF.second; @@ -2315,7 +2321,7 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info, } while (true); OS << ")\n"; - OS << " Features.set(" << SFI.getEnumName() << ", 1);\n"; + OS << " Features |= " << SFI.getEnumName() << ";\n"; } OS << " return Features;\n"; OS << "}\n\n"; @@ -2400,7 +2406,7 @@ static void emitMnemonicAliasVariant(raw_ostream &OS,const AsmMatcherInfo &Info, if (!MatchCode.empty()) MatchCode += "else "; - MatchCode += "if ((Features & FeatureBitset({"+FeatureMask+"})) == FeatureBitset({"+FeatureMask+"}))\n"; + MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n"; MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n"; } @@ -2431,7 +2437,7 @@ static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info, if (Aliases.empty()) return false; OS << "static void applyMnemonicAliases(StringRef &Mnemonic, " - "FeatureBitset Features, unsigned VariantID) {\n"; + "uint64_t Features, unsigned VariantID) {\n"; OS << " switch (VariantID) {\n"; unsigned VariantCount = Target.getAsmParserVariantCount(); for (unsigned VC = 0; VC != VariantCount; ++VC) { @@ -2467,7 +2473,8 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Emit the static custom operand parsing table; OS << "namespace {\n"; OS << " struct OperandMatchEntry {\n"; - OS << " FeatureBitset RequiredFeatures;\n"; + OS << " " << getMinimalRequiredFeaturesType(Info) + << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) << " Mnemonic;\n"; OS << " " << getMinimalTypeForRange(std::distance( @@ -2510,14 +2517,12 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Write the required features mask. if (!II.RequiredFeatures.empty()) { - OS << "{"; for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { - if (i) OS << ","; + if (i) OS << "|"; OS << II.RequiredFeatures[i]->getEnumName(); } - OS << "}"; } else - OS << "{}"; + OS << "0"; // Store a pascal-style length byte in the mnemonic. std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); @@ -2573,7 +2578,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Emit code to get the available features. OS << " // Get the current feature set.\n"; - OS << " FeatureBitset AvailableFeatures = getAvailableFeatures();\n\n"; + OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n"; OS << " // Get the next operand index.\n"; OS << " unsigned NextOpNum = Operands.size()-1;\n"; @@ -2676,7 +2681,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "#undef GET_ASSEMBLER_HEADER\n"; OS << " // This should be included into the middle of the declaration of\n"; OS << " // your subclasses implementation of MCTargetAsmParser.\n"; - OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset& FB) const;\n"; + OS << " uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n"; OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, " << "unsigned Opcode,\n" << " const OperandVector " @@ -2686,9 +2691,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n"; OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n" << " MCInst &Inst,\n" - << " uint64_t &ErrorInfo,\n" - << " FeatureBitset &ErrorMissingFeature,\n" - << " bool matchingInlineAsm,\n" + << " uint64_t &ErrorInfo," + << " bool matchingInlineAsm,\n" << " unsigned VariantID = 0);\n"; if (!Info.OperandMatchInfo.empty()) { @@ -2799,7 +2803,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " uint16_t Opcode;\n"; OS << " " << getMinimalTypeForRange(Info.Matchables.size()) << " ConvertFn;\n"; - OS << " FeatureBitset RequiredFeatures;\n"; + OS << " " << getMinimalRequiredFeaturesType(Info) + << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange( std::distance(Info.Classes.begin(), Info.Classes.end())) << " Classes[" << MaxNumOperands << "];\n"; @@ -2845,14 +2850,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Write the required features mask. if (!MI->RequiredFeatures.empty()) { - OS << "{"; for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) { - if (i) OS << ","; + if (i) OS << "|"; OS << MI->RequiredFeatures[i]->getEnumName(); } - OS << "}"; } else - OS << "{}"; + OS << "0"; OS << ", { "; for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) { @@ -2891,7 +2894,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "unsigned " << Target.getName() << ClassName << "::\n" << "MatchInstructionImpl(const OperandVector &Operands,\n"; OS << " MCInst &Inst, uint64_t &ErrorInfo,\n" - << " FeatureBitset &ErrorMissingFeature,\n" << " bool matchingInlineAsm, unsigned VariantID) {\n"; OS << " // Eliminate obvious mismatches.\n"; @@ -2902,7 +2904,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Emit code to get the available features. OS << " // Get the current feature set.\n"; - OS << " FeatureBitset AvailableFeatures = getAvailableFeatures();\n\n"; + OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n"; OS << " // Get the instruction mnemonic, which is the first token.\n"; OS << " StringRef Mnemonic = ((" << Target.getName() @@ -2918,7 +2920,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " bool HadMatchOtherThanFeatures = false;\n"; OS << " bool HadMatchOtherThanPredicate = false;\n"; OS << " unsigned RetCode = Match_InvalidOperand;\n"; - OS << " FeatureBitset MissingFeatures(~0ULL);\n"; + OS << " uint64_t MissingFeatures = ~0ULL;\n"; OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; OS << " // wrong for all instances of the instruction.\n"; OS << " ErrorInfo = ~0ULL;\n"; @@ -2994,10 +2996,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " if ((AvailableFeatures & it->RequiredFeatures) " << "!= it->RequiredFeatures) {\n"; OS << " HadMatchOtherThanFeatures = true;\n"; - OS << " FeatureBitset NewMissingFeatures = it->RequiredFeatures & " + OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & " "~AvailableFeatures;\n"; - OS << " if (NewMissingFeatures.count() <=\n" - " MissingFeatures.count())\n"; + OS << " if (countPopulation(NewMissingFeatures) <=\n" + " countPopulation(MissingFeatures))\n"; OS << " MissingFeatures = NewMissingFeatures;\n"; OS << " continue;\n"; OS << " }\n"; @@ -3047,7 +3049,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n"; OS << " return RetCode;\n\n"; OS << " // Missing feature matches return which features were missing\n"; - OS << " ErrorMissingFeature = MissingFeatures;\n"; + OS << " ErrorInfo = MissingFeatures;\n"; OS << " return Match_MissingFeature;\n"; OS << "}\n\n";