@@ -44,13 +44,27 @@ static int64_t getInt(const Record *R, StringRef Field) {
44
44
45
45
namespace {
46
46
struct 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
+ };
48
54
49
55
std::string Name;
50
56
const Record *Class = nullptr ;
51
57
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
+ }
54
68
};
55
69
56
70
struct GenericField {
@@ -129,11 +143,12 @@ class SearchableTableEmitter {
129
143
else if (Field.IsInstruction )
130
144
return I->getAsString ();
131
145
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 ());
133
148
if (!Entry)
134
149
PrintFatalError (Loc,
135
150
Twine (" Entry for field '" ) + Field.Name + " ' is null" );
136
- return Entry->first .str ();
151
+ return Entry->Name .str ();
137
152
}
138
153
PrintFatalError (Loc, Twine (" invalid field type for field '" ) + Field.Name +
139
154
" '; expected: bit, bits, string, or code" );
@@ -221,7 +236,7 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
221
236
}
222
237
if (Field.Enum ) {
223
238
const Record *EnumEntry = Rec->getValueAsDef (Field.Name );
224
- return Field.Enum ->EntryMap [ EnumEntry]-> second ;
239
+ return Field.Enum ->getEntry ( EnumEntry)-> Value ;
225
240
}
226
241
assert (isa<BitsRecTy>(Field.RecType ) && " unexpected field type" );
227
242
@@ -272,8 +287,8 @@ bool SearchableTableEmitter::compareBy(const Record *LHS, const Record *RHS,
272
287
} else if (Field.Enum ) {
273
288
auto LHSr = cast<DefInit>(LHSI)->getDef ();
274
289
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 ;
277
292
if (LHSv < RHSv)
278
293
return true ;
279
294
if (LHSv > RHSv)
@@ -308,8 +323,8 @@ void SearchableTableEmitter::emitGenericEnum(const GenericEnum &Enum,
308
323
emitIfdef ((Twine (" GET_" ) + Enum.PreprocessorGuard + " _DECL" ).str (), OS);
309
324
310
325
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 " ;
313
328
OS << " };\n " ;
314
329
315
330
OS << " #endif\n\n " ;
@@ -625,31 +640,29 @@ std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex(
625
640
void SearchableTableEmitter::collectEnumEntries (
626
641
GenericEnum &Enum, StringRef NameField, StringRef ValueField,
627
642
ArrayRef<const Record *> Items) {
643
+ Enum.Entries .reserve (Items.size ());
628
644
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);
641
649
}
642
650
651
+ // If no values are provided for enums, assign values in the order of sorted
652
+ // enum names.
643
653
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
+ });
649
658
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 ;
652
661
}
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);
653
666
}
654
667
655
668
void SearchableTableEmitter::collectTableEntries (
0 commit comments