@@ -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" );
@@ -180,6 +195,7 @@ class SearchableTableEmitter {
180
195
return " bool" ;
181
196
} else if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction )
182
197
return " unsigned" ;
198
+
183
199
PrintFatalError (Index.Loc ,
184
200
Twine (" In table '" ) + Table.Name + " ' lookup method '" +
185
201
Index.Name + " ', key field '" + Field.Name +
@@ -221,7 +237,7 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
221
237
}
222
238
if (Field.Enum ) {
223
239
const Record *EnumEntry = Rec->getValueAsDef (Field.Name );
224
- return Field.Enum ->EntryMap [ EnumEntry]-> second ;
240
+ return Field.Enum ->getEntry ( EnumEntry)-> Value ;
225
241
}
226
242
assert (isa<BitsRecTy>(Field.RecType ) && " unexpected field type" );
227
243
@@ -272,8 +288,8 @@ bool SearchableTableEmitter::compareBy(const Record *LHS, const Record *RHS,
272
288
} else if (Field.Enum ) {
273
289
auto LHSr = cast<DefInit>(LHSI)->getDef ();
274
290
auto RHSr = cast<DefInit>(RHSI)->getDef ();
275
- int64_t LHSv = Field.Enum ->EntryMap [ LHSr]-> second ;
276
- int64_t RHSv = Field.Enum ->EntryMap [ RHSr]-> second ;
291
+ int64_t LHSv = Field.Enum ->getEntry ( LHSr)-> Value ;
292
+ int64_t RHSv = Field.Enum ->getEntry ( RHSr)-> Value ;
277
293
if (LHSv < RHSv)
278
294
return true ;
279
295
if (LHSv > RHSv)
@@ -308,8 +324,8 @@ void SearchableTableEmitter::emitGenericEnum(const GenericEnum &Enum,
308
324
emitIfdef ((Twine (" GET_" ) + Enum.PreprocessorGuard + " _DECL" ).str (), OS);
309
325
310
326
OS << " enum " << Enum.Name << " {\n " ;
311
- for (const auto &Entry : Enum.Entries )
312
- OS << " " << Entry-> first << " = " << Entry-> second << " ,\n " ;
327
+ for (const auto &[Name, Value, _] : Enum.Entries )
328
+ OS << " " << Name << " = " << Value << " ,\n " ;
313
329
OS << " };\n " ;
314
330
315
331
OS << " #endif\n\n " ;
@@ -625,31 +641,29 @@ std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex(
625
641
void SearchableTableEmitter::collectEnumEntries (
626
642
GenericEnum &Enum, StringRef NameField, StringRef ValueField,
627
643
ArrayRef<const Record *> Items) {
644
+ Enum.Entries .reserve (Items.size ());
628
645
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 ());
646
+ StringRef Name = NameField.empty () ? EntryRec->getName ()
647
+ : EntryRec->getValueAsString (NameField);
648
+ int64_t Value = ValueField.empty () ? 0 : getInt (EntryRec, ValueField);
649
+ Enum.Entries .emplace_back (Name, Value, EntryRec);
641
650
}
642
651
652
+ // If no values are provided for enums, assign values in the order of sorted
653
+ // enum names.
643
654
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
- });
655
+ llvm::stable_sort (Enum.Entries , [](const GenericEnum::Entry &LHS,
656
+ const GenericEnum::Entry &RHS) {
657
+ return LHS.Name < RHS.Name ;
658
+ });
649
659
650
- for (size_t i = 0 ; i < Enum.Entries . size (); ++i )
651
- Enum. Entries [i]-> second = i ;
660
+ for (auto [Idx, Entry] : enumerate( Enum.Entries ) )
661
+ Entry. Value = Idx ;
652
662
}
663
+
664
+ // Populate the entry map after the `Entries` vector is finalized.
665
+ for (auto [Idx, Entry] : enumerate(Enum.Entries ))
666
+ Enum.EntryMap .try_emplace (Entry.Def , Idx);
653
667
}
654
668
655
669
void SearchableTableEmitter::collectTableEntries (
0 commit comments