@@ -44,13 +44,27 @@ static int64_t getInt(const Record *R, StringRef Field) {
4444
4545namespace {
4646struct GenericEnum {
47- using Entry = std::pair<StringRef, int64_t >;
47+ struct Entry {
48+ StringRef Name;
49+ int64_t Value;
50+ const Record *Def;
51+ Entry (StringRef N, int64_t V, const Record *D)
52+ : Name(N), Value(V), Def(D) {}
53+ };
4854
4955 std::string Name;
5056 const Record *Class = nullptr ;
5157 std::string PreprocessorGuard;
52- std::vector<std::unique_ptr<Entry>> Entries;
53- DenseMap<const Record *, Entry *> EntryMap;
58+ std::vector<Entry> Entries;
59+ // Map from a Record to an index into the `Entries` vector.
60+ DenseMap<const Record *, uint32_t > EntryMap;
61+
62+ const Entry *getEntry (const Record *Def) const {
63+ auto II = EntryMap.find (Def);
64+ if (II == EntryMap.end ())
65+ return nullptr ;
66+ return &Entries[II->second ];
67+ }
5468};
5569
5670struct GenericField {
@@ -129,11 +143,12 @@ class SearchableTableEmitter {
129143 else if (Field.IsInstruction )
130144 return I->getAsString ();
131145 else if (Field.Enum ) {
132- auto *Entry = Field.Enum ->EntryMap [cast<DefInit>(I)->getDef ()];
146+ const GenericEnum::Entry *Entry =
147+ Field.Enum ->getEntry (cast<DefInit>(I)->getDef ());
133148 if (!Entry)
134149 PrintFatalError (Loc,
135150 Twine (" Entry for field '" ) + Field.Name + " ' is null" );
136- return Entry->first .str ();
151+ return Entry->Name .str ();
137152 }
138153 PrintFatalError (Loc, Twine (" invalid field type for field '" ) + Field.Name +
139154 " '; expected: bit, bits, string, or code" );
@@ -221,7 +236,7 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
221236 }
222237 if (Field.Enum ) {
223238 const Record *EnumEntry = Rec->getValueAsDef (Field.Name );
224- return Field.Enum ->EntryMap [ EnumEntry]-> second ;
239+ return Field.Enum ->getEntry ( EnumEntry)-> Value ;
225240 }
226241 assert (isa<BitsRecTy>(Field.RecType ) && " unexpected field type" );
227242
@@ -272,8 +287,8 @@ bool SearchableTableEmitter::compareBy(const Record *LHS, const Record *RHS,
272287 } else if (Field.Enum ) {
273288 auto LHSr = cast<DefInit>(LHSI)->getDef ();
274289 auto RHSr = cast<DefInit>(RHSI)->getDef ();
275- int64_t LHSv = Field.Enum ->EntryMap [ LHSr]-> second ;
276- int64_t RHSv = Field.Enum ->EntryMap [ RHSr]-> second ;
290+ int64_t LHSv = Field.Enum ->getEntry ( LHSr)-> Value ;
291+ int64_t RHSv = Field.Enum ->getEntry ( RHSr)-> Value ;
277292 if (LHSv < RHSv)
278293 return true ;
279294 if (LHSv > RHSv)
@@ -308,8 +323,8 @@ void SearchableTableEmitter::emitGenericEnum(const GenericEnum &Enum,
308323 emitIfdef ((Twine (" GET_" ) + Enum.PreprocessorGuard + " _DECL" ).str (), OS);
309324
310325 OS << " enum " << Enum.Name << " {\n " ;
311- for (const auto &Entry : Enum.Entries )
312- OS << " " << Entry-> first << " = " << Entry-> second << " ,\n " ;
326+ for (const auto &[Name, Value, _] : Enum.Entries )
327+ OS << " " << Name << " = " << Value << " ,\n " ;
313328 OS << " };\n " ;
314329
315330 OS << " #endif\n\n " ;
@@ -625,31 +640,29 @@ std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex(
625640void SearchableTableEmitter::collectEnumEntries (
626641 GenericEnum &Enum, StringRef NameField, StringRef ValueField,
627642 ArrayRef<const Record *> Items) {
643+ Enum.Entries .reserve (Items.size ());
628644 for (const Record *EntryRec : Items) {
629- StringRef Name;
630- if (NameField.empty ())
631- Name = EntryRec->getName ();
632- else
633- Name = EntryRec->getValueAsString (NameField);
634-
635- int64_t Value = 0 ;
636- if (!ValueField.empty ())
637- Value = getInt (EntryRec, ValueField);
638-
639- Enum.Entries .push_back (std::make_unique<GenericEnum::Entry>(Name, Value));
640- Enum.EntryMap .try_emplace (EntryRec, Enum.Entries .back ().get ());
645+ StringRef Name = NameField.empty () ? EntryRec->getName ()
646+ : EntryRec->getValueAsString (NameField);
647+ int64_t Value = ValueField.empty () ? 0 : getInt (EntryRec, ValueField);
648+ Enum.Entries .emplace_back (Name, Value, EntryRec);
641649 }
642650
651+ // If no values are provided for enums, assign values in the order of sorted
652+ // enum names.
643653 if (ValueField.empty ()) {
644- llvm::stable_sort (Enum.Entries ,
645- [](const std::unique_ptr<GenericEnum::Entry> &LHS,
646- const std::unique_ptr<GenericEnum::Entry> &RHS) {
647- return LHS->first < RHS->first ;
648- });
654+ llvm::stable_sort (Enum.Entries , [](const GenericEnum::Entry &LHS,
655+ const GenericEnum::Entry &RHS) {
656+ return LHS.Name < RHS.Name ;
657+ });
649658
650- for (size_t i = 0 ; i < Enum.Entries . size (); ++i )
651- Enum. Entries [i]-> second = i ;
659+ for (auto [Idx, Entry] : enumerate( Enum.Entries ) )
660+ Entry. Value = Idx ;
652661 }
662+
663+ // Populate the entry map after the `Entries` vector is finalized.
664+ for (auto [Idx, Entry] : enumerate(Enum.Entries ))
665+ Enum.EntryMap .try_emplace (Entry.Def , Idx);
653666}
654667
655668void SearchableTableEmitter::collectTableEntries (
0 commit comments