diff options
Diffstat (limited to 'utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 4169f8d..3d72741 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -117,6 +117,8 @@ #include <sstream> using namespace llvm; +#define DEBUG_TYPE "asm-matcher-emitter" + static cl::opt<std::string> MatchPrefix("match-prefix", cl::init(""), cl::desc("Only match instructions with the given prefix")); @@ -191,10 +193,10 @@ struct ClassInfo { /// parsing on the operand. std::string ParserMethod; - /// For register classes, the records for all the registers in this class. + /// For register classes: the records for all the registers in this class. RegisterSet Registers; - /// For custom match classes, he diagnostic kind for when the predicate fails. + /// For custom match classes: the diagnostic kind for when the predicate fails. std::string DiagnosticType; public: /// isRegisterClass() - Check if this is a register class. @@ -306,8 +308,8 @@ struct MatchableInfo { /// Register record if this token is singleton register. Record *SingletonReg; - explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1), - SingletonReg(0) {} + explicit AsmOperand(StringRef T) : Token(T), Class(nullptr), SubOpIdx(-1), + SingletonReg(nullptr) {} }; /// ResOperand - This represents a single operand in the result instruction @@ -571,6 +573,11 @@ struct SubtargetFeatureInfo { std::string getEnumName() const { return "Feature_" + TheDef->getName(); } + + void dump() { + errs() << getEnumName() << " " << Index << "\n"; + TheDef->dump(); + } }; struct OperandMatchEntry { @@ -666,7 +673,7 @@ public: assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator I = SubtargetFeatures.find(Def); - return I == SubtargetFeatures.end() ? 0 : I->second; + return I == SubtargetFeatures.end() ? nullptr : I->second; } RecordKeeper &getRecords() const { @@ -1018,7 +1025,7 @@ AsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) { // RegisterOperand may have an associated ParserMatchClass. If it does, // use it, else just fall back to the underlying register class. const RecordVal *R = Rec->getValue("ParserMatchClass"); - if (R == 0 || R->getValue() == 0) + if (!R || !R->getValue()) PrintFatalError("Record `" + Rec->getName() + "' does not have a ParserMatchClass!\n"); @@ -1322,6 +1329,7 @@ void AsmMatcherInfo::buildInfo() { unsigned FeatureNo = SubtargetFeatures.size(); SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); + DEBUG(SubtargetFeatures[Pred]->dump()); assert(FeatureNo < 32 && "Too many subtarget features!"); } @@ -1373,7 +1381,8 @@ void AsmMatcherInfo::buildInfo() { std::vector<Record*> AllInstAliases = Records.getAllDerivedDefinitions("InstAlias"); for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) { - CodeGenInstAlias *Alias = new CodeGenInstAlias(AllInstAliases[i], Target); + CodeGenInstAlias *Alias = + new CodeGenInstAlias(AllInstAliases[i], 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 @@ -1897,7 +1906,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, } case MatchableInfo::ResOperand::RegOperand: { std::string Reg, Name; - if (OpInfo.Register == 0) { + if (!OpInfo.Register) { Name = "reg0"; Reg = "0"; } else { @@ -2196,18 +2205,35 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, OS << "}\n\n"; } +static const char *getMinimalTypeForRange(uint64_t Range) { + assert(Range <= 0xFFFFFFFFULL && "Enum too large"); + if (Range > 0xFFFF) + return "uint32_t"; + if (Range > 0xFF) + return "uint16_t"; + return "uint8_t"; +} + +static const char *getMinimalRequiredFeaturesType(const AsmMatcherInfo &Info) { + uint64_t MaxIndex = Info.SubtargetFeatures.size(); + if (MaxIndex > 0) + MaxIndex--; + return getMinimalTypeForRange(1ULL << MaxIndex); +} + /// emitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag /// definitions. static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, raw_ostream &OS) { OS << "// Flags for subtarget features that participate in " << "instruction matching.\n"; - OS << "enum SubtargetFeatureFlag {\n"; + OS << "enum SubtargetFeatureFlag : " << getMinimalRequiredFeaturesType(Info) + << " {\n"; for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator it = Info.SubtargetFeatures.begin(), ie = Info.SubtargetFeatures.end(); it != ie; ++it) { SubtargetFeatureInfo &SFI = *it->second; - OS << " " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n"; + OS << " " << SFI.getEnumName() << " = (1U << " << SFI.Index << "),\n"; } OS << " Feature_None = 0\n"; OS << "};\n\n"; @@ -2319,7 +2345,7 @@ static std::string GetAliasRequiredFeatures(Record *R, for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) { SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); - if (F == 0) + if (!F) PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() + "' is not marked as an AssemblerPredicate!"); @@ -2443,15 +2469,6 @@ static bool emitMnemonicAliases(raw_ostream &OS, const AsmMatcherInfo &Info, return true; } -static const char *getMinimalTypeForRange(uint64_t Range) { - assert(Range < 0xFFFFFFFFULL && "Enum too large"); - if (Range > 0xFFFF) - return "uint32_t"; - if (Range > 0xFF) - return "uint16_t"; - return "uint8_t"; -} - static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, const AsmMatcherInfo &Info, StringRef ClassName, StringToOffsetTable &StringTable, @@ -2466,7 +2483,7 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Emit the static custom operand parsing table; OS << "namespace {\n"; OS << " struct OperandMatchEntry {\n"; - OS << " " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size()) + OS << " " << getMinimalRequiredFeaturesType(Info) << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) << " Mnemonic;\n"; @@ -2802,7 +2819,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " uint16_t Opcode;\n"; OS << " " << getMinimalTypeForRange(Info.Matchables.size()) << " ConvertFn;\n"; - OS << " " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size()) + OS << " " << getMinimalRequiredFeaturesType(Info) << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange(Info.Classes.size()) << " Classes[" << MaxNumOperands << "];\n"; @@ -2881,8 +2898,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { for (unsigned VC = 0; VC != VariantCount; ++VC) { Record *AsmVariant = Target.getAsmParserVariant(VC); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); - OS << " case " << AsmVariantNo << ": Start = MatchTable" << VC - << "; End = array_endof(MatchTable" << VC << "); break;\n"; + OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC + << "); End = std::end(MatchTable" << VC << "); break;\n"; } OS << " }\n"; OS << " // Search the table.\n"; @@ -2936,8 +2953,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { for (unsigned VC = 0; VC != VariantCount; ++VC) { Record *AsmVariant = Target.getAsmParserVariant(VC); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); - OS << " case " << AsmVariantNo << ": Start = MatchTable" << VC - << "; End = array_endof(MatchTable" << VC << "); break;\n"; + OS << " case " << AsmVariantNo << ": Start = std::begin(MatchTable" << VC + << "); End = std::end(MatchTable" << VC << "); break;\n"; } OS << " }\n"; OS << " // Search the table.\n"; |