diff options
Diffstat (limited to 'utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 429 |
1 files changed, 184 insertions, 245 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 891328f..65a34d3 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -115,6 +115,7 @@ #include <map> #include <set> #include <sstream> +#include <forward_list> using namespace llvm; #define DEBUG_TYPE "asm-matcher-emitter" @@ -255,9 +256,8 @@ public: return true; // ... or if any of its super classes are a subset of RHS. - for (std::vector<ClassInfo*>::const_iterator it = SuperClasses.begin(), - ie = SuperClasses.end(); it != ie; ++it) - if ((*it)->isSubsetOf(RHS)) + for (const ClassInfo *CI : SuperClasses) + if (CI->isSubsetOf(RHS)) return true; return false; @@ -391,6 +391,10 @@ struct MatchableInfo { /// AsmVariantID - Target's assembly syntax variant no. int AsmVariantID; + /// AsmString - The assembly string for this instruction (with variants + /// removed), e.g. "movsx $src, $dst". + std::string AsmString; + /// TheDef - This is the definition of the instruction or InstAlias that this /// matchable came from. Record *const TheDef; @@ -408,10 +412,6 @@ struct MatchableInfo { /// MCInst. SmallVector<ResOperand, 8> ResOperands; - /// AsmString - The assembly string for this instruction (with variants - /// removed), e.g. "movsx $src, $dst". - std::string AsmString; - /// Mnemonic - This is the first token of the matched instruction, its /// mnemonic. StringRef Mnemonic; @@ -423,7 +423,7 @@ struct MatchableInfo { SmallVector<AsmOperand, 8> AsmOperands; /// Predicates - The required subtarget features to match this instruction. - SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures; + SmallVector<const SubtargetFeatureInfo *, 4> RequiredFeatures; /// ConversionFnKind - The enum value which is passed to the generated /// convertToMCInst to convert parsed operands into an MCInst for this @@ -434,13 +434,15 @@ struct MatchableInfo { bool HasDeprecation; MatchableInfo(const CodeGenInstruction &CGI) - : AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI), - AsmString(CGI.AsmString) { + : AsmVariantID(0), AsmString(CGI.AsmString), TheDef(CGI.TheDef), DefRec(&CGI) { } - MatchableInfo(const CodeGenInstAlias *Alias) - : AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias), - AsmString(Alias->AsmString) { + MatchableInfo(std::unique_ptr<const CodeGenInstAlias> Alias) + : AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef), DefRec(Alias.release()) { + } + + ~MatchableInfo() { + delete DefRec.dyn_cast<const CodeGenInstAlias*>(); } // Two-operand aliases clone from the main matchable, but mark the second @@ -516,7 +518,7 @@ struct MatchableInfo { /// couldMatchAmbiguouslyWith - Check whether this matchable could /// ambiguously match the same set of operands as \p RHS (without being a /// strictly superior match). - bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) { + bool couldMatchAmbiguouslyWith(const MatchableInfo &RHS) const { // The primary comparator is the instruction mnemonic. if (Mnemonic != RHS.Mnemonic) return false; @@ -552,7 +554,7 @@ struct MatchableInfo { return !(HasLT ^ HasGT); } - void dump(); + void dump() const; private: void tokenizeAsmString(const AsmMatcherInfo &Info); @@ -574,7 +576,7 @@ struct SubtargetFeatureInfo { return "Feature_" + TheDef->getName(); } - void dump() { + void dump() const { errs() << getEnumName() << " " << Index << "\n"; TheDef->dump(); } @@ -582,10 +584,10 @@ struct SubtargetFeatureInfo { struct OperandMatchEntry { unsigned OperandMask; - MatchableInfo* MI; + const MatchableInfo* MI; ClassInfo *CI; - static OperandMatchEntry create(MatchableInfo* mi, ClassInfo *ci, + static OperandMatchEntry create(const MatchableInfo *mi, ClassInfo *ci, unsigned opMask) { OperandMatchEntry X; X.OperandMask = opMask; @@ -608,10 +610,10 @@ public: CodeGenTarget &Target; /// The classes which are needed for matching. - std::vector<ClassInfo*> Classes; + std::forward_list<ClassInfo> Classes; /// The information on the matchables to match. - std::vector<MatchableInfo*> Matchables; + std::vector<std::unique_ptr<MatchableInfo>> Matchables; /// Info for custom matching operands by user defined methods. std::vector<OperandMatchEntry> OperandMatchInfo; @@ -621,7 +623,7 @@ public: RegisterClassesTy RegisterClasses; /// Map of Predicate records to their subtarget information. - std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> SubtargetFeatures; + std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures; /// Map of AsmOperandClass records to their class information. std::map<Record*, ClassInfo*> AsmOperandClasses; @@ -669,11 +671,10 @@ public: /// getSubtargetFeature - Lookup or create the subtarget feature info for the /// given operand. - SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const { + const SubtargetFeatureInfo *getSubtargetFeature(Record *Def) const { assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); - std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator I = - SubtargetFeatures.find(Def); - return I == SubtargetFeatures.end() ? nullptr : I->second; + const auto &I = SubtargetFeatures.find(Def); + return I == SubtargetFeatures.end() ? nullptr : &I->second; } RecordKeeper &getRecords() const { @@ -683,11 +684,11 @@ public: } // End anonymous namespace -void MatchableInfo::dump() { +void MatchableInfo::dump() const { errs() << TheDef->getName() << " -- " << "flattened:\"" << AsmString <<"\"\n"; for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { - AsmOperand &Op = AsmOperands[i]; + const AsmOperand &Op = AsmOperands[i]; errs() << " op[" << i << "] = " << Op.Class->ClassName << " - "; errs() << '\"' << Op.Token << "\"\n"; } @@ -777,8 +778,8 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, // Compute the require features. std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates"); for (unsigned i = 0, e = Predicates.size(); i != e; ++i) - if (SubtargetFeatureInfo *Feature = - Info.getSubtargetFeature(Predicates[i])) + if (const SubtargetFeatureInfo *Feature = + Info.getSubtargetFeature(Predicates[i])) RequiredFeatures.push_back(Feature); // Collect singleton registers, if used. @@ -978,6 +979,7 @@ static std::string getEnumNameForToken(StringRef Str) { case '.': Res += "_DOT_"; break; case '<': Res += "_LT_"; break; case '>': Res += "_GT_"; break; + case '-': Res += "_MINUS_"; break; default: if ((*it >= 'A' && *it <= 'Z') || (*it >= 'a' && *it <= 'z') || @@ -995,7 +997,8 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { ClassInfo *&Entry = TokenClasses[Token]; if (!Entry) { - Entry = new ClassInfo(); + Classes.emplace_front(); + Entry = &Classes.front(); Entry->Kind = ClassInfo::Token; Entry->ClassName = "Token"; Entry->Name = "MCK_" + getEnumNameForToken(Token); @@ -1004,7 +1007,6 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) { Entry->RenderMethod = "<invalid>"; Entry->ParserMethod = ""; Entry->DiagnosticType = ""; - Classes.push_back(Entry); } return Entry; @@ -1076,10 +1078,8 @@ struct LessRegisterSet { void AsmMatcherInfo:: buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { - const std::vector<CodeGenRegister*> &Registers = - Target.getRegBank().getRegisters(); - ArrayRef<CodeGenRegisterClass*> RegClassList = - Target.getRegBank().getRegClasses(); + const auto &Registers = Target.getRegBank().getRegisters(); + auto &RegClassList = Target.getRegBank().getRegClasses(); typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet; @@ -1087,15 +1087,12 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { RegisterSetSet RegisterSets; // Gather the defined sets. - for (ArrayRef<CodeGenRegisterClass*>::const_iterator it = - RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) - RegisterSets.insert(RegisterSet( - (*it)->getOrder().begin(), (*it)->getOrder().end())); + for (const CodeGenRegisterClass &RC : RegClassList) + RegisterSets.insert( + RegisterSet(RC.getOrder().begin(), RC.getOrder().end())); // Add any required singleton sets. - for (SmallPtrSetImpl<Record*>::iterator it = SingletonRegisters.begin(), - ie = SingletonRegisters.end(); it != ie; ++it) { - Record *Rec = *it; + for (Record *Rec : SingletonRegisters) { RegisterSets.insert(RegisterSet(&Rec, &Rec + 1)); } @@ -1103,19 +1100,16 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { // a unique register set class), and build the mapping of registers to the set // they should classify to. std::map<Record*, RegisterSet> RegisterMap; - for (std::vector<CodeGenRegister*>::const_iterator it = Registers.begin(), - ie = Registers.end(); it != ie; ++it) { - const CodeGenRegister &CGR = **it; + for (const CodeGenRegister &CGR : Registers) { // Compute the intersection of all sets containing this register. RegisterSet ContainingSet; - for (RegisterSetSet::iterator it = RegisterSets.begin(), - ie = RegisterSets.end(); it != ie; ++it) { - if (!it->count(CGR.TheDef)) + for (const RegisterSet &RS : RegisterSets) { + if (!RS.count(CGR.TheDef)) continue; if (ContainingSet.empty()) { - ContainingSet = *it; + ContainingSet = RS; continue; } @@ -1123,7 +1117,7 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { std::swap(Tmp, ContainingSet); std::insert_iterator<RegisterSet> II(ContainingSet, ContainingSet.begin()); - std::set_intersection(Tmp.begin(), Tmp.end(), it->begin(), it->end(), II, + std::set_intersection(Tmp.begin(), Tmp.end(), RS.begin(), RS.end(), II, LessRecordByID()); } @@ -1136,39 +1130,35 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { // Construct the register classes. std::map<RegisterSet, ClassInfo*, LessRegisterSet> RegisterSetClasses; unsigned Index = 0; - for (RegisterSetSet::iterator it = RegisterSets.begin(), - ie = RegisterSets.end(); it != ie; ++it, ++Index) { - ClassInfo *CI = new ClassInfo(); + for (const RegisterSet &RS : RegisterSets) { + Classes.emplace_front(); + ClassInfo *CI = &Classes.front(); CI->Kind = ClassInfo::RegisterClass0 + Index; CI->ClassName = "Reg" + utostr(Index); CI->Name = "MCK_Reg" + utostr(Index); CI->ValueName = ""; CI->PredicateMethod = ""; // unused CI->RenderMethod = "addRegOperands"; - CI->Registers = *it; + CI->Registers = RS; // FIXME: diagnostic type. CI->DiagnosticType = ""; - Classes.push_back(CI); - RegisterSetClasses.insert(std::make_pair(*it, CI)); + RegisterSetClasses.insert(std::make_pair(RS, CI)); + ++Index; } // Find the superclasses; we could compute only the subgroup lattice edges, // but there isn't really a point. - for (RegisterSetSet::iterator it = RegisterSets.begin(), - ie = RegisterSets.end(); it != ie; ++it) { - ClassInfo *CI = RegisterSetClasses[*it]; - for (RegisterSetSet::iterator it2 = RegisterSets.begin(), - ie2 = RegisterSets.end(); it2 != ie2; ++it2) - if (*it != *it2 && - std::includes(it2->begin(), it2->end(), it->begin(), it->end(), + for (const RegisterSet &RS : RegisterSets) { + ClassInfo *CI = RegisterSetClasses[RS]; + for (const RegisterSet &RS2 : RegisterSets) + if (RS != RS2 && + std::includes(RS2.begin(), RS2.end(), RS.begin(), RS.end(), LessRecordByID())) - CI->SuperClasses.push_back(RegisterSetClasses[*it2]); + CI->SuperClasses.push_back(RegisterSetClasses[RS2]); } // Name the register classes which correspond to a user defined RegisterClass. - for (ArrayRef<CodeGenRegisterClass*>::const_iterator - it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { - const CodeGenRegisterClass &RC = **it; + for (const CodeGenRegisterClass &RC : RegClassList) { // Def will be NULL for non-user defined register classes. Record *Def = RC.getDef(); if (!Def) @@ -1191,9 +1181,7 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) { RegisterClasses[it->first] = RegisterSetClasses[it->second]; // Name the register classes which correspond to singleton registers. - for (SmallPtrSetImpl<Record*>::iterator it = SingletonRegisters.begin(), - ie = SingletonRegisters.end(); it != ie; ++it) { - Record *Rec = *it; + for (Record *Rec : SingletonRegisters) { ClassInfo *CI = RegisterClasses[Rec]; assert(CI && "Missing singleton register class info!"); @@ -1211,36 +1199,36 @@ void AsmMatcherInfo::buildOperandClasses() { Records.getAllDerivedDefinitions("AsmOperandClass"); // Pre-populate AsmOperandClasses map. - for (std::vector<Record*>::iterator it = AsmOperands.begin(), - ie = AsmOperands.end(); it != ie; ++it) - AsmOperandClasses[*it] = new ClassInfo(); + for (Record *Rec : AsmOperands) { + Classes.emplace_front(); + AsmOperandClasses[Rec] = &Classes.front(); + } unsigned Index = 0; - for (std::vector<Record*>::iterator it = AsmOperands.begin(), - ie = AsmOperands.end(); it != ie; ++it, ++Index) { - ClassInfo *CI = AsmOperandClasses[*it]; + for (Record *Rec : AsmOperands) { + ClassInfo *CI = AsmOperandClasses[Rec]; CI->Kind = ClassInfo::UserClass0 + Index; - ListInit *Supers = (*it)->getValueAsListInit("SuperClasses"); + ListInit *Supers = Rec->getValueAsListInit("SuperClasses"); for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i)); if (!DI) { - PrintError((*it)->getLoc(), "Invalid super class reference!"); + PrintError(Rec->getLoc(), "Invalid super class reference!"); continue; } ClassInfo *SC = AsmOperandClasses[DI->getDef()]; if (!SC) - PrintError((*it)->getLoc(), "Invalid super class reference!"); + PrintError(Rec->getLoc(), "Invalid super class reference!"); else CI->SuperClasses.push_back(SC); } - CI->ClassName = (*it)->getValueAsString("Name"); + CI->ClassName = Rec->getValueAsString("Name"); CI->Name = "MCK_" + CI->ClassName; - CI->ValueName = (*it)->getName(); + CI->ValueName = Rec->getName(); // Get or construct the predicate method name. - Init *PMName = (*it)->getValueInit("PredicateMethod"); + Init *PMName = Rec->getValueInit("PredicateMethod"); if (StringInit *SI = dyn_cast<StringInit>(PMName)) { CI->PredicateMethod = SI->getValue(); } else { @@ -1249,7 +1237,7 @@ void AsmMatcherInfo::buildOperandClasses() { } // Get or construct the render method name. - Init *RMName = (*it)->getValueInit("RenderMethod"); + Init *RMName = Rec->getValueInit("RenderMethod"); if (StringInit *SI = dyn_cast<StringInit>(RMName)) { CI->RenderMethod = SI->getValue(); } else { @@ -1258,18 +1246,17 @@ void AsmMatcherInfo::buildOperandClasses() { } // Get the parse method name or leave it as empty. - Init *PRMName = (*it)->getValueInit("ParserMethod"); + Init *PRMName = Rec->getValueInit("ParserMethod"); if (StringInit *SI = dyn_cast<StringInit>(PRMName)) CI->ParserMethod = SI->getValue(); // Get the diagnostic type or leave it as empty. // Get the parse method name or leave it as empty. - Init *DiagnosticType = (*it)->getValueInit("DiagnosticType"); + Init *DiagnosticType = Rec->getValueInit("DiagnosticType"); if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType)) CI->DiagnosticType = SI->getValue(); - AsmOperandClasses[*it] = CI; - Classes.push_back(CI); + ++Index; } } @@ -1288,16 +1275,13 @@ void AsmMatcherInfo::buildOperandMatchInfo() { typedef std::map<ClassInfo *, unsigned, less_ptr<ClassInfo>> OpClassMaskTy; OpClassMaskTy OpClassMask; - for (std::vector<MatchableInfo*>::const_iterator it = - Matchables.begin(), ie = Matchables.end(); - it != ie; ++it) { - MatchableInfo &II = **it; + for (const auto &MI : Matchables) { OpClassMask.clear(); // Keep track of all operands of this instructions which belong to the // same class. - for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { - MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; + for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) { + const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i]; if (Op.Class->ParserMethod.empty()) continue; unsigned &OperandMask = OpClassMask[Op.Class]; @@ -1305,11 +1289,11 @@ void AsmMatcherInfo::buildOperandMatchInfo() { } // Generate operand match info for each mnemonic/operand class pair. - for (OpClassMaskTy::iterator iit = OpClassMask.begin(), - iie = OpClassMask.end(); iit != iie; ++iit) { - unsigned OpMask = iit->second; - ClassInfo *CI = iit->first; - OperandMatchInfo.push_back(OperandMatchEntry::create(&II, CI, OpMask)); + for (const auto &OCM : OpClassMask) { + unsigned OpMask = OCM.second; + ClassInfo *CI = OCM.first; + OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI, + OpMask)); } } } @@ -1327,10 +1311,10 @@ void AsmMatcherInfo::buildInfo() { if (Pred->getName().empty()) PrintFatalError(Pred->getLoc(), "Predicate has no name!"); - uint64_t FeatureNo = SubtargetFeatures.size(); - SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); - DEBUG(SubtargetFeatures[Pred]->dump()); - assert(FeatureNo < 64 && "Too many subtarget features!"); + SubtargetFeatures.insert(std::make_pair( + Pred, SubtargetFeatureInfo(Pred, SubtargetFeatures.size()))); + DEBUG(SubtargetFeatures.find(Pred)->second.dump()); + assert(SubtargetFeatures.size() <= 64 && "Too many subtarget features!"); } // Parse the instructions; we need to do this first so that we can gather the @@ -1344,20 +1328,18 @@ void AsmMatcherInfo::buildInfo() { std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) { - const CodeGenInstruction &CGI = **I; + for (const CodeGenInstruction *CGI : Target.instructions()) { // If the tblgen -match-prefix option is specified (for tblgen hackers), // filter the set of instructions we consider. - if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix)) + if (!StringRef(CGI->TheDef->getName()).startswith(MatchPrefix)) continue; // Ignore "codegen only" instructions. - if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) + if (CGI->TheDef->getValueAsBit("isCodeGenOnly")) continue; - std::unique_ptr<MatchableInfo> II(new MatchableInfo(CGI)); + std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI)); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); @@ -1366,14 +1348,7 @@ void AsmMatcherInfo::buildInfo() { if (!II->validate(CommentDelimiter, true)) continue; - // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. - // - // FIXME: This is a total hack. - if (StringRef(II->TheDef->getName()).startswith("Int_") || - StringRef(II->TheDef->getName()).endswith("_Int")) - continue; - - Matchables.push_back(II.release()); + Matchables.push_back(std::move(II)); } // Parse all of the InstAlias definitions and stick them in the list of @@ -1381,8 +1356,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], AsmVariantNo, Target); + auto Alias = llvm::make_unique<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 @@ -1391,14 +1366,14 @@ void AsmMatcherInfo::buildInfo() { .startswith( MatchPrefix)) continue; - std::unique_ptr<MatchableInfo> II(new MatchableInfo(Alias)); + std::unique_ptr<MatchableInfo> II(new MatchableInfo(std::move(Alias))); II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); // Validate the alias definitions. II->validate(CommentDelimiter, false); - Matchables.push_back(II.release()); + Matchables.push_back(std::move(II)); } } @@ -1410,11 +1385,8 @@ void AsmMatcherInfo::buildInfo() { // Build the information about matchables, now that we have fully formed // classes. - std::vector<MatchableInfo*> NewMatchables; - for (std::vector<MatchableInfo*>::iterator it = Matchables.begin(), - ie = Matchables.end(); it != ie; ++it) { - MatchableInfo *II = *it; - + std::vector<std::unique_ptr<MatchableInfo>> NewMatchables; + for (auto &II : Matchables) { // Parse the tokens after the mnemonic. // Note: buildInstructionOperandReference may insert new AsmOperands, so // don't precompute the loop bound. @@ -1449,9 +1421,9 @@ void AsmMatcherInfo::buildInfo() { OperandName = Token.substr(1); if (II->DefRec.is<const CodeGenInstruction*>()) - buildInstructionOperandReference(II, OperandName, i); + buildInstructionOperandReference(II.get(), OperandName, i); else - buildAliasOperandReference(II, OperandName, Op); + buildAliasOperandReference(II.get(), OperandName, Op); } if (II->DefRec.is<const CodeGenInstruction*>()) { @@ -1469,14 +1441,14 @@ void AsmMatcherInfo::buildInfo() { AliasII->formTwoOperandAlias(Constraint); // Add the alias to the matchables list. - NewMatchables.push_back(AliasII.release()); + NewMatchables.push_back(std::move(AliasII)); } } else II->buildAliasResultOperands(); } if (!NewMatchables.empty()) - Matchables.insert(Matchables.end(), NewMatchables.begin(), - NewMatchables.end()); + std::move(NewMatchables.begin(), NewMatchables.end(), + std::back_inserter(Matchables)); // Process token alias definitions and set up the associated superclass // information. @@ -1493,7 +1465,7 @@ void AsmMatcherInfo::buildInfo() { } // Reorder classes so that classes precede super classes. - std::sort(Classes.begin(), Classes.end(), less_ptr<ClassInfo>()); + Classes.sort(); } /// buildInstructionOperandReference - The specified operand is a reference to a @@ -1703,7 +1675,7 @@ static unsigned getConverterOperandID(const std::string &Name, static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, - std::vector<MatchableInfo*> &Infos, + std::vector<std::unique_ptr<MatchableInfo>> &Infos, raw_ostream &OS) { SetVector<std::string> OperandConversionKinds; SetVector<std::string> InstructionConversionKinds; @@ -1767,16 +1739,13 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, OperandConversionKinds.insert("CVT_Tied"); enum { CVT_Done, CVT_Reg, CVT_Tied }; - for (std::vector<MatchableInfo*>::const_iterator it = Infos.begin(), - ie = Infos.end(); it != ie; ++it) { - MatchableInfo &II = **it; - + for (auto &II : Infos) { // Check if we have a custom match function. std::string AsmMatchConverter = - II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); + II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter"); if (!AsmMatchConverter.empty()) { std::string Signature = "ConvertCustom_" + AsmMatchConverter; - II.ConversionFnKind = Signature; + II->ConversionFnKind = Signature; // Check if we have already generated this signature. if (!InstructionConversionKinds.insert(Signature)) @@ -1808,16 +1777,17 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, std::vector<uint8_t> ConversionRow; // Compute the convert enum and the case body. - MaxRowLength = std::max(MaxRowLength, II.ResOperands.size()*2 + 1 ); + MaxRowLength = std::max(MaxRowLength, II->ResOperands.size()*2 + 1 ); - for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) { - const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i]; + for (unsigned i = 0, e = II->ResOperands.size(); i != e; ++i) { + const MatchableInfo::ResOperand &OpInfo = II->ResOperands[i]; // Generate code to populate each result operand. switch (OpInfo.Kind) { case MatchableInfo::ResOperand::RenderAsmOperand: { // This comes from something we parsed. - MatchableInfo::AsmOperand &Op = II.AsmOperands[OpInfo.AsmOperandNum]; + const MatchableInfo::AsmOperand &Op = + II->AsmOperands[OpInfo.AsmOperandNum]; // Registers are always converted the same, don't duplicate the // conversion function based on them. @@ -1879,6 +1849,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, case MatchableInfo::ResOperand::ImmOperand: { int64_t Val = OpInfo.ImmVal; std::string Ty = "imm_" + itostr(Val); + Ty = getEnumNameForToken(Ty); Signature += "__" + Ty; std::string Name = "CVT_" + Ty; @@ -1940,7 +1911,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, if (Signature == "Convert") Signature += "_NoOperands"; - II.ConversionFnKind = Signature; + II->ConversionFnKind = Signature; // Save the signature. If we already have it, don't add a new row // to the table. @@ -2003,7 +1974,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, /// emitMatchClassEnumeration - Emit the enumeration for match class kinds. static void emitMatchClassEnumeration(CodeGenTarget &Target, - std::vector<ClassInfo*> &Infos, + std::forward_list<ClassInfo> &Infos, raw_ostream &OS) { OS << "namespace {\n\n"; @@ -2011,9 +1982,7 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target, << "/// instruction matching.\n"; OS << "enum MatchClassKind {\n"; OS << " InvalidMatchClass = 0,\n"; - for (std::vector<ClassInfo*>::iterator it = Infos.begin(), - ie = Infos.end(); it != ie; ++it) { - ClassInfo &CI = **it; + for (const auto &CI : Infos) { OS << " " << CI.Name << ", // "; if (CI.Kind == ClassInfo::Token) { OS << "'" << CI.ValueName << "'\n"; @@ -2053,10 +2022,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, // Check the user classes. We don't care what order since we're only // actually matching against one of them. - for (std::vector<ClassInfo*>::iterator it = Info.Classes.begin(), - ie = Info.Classes.end(); it != ie; ++it) { - ClassInfo &CI = **it; - + for (const auto &CI : Info.Classes) { if (!CI.isUserClass()) continue; @@ -2075,11 +2041,9 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, OS << " MatchClassKind OpKind;\n"; OS << " switch (Operand.getReg()) {\n"; OS << " default: OpKind = InvalidMatchClass; break;\n"; - for (AsmMatcherInfo::RegisterClassesTy::iterator - it = Info.RegisterClasses.begin(), ie = Info.RegisterClasses.end(); - it != ie; ++it) + for (const auto &RC : Info.RegisterClasses) OS << " case " << Info.Target.getName() << "::" - << it->first->getName() << ": OpKind = " << it->second->Name + << RC.first->getName() << ": OpKind = " << RC.second->Name << "; break;\n"; OS << " }\n"; OS << " return isSubclass(OpKind, Kind) ? " @@ -2094,7 +2058,7 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, /// emitIsSubclass - Emit the subclass predicate function. static void emitIsSubclass(CodeGenTarget &Target, - std::vector<ClassInfo*> &Infos, + std::forward_list<ClassInfo> &Infos, raw_ostream &OS) { OS << "/// isSubclass - Compute whether \\p A is a subclass of \\p B.\n"; OS << "static bool isSubclass(MatchClassKind A, MatchClassKind B) {\n"; @@ -2107,15 +2071,9 @@ static void emitIsSubclass(CodeGenTarget &Target, SS << " switch (A) {\n"; SS << " default:\n"; SS << " return false;\n"; - for (std::vector<ClassInfo*>::iterator it = Infos.begin(), - ie = Infos.end(); it != ie; ++it) { - ClassInfo &A = **it; - + for (const auto &A : Infos) { std::vector<StringRef> SuperClasses; - for (std::vector<ClassInfo*>::iterator it = Infos.begin(), - ie = Infos.end(); it != ie; ++it) { - ClassInfo &B = **it; - + for (const auto &B : Infos) { if (&A != &B && A.isSubsetOf(B)) SuperClasses.push_back(B.Name); } @@ -2157,17 +2115,14 @@ static void emitIsSubclass(CodeGenTarget &Target, /// emitMatchTokenString - Emit the function to match a token string to the /// appropriate match class value. static void emitMatchTokenString(CodeGenTarget &Target, - std::vector<ClassInfo*> &Infos, + std::forward_list<ClassInfo> &Infos, raw_ostream &OS) { // Construct the match list. std::vector<StringMatcher::StringPair> Matches; - for (std::vector<ClassInfo*>::iterator it = Infos.begin(), - ie = Infos.end(); it != ie; ++it) { - ClassInfo &CI = **it; - + for (const auto &CI : Infos) { if (CI.Kind == ClassInfo::Token) - Matches.push_back(StringMatcher::StringPair(CI.ValueName, - "return " + CI.Name + ";")); + Matches.push_back( + StringMatcher::StringPair(CI.ValueName, "return " + CI.Name + ";")); } OS << "static MatchClassKind matchTokenString(StringRef Name) {\n"; @@ -2184,16 +2139,14 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, raw_ostream &OS) { // Construct the match list. std::vector<StringMatcher::StringPair> Matches; - const std::vector<CodeGenRegister*> &Regs = - Target.getRegBank().getRegisters(); - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister *Reg = Regs[i]; - if (Reg->TheDef->getValueAsString("AsmName").empty()) + const auto &Regs = Target.getRegBank().getRegisters(); + for (const CodeGenRegister &Reg : Regs) { + if (Reg.TheDef->getValueAsString("AsmName").empty()) continue; - Matches.push_back(StringMatcher::StringPair( - Reg->TheDef->getValueAsString("AsmName"), - "return " + utostr(Reg->EnumValue) + ";")); + Matches.push_back( + StringMatcher::StringPair(Reg.TheDef->getValueAsString("AsmName"), + "return " + utostr(Reg.EnumValue) + ";")); } OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; @@ -2230,10 +2183,8 @@ static void emitSubtargetFeatureFlagEnumeration(AsmMatcherInfo &Info, << "instruction matching.\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; + for (const auto &SF : Info.SubtargetFeatures) { + const SubtargetFeatureInfo &SFI = SF.second; OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n"; } OS << " Feature_None = 0\n"; @@ -2268,10 +2219,8 @@ static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) { << "static const char *getSubtargetFeatureName(uint64_t Val) {\n"; if (!Info.SubtargetFeatures.empty()) { OS << " switch(Val) {\n"; - typedef std::map<Record*, SubtargetFeatureInfo*, LessRecordByID> RecFeatMap; - for (RecFeatMap::const_iterator it = Info.SubtargetFeatures.begin(), - ie = Info.SubtargetFeatures.end(); it != ie; ++it) { - SubtargetFeatureInfo &SFI = *it->second; + for (const auto &SF : Info.SubtargetFeatures) { + const SubtargetFeatureInfo &SFI = SF.second; // FIXME: Totally just a placeholder name to get the algorithm working. OS << " case " << SFI.getEnumName() << ": return \"" << SFI.TheDef->getValueAsString("PredicateName") << "\";\n"; @@ -2295,10 +2244,8 @@ static void emitComputeAvailableFeatures(AsmMatcherInfo &Info, OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n" << "ComputeAvailableFeatures(uint64_t FB) const {\n"; OS << " uint64_t Features = 0;\n"; - for (std::map<Record*, SubtargetFeatureInfo*, LessRecordByID>::const_iterator - it = Info.SubtargetFeatures.begin(), - ie = Info.SubtargetFeatures.end(); it != ie; ++it) { - SubtargetFeatureInfo &SFI = *it->second; + for (const auto &SF : Info.SubtargetFeatures) { + const SubtargetFeatureInfo &SFI = SF.second; OS << " if ("; std::string CondStorage = @@ -2344,7 +2291,7 @@ static std::string GetAliasRequiredFeatures(Record *R, std::string Result; unsigned NumFeatures = 0; for (unsigned i = 0, e = ReqFeatures.size(); i != e; ++i) { - SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); + const SubtargetFeatureInfo *F = Info.getSubtargetFeature(ReqFeatures[i]); if (!F) PrintFatalError(R->getLoc(), "Predicate '" + ReqFeatures[i]->getName() + @@ -2488,8 +2435,8 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, << " RequiredFeatures;\n"; OS << " " << getMinimalTypeForRange(MaxMnemonicIndex) << " Mnemonic;\n"; - OS << " " << getMinimalTypeForRange(Info.Classes.size()) - << " Class;\n"; + OS << " " << getMinimalTypeForRange(std::distance( + Info.Classes.begin(), Info.Classes.end())) << " Class;\n"; OS << " " << getMinimalTypeForRange(MaxMask) << " OperandMask;\n\n"; OS << " StringRef getMnemonic() const {\n"; @@ -2566,13 +2513,11 @@ static void emitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, << " &Operands,\n unsigned MCK) {\n\n" << " switch(MCK) {\n"; - for (std::vector<ClassInfo*>::const_iterator it = Info.Classes.begin(), - ie = Info.Classes.end(); it != ie; ++it) { - ClassInfo *CI = *it; - if (CI->ParserMethod.empty()) + for (const auto &CI : Info.Classes) { + if (CI.ParserMethod.empty()) continue; - OS << " case " << CI->Name << ":\n" - << " return " << CI->ParserMethod << "(Operands);\n"; + OS << " case " << CI.Name << ":\n" + << " return " << CI.ParserMethod << "(Operands);\n"; } OS << " default:\n"; @@ -2651,22 +2596,23 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // stable_sort to ensure that ambiguous instructions are still // deterministically ordered. std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(), - less_ptr<MatchableInfo>()); + [](const std::unique_ptr<MatchableInfo> &a, + const std::unique_ptr<MatchableInfo> &b){ + return *a < *b;}); DEBUG_WITH_TYPE("instruction_info", { - for (std::vector<MatchableInfo*>::iterator - it = Info.Matchables.begin(), ie = Info.Matchables.end(); - it != ie; ++it) - (*it)->dump(); + for (const auto &MI : Info.Matchables) + MI->dump(); }); // Check for ambiguous matchables. DEBUG_WITH_TYPE("ambiguous_instrs", { unsigned NumAmbiguous = 0; - for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) { - for (unsigned j = i + 1; j != e; ++j) { - MatchableInfo &A = *Info.Matchables[i]; - MatchableInfo &B = *Info.Matchables[j]; + for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E; + ++I) { + for (auto J = std::next(I); J != E; ++J) { + const MatchableInfo &A = **I; + const MatchableInfo &B = **J; if (A.couldMatchAmbiguouslyWith(B)) { errs() << "warning: ambiguous matchables:\n"; @@ -2701,15 +2647,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " void convertToMapAndConstraints(unsigned Kind,\n "; OS << " const OperandVector &Operands) override;\n"; OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n"; - OS << " unsigned MatchInstructionImpl(\n"; - OS.indent(27); - OS << "const OperandVector &Operands,\n" + OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n" << " MCInst &Inst,\n" << " uint64_t &ErrorInfo," << " bool matchingInlineAsm,\n" << " unsigned VariantID = 0);\n"; - if (Info.OperandMatchInfo.size()) { + if (!Info.OperandMatchInfo.empty()) { OS << "\n enum OperandMatchResultTy {\n"; OS << " MatchOperand_Success, // operand matched successfully\n"; OS << " MatchOperand_NoMatch, // operand did not match\n"; @@ -2786,15 +2730,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { size_t MaxNumOperands = 0; unsigned MaxMnemonicIndex = 0; bool HasDeprecation = false; - for (std::vector<MatchableInfo*>::const_iterator it = - Info.Matchables.begin(), ie = Info.Matchables.end(); - it != ie; ++it) { - MatchableInfo &II = **it; - MaxNumOperands = std::max(MaxNumOperands, II.AsmOperands.size()); - HasDeprecation |= II.HasDeprecation; + for (const auto &MI : Info.Matchables) { + MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size()); + HasDeprecation |= MI->HasDeprecation; // Store a pascal-style length byte in the mnemonic. - std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); + std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); MaxMnemonicIndex = std::max(MaxMnemonicIndex, StringTable.GetOrAddStringOffset(LenMnemonic, false)); } @@ -2822,8 +2763,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << " ConvertFn;\n"; OS << " " << getMinimalRequiredFeaturesType(Info) << " RequiredFeatures;\n"; - OS << " " << getMinimalTypeForRange(Info.Classes.size()) - << " Classes[" << MaxNumOperands << "];\n"; + OS << " " << getMinimalTypeForRange( + std::distance(Info.Classes.begin(), Info.Classes.end())) + << " Classes[" << MaxNumOperands << "];\n"; OS << " StringRef getMnemonic() const {\n"; OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; OS << " MnemonicTable[Mnemonic]);\n"; @@ -2852,33 +2794,30 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "static const MatchEntry MatchTable" << VC << "[] = {\n"; - for (std::vector<MatchableInfo*>::const_iterator it = - Info.Matchables.begin(), ie = Info.Matchables.end(); - it != ie; ++it) { - MatchableInfo &II = **it; - if (II.AsmVariantID != AsmVariantNo) + for (const auto &MI : Info.Matchables) { + if (MI->AsmVariantID != AsmVariantNo) continue; // Store a pascal-style length byte in the mnemonic. - std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); + std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str(); OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false) - << " /* " << II.Mnemonic << " */, " + << " /* " << MI->Mnemonic << " */, " << Target.getName() << "::" - << II.getResultInst()->TheDef->getName() << ", " - << II.ConversionFnKind << ", "; + << MI->getResultInst()->TheDef->getName() << ", " + << MI->ConversionFnKind << ", "; // Write the required features mask. - if (!II.RequiredFeatures.empty()) { - for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) { + if (!MI->RequiredFeatures.empty()) { + for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) { if (i) OS << "|"; - OS << II.RequiredFeatures[i]->getEnumName(); + OS << MI->RequiredFeatures[i]->getEnumName(); } } else OS << "0"; OS << ", { "; - for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { - MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; + for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) { + const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i]; if (i) OS << ", "; OS << Op.Class->Name; @@ -2895,7 +2834,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " // Find the appropriate table for this asm variant.\n"; OS << " const MatchEntry *Start, *End;\n"; OS << " switch (VariantID) {\n"; - OS << " default: // unreachable\n"; + OS << " default: llvm_unreachable(\"invalid variant!\");\n"; for (unsigned VC = 0; VC != VariantCount; ++VC) { Record *AsmVariant = Target.getAsmParserVariant(VC); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); @@ -2911,10 +2850,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Finally, build the match function. OS << "unsigned " << Target.getName() << ClassName << "::\n" - << "MatchInstructionImpl(const OperandVector" - << " &Operands,\n"; - OS << " MCInst &Inst,\n" - << "uint64_t &ErrorInfo, bool matchingInlineAsm, unsigned VariantID) {\n"; + << "MatchInstructionImpl(const OperandVector &Operands,\n"; + OS << " MCInst &Inst, uint64_t &ErrorInfo,\n" + << " bool matchingInlineAsm, unsigned VariantID) {\n"; OS << " // Eliminate obvious mismatches.\n"; OS << " if (Operands.size() > " << (MaxNumOperands+1) << ") {\n"; @@ -2949,7 +2887,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " // Find the appropriate table for this asm variant.\n"; OS << " const MatchEntry *Start, *End;\n"; OS << " switch (VariantID) {\n"; - OS << " default: // unreachable\n"; + OS << " default: llvm_unreachable(\"invalid variant!\");\n"; for (unsigned VC = 0; VC != VariantCount; ++VC) { Record *AsmVariant = Target.getAsmParserVariant(VC); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); @@ -3018,12 +2956,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " HadMatchOtherThanFeatures = true;\n"; OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & " "~AvailableFeatures;\n"; - OS << " if (CountPopulation_64(NewMissingFeatures) <=\n" - " CountPopulation_64(MissingFeatures))\n"; + OS << " if (countPopulation(NewMissingFeatures) <=\n" + " countPopulation(MissingFeatures))\n"; OS << " MissingFeatures = NewMissingFeatures;\n"; OS << " continue;\n"; OS << " }\n"; OS << "\n"; + OS << " Inst.clear();\n\n"; OS << " if (matchingInlineAsm) {\n"; OS << " Inst.setOpcode(it->Opcode);\n"; OS << " convertToMapAndConstraints(it->ConvertFn, Operands);\n"; @@ -3072,7 +3011,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " return Match_MissingFeature;\n"; OS << "}\n\n"; - if (Info.OperandMatchInfo.size()) + if (!Info.OperandMatchInfo.empty()) emitCustomOperandParsing(OS, Target, Info, ClassName, StringTable, MaxMnemonicIndex); |