diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -1955,8 +1955,11 @@ } void addDef(std::unique_ptr R) { - bool Ins = Defs.insert(std::make_pair(std::string(R->getName()), - std::move(R))).second; + Defs2.push_back(R.get()); + + bool Ins = + Defs.insert(std::make_pair(std::string(R->getName()), std::move(R))) + .second; (void)Ins; assert(Ins && "Record already exists"); } @@ -1997,19 +2000,27 @@ //===--------------------------------------------------------------------===// // High-level helper methods, useful for tablegen backends. + enum SortOrder { + None = 0, // Registration order + Numeric, + Char, + }; + /// Get all the concrete records that inherit from the one specified /// class. The class must be defined. - std::vector getAllDerivedDefinitions(StringRef ClassName) const; + std::vector getAllDerivedDefinitions(StringRef ClassName, + SortOrder Order = None) const; /// Get all the concrete records that inherit from all the specified /// classes. The classes must be defined. - std::vector getAllDerivedDefinitions( - ArrayRef ClassNames) const; + std::vector getAllDerivedDefinitions(ArrayRef ClassNames, + SortOrder Order = None) const; /// Get all the concrete records that inherit from specified class, if the /// class is defined. Returns an empty vector if the class is not defined. std::vector - getAllDerivedDefinitionsIfDefined(StringRef ClassName) const; + getAllDerivedDefinitionsIfDefined(StringRef ClassName, + SortOrder Order = None) const; void dump() const; @@ -2021,7 +2032,8 @@ std::string InputFilename; RecordMap Classes, Defs; - mutable StringMap> ClassRecordsMap; + std::vector Defs2; + mutable std::array>, 3> ClassRecordsMap; GlobalMap ExtraGlobals; // These members are for the phase timing feature. We need a timer group, diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -2976,18 +2976,20 @@ } std::vector -RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { +RecordKeeper::getAllDerivedDefinitions(StringRef ClassName, + SortOrder Order) const { // We cache the record vectors for single classes. Many backends request // the same vectors multiple times. - auto Pair = ClassRecordsMap.try_emplace(ClassName); + auto Pair = ClassRecordsMap[int(Order)].try_emplace(ClassName); if (Pair.second) - Pair.first->second = getAllDerivedDefinitions(ArrayRef(ClassName)); + Pair.first->second = getAllDerivedDefinitions(ArrayRef(ClassName), Order); return Pair.first->second; } -std::vector RecordKeeper::getAllDerivedDefinitions( - ArrayRef ClassNames) const { +std::vector +RecordKeeper::getAllDerivedDefinitions(ArrayRef ClassNames, + SortOrder Order) const { SmallVector ClassRecs; std::vector Defs; @@ -2999,19 +3001,35 @@ ClassRecs.push_back(Class); } - for (const auto &OneDef : getDefs()) { + for (auto *OneDef : Defs2) { if (all_of(ClassRecs, [&OneDef](const Record *Class) { - return OneDef.second->isSubClassOf(Class); - })) - Defs.push_back(OneDef.second.get()); + return OneDef->isSubClassOf(Class); + })) + Defs.push_back(OneDef); + } + + switch (Order) { + case None: + break; + case Numeric: + llvm::sort(Defs, [](Record *LHS, Record *RHS) { + return LHS->getName().compare_numeric(RHS->getName()) < 0; + }); + break; + case Char: + llvm::sort(Defs, [](Record *LHS, Record *RHS) { + return LHS->getName() < RHS->getName(); + }); + break; } return Defs; } std::vector -RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName) const { - return getClass(ClassName) ? getAllDerivedDefinitions(ClassName) +RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName, + SortOrder Order) const { + return getClass(ClassName) ? getAllDerivedDefinitions(ClassName, Order) : std::vector(); } diff --git a/llvm/utils/TableGen/Attributes.cpp b/llvm/utils/TableGen/Attributes.cpp --- a/llvm/utils/TableGen/Attributes.cpp +++ b/llvm/utils/TableGen/Attributes.cpp @@ -64,7 +64,8 @@ unsigned Value = 1; // Leave zero for AttrKind::None. for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) { OS << "First" << KindName << " = " << Value << ",\n"; - for (auto *A : Records.getAllDerivedDefinitions(KindName)) { + for (auto *A : + Records.getAllDerivedDefinitions(KindName, RecordKeeper::Numeric)) { OS << A->getName() << " = " << Value << ",\n"; Value++; } @@ -113,7 +114,8 @@ OS << "#undef GET_ATTR_PROP_TABLE\n"; OS << "static const uint8_t AttrPropTable[] = {\n"; for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) { - for (auto *A : Records.getAllDerivedDefinitions(KindName)) { + for (auto *A : + Records.getAllDerivedDefinitions(KindName, RecordKeeper::Numeric)) { OS << "0"; for (Init *P : *A->getValueAsListInit("Properties")) OS << " | AttributeProperty::" << cast(P)->getDef()->getName(); diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -3272,7 +3272,8 @@ /// inside a pattern fragment to a pattern fragment. /// void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) { - std::vector Fragments = Records.getAllDerivedDefinitions("PatFrags"); + std::vector Fragments = + Records.getAllDerivedDefinitions("PatFrags", RecordKeeper::Numeric); // First step, parse all of the fragments. for (Record *Frag : Fragments) { diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp --- a/llvm/utils/TableGen/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/CodeGenRegisters.cpp @@ -1174,8 +1174,8 @@ getReg(Regs[i]); // Expand tuples and number the new registers. - std::vector Tups = - Records.getAllDerivedDefinitions("RegisterTuples"); + std::vector Tups = + Records.getAllDerivedDefinitions("RegisterTuples", RecordKeeper::Char); for (Record *R : Tups) { std::vector TupRegs = *Sets.expand(R); @@ -1240,7 +1240,8 @@ NumNativeRegUnits = RegUnits.size(); // Read in register class definitions. - std::vector RCs = Records.getAllDerivedDefinitions("RegisterClass"); + std::vector RCs = + Records.getAllDerivedDefinitions("RegisterClass", RecordKeeper::Numeric); if (RCs.empty()) PrintFatalError("No 'RegisterClass' subclasses defined!"); diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp --- a/llvm/utils/TableGen/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/CodeGenSchedule.cpp @@ -1836,7 +1836,8 @@ // Collect all the RegisterFile definitions available in this target. void CodeGenSchedModels::collectRegisterFiles() { - RecVec RegisterFileDefs = Records.getAllDerivedDefinitions("RegisterFile"); + RecVec RegisterFileDefs = + Records.getAllDerivedDefinitions("RegisterFile", RecordKeeper::Numeric); // RegisterFiles is the vector of CodeGenRegisterFile. for (Record *RF : RegisterFileDefs) { diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -5552,7 +5552,7 @@ StringRef AdditionalDeclarations, std::function Filter) { std::vector MatchedRecords; - const auto &Defs = RK.getAllDerivedDefinitions("PatFrags"); + auto Defs = RK.getAllDerivedDefinitions("PatFrags", RecordKeeper::Numeric); std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords), [&](Record *Record) { return !Record->getValueAsString(CodeFieldName).empty() && diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp --- a/llvm/utils/TableGen/RegisterBankEmitter.cpp +++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp @@ -279,7 +279,8 @@ Records.startTimer("Analyze records"); std::vector Banks; - for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) { + for (const auto &V : Records.getAllDerivedDefinitions( + "RegisterBank", RecordKeeper::Numeric)) { SmallPtrSet VisitedRCs; RegisterBank Bank(*V); diff --git a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp --- a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp +++ b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp @@ -24,7 +24,7 @@ SubtargetFeatureInfo::getAll(const RecordKeeper &Records) { std::vector> SubtargetFeatures; std::vector AllPredicates = - Records.getAllDerivedDefinitions("Predicate"); + Records.getAllDerivedDefinitions("Predicate", RecordKeeper::Numeric); for (Record *Pred : AllPredicates) { // Ignore predicates that are not intended for the assembler. //