@@ -32,9 +32,9 @@ using namespace llvm;
32
32
#define DEBUG_TYPE " searchable-table-emitter"
33
33
34
34
static int64_t getAsInt (const Init *B) {
35
- if (const BitsInit *BI = dyn_cast<BitsInit>(B))
35
+ if (const auto *BI = dyn_cast<BitsInit>(B))
36
36
return *BI->convertInitializerToInt ();
37
- if (const IntInit *II = dyn_cast<IntInit>(B))
37
+ if (const auto *II = dyn_cast<IntInit>(B))
38
38
return II->getValue ();
39
39
llvm_unreachable (" Unexpected initializer" );
40
40
}
@@ -126,20 +126,21 @@ class SearchableTableEmitter {
126
126
127
127
std::string primaryRepresentation (SMLoc Loc, const GenericField &Field,
128
128
const Init *I) {
129
- if (const StringInit *SI = dyn_cast<StringInit>(I)) {
129
+ if (const auto *SI = dyn_cast<StringInit>(I)) {
130
130
if (Field.IsCode || SI->hasCodeFormat ())
131
131
return SI->getValue ().str ();
132
132
else
133
133
return SI->getAsString ();
134
- } else if (const BitsInit *BI = dyn_cast<BitsInit>(I))
134
+ }
135
+ if (const auto *BI = dyn_cast<BitsInit>(I))
135
136
return " 0x" + utohexstr (getAsInt (BI));
136
- else if (const BitInit *BI = dyn_cast<BitInit>(I))
137
+ if (const auto *BI = dyn_cast<BitInit>(I))
137
138
return BI->getValue () ? " true" : " false" ;
138
- else if (Field.IsIntrinsic )
139
+ if (Field.IsIntrinsic )
139
140
return " Intrinsic::" + getIntrinsic (I).EnumName .str ();
140
- else if (Field.IsInstruction )
141
+ if (Field.IsInstruction )
141
142
return I->getAsString ();
142
- else if (Field.Enum ) {
143
+ if (Field.Enum ) {
143
144
const GenericEnum::Entry *Entry =
144
145
Field.Enum ->getEntry (cast<DefInit>(I)->getDef ());
145
146
if (!Entry)
@@ -152,7 +153,7 @@ class SearchableTableEmitter {
152
153
}
153
154
154
155
bool isIntrinsic (const Init *I) {
155
- if (const DefInit *DI = dyn_cast<DefInit>(I))
156
+ if (const auto *DI = dyn_cast<DefInit>(I))
156
157
return DI->getDef ()->isSubClassOf (" Intrinsic" );
157
158
return false ;
158
159
}
@@ -174,7 +175,8 @@ class SearchableTableEmitter {
174
175
if (Ctx == TypeInTempStruct)
175
176
return " std::string" ;
176
177
return " StringRef" ;
177
- } else if (const BitsRecTy *BI = dyn_cast<BitsRecTy>(Field.RecType )) {
178
+ }
179
+ if (const auto *BI = dyn_cast<BitsRecTy>(Field.RecType )) {
178
180
unsigned NumBits = BI->getNumBits ();
179
181
if (NumBits <= 8 )
180
182
return " uint8_t" ;
@@ -188,9 +190,10 @@ class SearchableTableEmitter {
188
190
" ' lookup method '" + Index.Name +
189
191
" ', key field '" + Field.Name +
190
192
" ' of type bits is too large" );
191
- } else if (isa<BitRecTy>(Field.RecType )) {
193
+ }
194
+ if (isa<BitRecTy>(Field.RecType ))
192
195
return " bool" ;
193
- } else if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction )
196
+ if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction )
194
197
return " unsigned" ;
195
198
PrintFatalError (Index.Loc ,
196
199
Twine (" In table '" ) + Table.Name + " ' lookup method '" +
@@ -244,67 +247,81 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
244
247
// / key of \p Index.
245
248
bool SearchableTableEmitter::compareBy (const Record *LHS, const Record *RHS,
246
249
const SearchIndex &Index) {
247
- for (const auto &Field : Index.Fields ) {
248
- const Init *LHSI = LHS->getValueInit (Field.Name );
249
- const Init *RHSI = RHS->getValueInit (Field.Name );
250
+ // Compare two values and return:
251
+ // * -1 if LHS < RHS.
252
+ // * 1 if LHS > RHS.
253
+ // * 0 if LHS == RHS.
254
+ auto CmpLTValue = [](const auto &LHS, const auto &RHS) -> int {
255
+ if (LHS < RHS)
256
+ return -1 ;
257
+ if (LHS > RHS)
258
+ return 1 ;
259
+ return 0 ;
260
+ };
261
+
262
+ // Specialized form of `CmpLTValue` for string-like types that uses compare()
263
+ // to do the comparison of the 2 strings once (instead if 2 comparisons if we
264
+ // use `CmpLTValue`).
265
+ auto CmpLTString = [](StringRef LHS, StringRef RHS) -> int {
266
+ return LHS.compare (RHS);
267
+ };
250
268
269
+ // Compare two fields and returns:
270
+ // - true if LHS < RHS.
271
+ // - false if LHS > RHS.
272
+ // - std::nullopt if LHS == RHS.
273
+ auto CmpLTField = [this , &Index, &CmpLTValue,
274
+ &CmpLTString](const Init *LHSI, const Init *RHSI,
275
+ const GenericField &Field) -> int {
251
276
if (isa<BitsRecTy>(Field.RecType ) || isa<IntRecTy>(Field.RecType )) {
252
277
int64_t LHSi = getAsInt (LHSI);
253
278
int64_t RHSi = getAsInt (RHSI);
254
- if (LHSi < RHSi)
255
- return true ;
256
- if (LHSi > RHSi)
257
- return false ;
258
- } else if (Field.IsIntrinsic ) {
279
+ return CmpLTValue (LHSi, RHSi);
280
+ }
281
+
282
+ if (Field.IsIntrinsic ) {
259
283
const CodeGenIntrinsic &LHSi = getIntrinsic (LHSI);
260
284
const CodeGenIntrinsic &RHSi = getIntrinsic (RHSI);
261
- if (std::tie (LHSi.TargetPrefix , LHSi.Name ) <
262
- std::tie (RHSi.TargetPrefix , RHSi.Name ))
263
- return true ;
264
- if (std::tie (LHSi.TargetPrefix , LHSi.Name ) >
265
- std::tie (RHSi.TargetPrefix , RHSi.Name ))
266
- return false ;
267
- } else if (Field.IsInstruction ) {
285
+ if (int Cmp = CmpLTString (LHSi.TargetPrefix , RHSi.TargetPrefix ))
286
+ return Cmp;
287
+ return CmpLTString (LHSi.Name , RHSi.Name );
288
+ }
289
+
290
+ if (Field.IsInstruction ) {
268
291
// This does not correctly compare the predefined instructions!
269
292
const Record *LHSr = cast<DefInit>(LHSI)->getDef ();
270
293
const Record *RHSr = cast<DefInit>(RHSI)->getDef ();
271
294
272
- bool LHSpseudo = LHSr->getValueAsBit (" isPseudo" );
273
- bool RHSpseudo = RHSr->getValueAsBit (" isPseudo" );
274
- if (LHSpseudo && !RHSpseudo)
275
- return true ;
276
- if (!LHSpseudo && RHSpseudo)
277
- return false ;
295
+ // Order pseudo instructions before non-pseudo ones.
296
+ bool LHSNotPseudo = !LHSr->getValueAsBit (" isPseudo" );
297
+ bool RHSNotPseudo = !RHSr->getValueAsBit (" isPseudo" );
298
+ if (int Cmp = CmpLTValue (LHSNotPseudo, RHSNotPseudo))
299
+ return Cmp;
300
+ return CmpLTString (LHSr->getName (), RHSr->getName ());
301
+ }
278
302
279
- int comp = LHSr->getName ().compare (RHSr->getName ());
280
- if (comp < 0 )
281
- return true ;
282
- if (comp > 0 )
283
- return false ;
284
- } else if (Field.Enum ) {
285
- auto LHSr = cast<DefInit>(LHSI)->getDef ();
286
- auto RHSr = cast<DefInit>(RHSI)->getDef ();
303
+ if (Field.Enum ) {
304
+ const Record *LHSr = cast<DefInit>(LHSI)->getDef ();
305
+ const Record *RHSr = cast<DefInit>(RHSI)->getDef ();
287
306
int64_t LHSv = Field.Enum ->getEntry (LHSr)->Value ;
288
307
int64_t RHSv = Field.Enum ->getEntry (RHSr)->Value ;
289
- if (LHSv < RHSv)
290
- return true ;
291
- if (LHSv > RHSv)
292
- return false ;
293
- } else {
294
- std::string LHSs = primaryRepresentation (Index.Loc , Field, LHSI);
295
- std::string RHSs = primaryRepresentation (Index.Loc , Field, RHSI);
296
-
297
- if (isa<StringRecTy>(Field.RecType )) {
298
- LHSs = StringRef (LHSs).upper ();
299
- RHSs = StringRef (RHSs).upper ();
300
- }
308
+ return CmpLTValue (LHSv, RHSv);
309
+ }
301
310
302
- int comp = LHSs. compare (RHSs );
303
- if (comp < 0 )
304
- return true ;
305
- if (comp > 0 )
306
- return false ;
311
+ std::string LHSs = primaryRepresentation (Index. Loc , Field, LHSI );
312
+ std::string RHSs = primaryRepresentation (Index. Loc , Field, RHSI);
313
+ if (isa<StringRecTy>(Field. RecType )) {
314
+ LHSs = StringRef (LHSs). upper ();
315
+ RHSs = StringRef (RHSs). upper () ;
307
316
}
317
+ return CmpLTString (LHSs, RHSs);
318
+ };
319
+
320
+ for (const GenericField &Field : Index.Fields ) {
321
+ const Init *LHSI = LHS->getValueInit (Field.Name );
322
+ const Init *RHSI = RHS->getValueInit (Field.Name );
323
+ if (int Cmp = CmpLTField (LHSI, RHSI, Field))
324
+ return Cmp < 0 ;
308
325
}
309
326
return false ;
310
327
}
@@ -359,8 +376,8 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
359
376
360
377
std::vector<std::pair<const Record *, unsigned >> Entries;
361
378
Entries.reserve (Table.Entries .size ());
362
- for (unsigned i = 0 ; i < Table.Entries . size (); ++i )
363
- Entries.emplace_back (Table. Entries [i], i );
379
+ for (auto [Idx, TblEntry] : enumerate( Table.Entries ) )
380
+ Entries.emplace_back (TblEntry, Idx );
364
381
365
382
llvm::stable_sort (Entries,
366
383
[&](const std::pair<const Record *, unsigned > &LHS,
@@ -369,19 +386,19 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
369
386
});
370
387
371
388
IndexRowsStorage.reserve (Entries.size ());
372
- for (const auto &Entry : Entries) {
373
- IndexRowsStorage.push_back (Entry. first );
389
+ for (const auto &[EntryRec, EntryIndex] : Entries) {
390
+ IndexRowsStorage.push_back (EntryRec );
374
391
375
392
OS << " { " ;
376
393
ListSeparator LS;
377
394
for (const auto &Field : Index.Fields ) {
378
395
std::string Repr = primaryRepresentation (
379
- Index.Loc , Field, Entry. first ->getValueInit (Field.Name ));
396
+ Index.Loc , Field, EntryRec ->getValueInit (Field.Name ));
380
397
if (isa<StringRecTy>(Field.RecType ))
381
398
Repr = StringRef (Repr).upper ();
382
399
OS << LS << Repr;
383
400
}
384
- OS << " , " << Entry. second << " },\n " ;
401
+ OS << " , " << EntryIndex << " },\n " ;
385
402
}
386
403
387
404
OS << " };\n\n " ;
@@ -398,8 +415,8 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
398
415
Index.Fields [0 ].IsInstruction )) {
399
416
int64_t FirstKeyVal = getNumericKey (Index, IndexRows[0 ]);
400
417
IsContiguous = true ;
401
- for (unsigned i = 0 ; i < IndexRows. size (); ++i ) {
402
- if (getNumericKey (Index, IndexRows[i] ) != ( FirstKeyVal + i) ) {
418
+ for (const auto &[Idx, IndexRow] : enumerate(IndexRows) ) {
419
+ if (getNumericKey (Index, IndexRow ) != FirstKeyVal + ( int64_t )Idx ) {
403
420
IsContiguous = false ;
404
421
break ;
405
422
}
@@ -509,9 +526,9 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
509
526
OS << " ||\n Key." << Field.Name << " != Idx->" << Field.Name ;
510
527
}
511
528
512
- if (ShouldReturnRange)
529
+ if (ShouldReturnRange) {
513
530
OS << " return llvm::make_range(It.first, It.second);\n " ;
514
- else if (IsPrimary) {
531
+ } else if (IsPrimary) {
515
532
OS << " )\n return nullptr;\n\n " ;
516
533
OS << " return &*Idx;\n " ;
517
534
} else {
@@ -557,8 +574,7 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
557
574
558
575
// The primary data table contains all the fields defined for this map.
559
576
OS << " constexpr " << Table.CppTypeName << " " << Table.Name << " [] = {\n " ;
560
- for (unsigned i = 0 ; i < Table.Entries .size (); ++i) {
561
- const Record *Entry = Table.Entries [i];
577
+ for (const auto &[Idx, Entry] : enumerate(Table.Entries )) {
562
578
OS << " { " ;
563
579
564
580
ListSeparator LS;
@@ -567,7 +583,7 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
567
583
<< primaryRepresentation (Table.Locs [0 ], Field,
568
584
Entry->getValueInit (Field.Name ));
569
585
570
- OS << " }, // " << i << " \n " ;
586
+ OS << " }, // " << Idx << " \n " ;
571
587
}
572
588
OS << " };\n " ;
573
589
0 commit comments