78
78
#include " Common/CodeGenInstruction.h"
79
79
#include " Common/CodeGenTarget.h"
80
80
#include " TableGenBackends.h"
81
+ #include " llvm/ADT/SetVector.h"
81
82
#include " llvm/ADT/StringExtras.h"
82
83
#include " llvm/TableGen/Error.h"
83
84
#include " llvm/TableGen/Record.h"
@@ -361,45 +362,38 @@ unsigned MapTableEmitter::emitBinSearchTable(raw_ostream &OS) {
361
362
StringRef Namespace = Target.getInstNamespace ();
362
363
ArrayRef<const ListInit *> ValueCols = InstrMapDesc.getValueCols ();
363
364
unsigned NumCol = ValueCols.size ();
364
- unsigned TotalNumInstr = NumberedInstructions.size ();
365
365
unsigned TableSize = 0 ;
366
366
367
- OS << " static const uint16_t " << InstrMapDesc. getName () ;
367
+ OS << " using namespace " << Namespace << " ; \n " ;
368
368
// Number of columns in the table are NumCol+1 because key instructions are
369
369
// emitted as first column.
370
- OS << " Table[][" << NumCol + 1 << " ] = {\n " ;
371
- for (unsigned I = 0 ; I < TotalNumInstr; I++) {
372
- const Record *CurInstr = NumberedInstructions[I]->TheDef ;
370
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
371
+ const Record *CurInstr = Inst->TheDef ;
373
372
ArrayRef<const Record *> ColInstrs = MapTable[CurInstr];
373
+ if (ColInstrs.empty ())
374
+ continue ;
374
375
std::string OutStr;
375
- unsigned RelExists = 0 ;
376
- if (!ColInstrs.empty ()) {
377
- for (unsigned J = 0 ; J < NumCol; J++) {
378
- if (ColInstrs[J] != nullptr ) {
379
- RelExists = 1 ;
380
- OutStr += " , " ;
381
- OutStr += Namespace;
382
- OutStr += " ::" ;
383
- OutStr += ColInstrs[J]->getName ();
384
- } else {
385
- OutStr += " , (uint16_t)-1U" ;
386
- }
376
+ bool RelExists = false ;
377
+ for (const Record *ColInstr : ColInstrs) {
378
+ if (ColInstr) {
379
+ RelExists = true ;
380
+ OutStr += " , " ;
381
+ OutStr += ColInstr->getName ();
382
+ } else {
383
+ OutStr += " , (uint16_t)-1U" ;
387
384
}
385
+ }
388
386
389
- if (RelExists) {
390
- OS << " { " << Namespace << " :: " << CurInstr-> getName ();
391
- OS << OutStr << " }, \n " ;
392
- TableSize++ ;
393
- }
387
+ if (RelExists) {
388
+ if (TableSize == 0 )
389
+ OS << " static constexpr uint16_t Table[][ " << NumCol + 1 << " ] = { \n " ;
390
+ OS << " { " << CurInstr-> getName () << OutStr << " }, \n " ;
391
+ ++TableSize;
394
392
}
395
393
}
396
- if (!TableSize) {
397
- OS << " { " << Namespace << " ::"
398
- << " INSTRUCTION_LIST_END, " ;
399
- OS << Namespace << " ::"
400
- << " INSTRUCTION_LIST_END }" ;
401
- }
402
- OS << " }; // End of " << InstrMapDesc.getName () << " Table\n\n " ;
394
+
395
+ if (TableSize != 0 )
396
+ OS << " }; // End of Table\n\n " ;
403
397
return TableSize;
404
398
}
405
399
@@ -409,15 +403,19 @@ unsigned MapTableEmitter::emitBinSearchTable(raw_ostream &OS) {
409
403
// ===----------------------------------------------------------------------===//
410
404
411
405
void MapTableEmitter::emitBinSearch (raw_ostream &OS, unsigned TableSize) {
406
+ if (TableSize == 0 ) {
407
+ OS << " return -1;\n " ;
408
+ return ;
409
+ }
410
+
412
411
OS << " unsigned mid;\n " ;
413
412
OS << " unsigned start = 0;\n " ;
414
413
OS << " unsigned end = " << TableSize << " ;\n " ;
415
414
OS << " while (start < end) {\n " ;
416
415
OS << " mid = start + (end - start) / 2;\n " ;
417
- OS << " if (Opcode == " << InstrMapDesc. getName () << " Table[mid][0]) { \n " ;
416
+ OS << " if (Opcode == Table[mid][0]) \n " ;
418
417
OS << " break;\n " ;
419
- OS << " }\n " ;
420
- OS << " if (Opcode < " << InstrMapDesc.getName () << " Table[mid][0])\n " ;
418
+ OS << " if (Opcode < Table[mid][0])\n " ;
421
419
OS << " end = mid;\n " ;
422
420
OS << " else\n " ;
423
421
OS << " start = mid + 1;\n " ;
@@ -431,14 +429,15 @@ void MapTableEmitter::emitBinSearch(raw_ostream &OS, unsigned TableSize) {
431
429
// ===----------------------------------------------------------------------===//
432
430
433
431
void MapTableEmitter::emitMapFuncBody (raw_ostream &OS, unsigned TableSize) {
434
-
435
432
const ListInit *ColFields = InstrMapDesc.getColFields ();
436
433
ArrayRef<const ListInit *> ValueCols = InstrMapDesc.getValueCols ();
437
434
438
435
// Emit binary search algorithm to locate instructions in the
439
436
// relation table. If found, return opcode value from the appropriate column
440
437
// of the table.
441
438
emitBinSearch (OS, TableSize);
439
+ if (TableSize == 0 )
440
+ return ;
442
441
443
442
if (ValueCols.size () > 1 ) {
444
443
for (unsigned I = 0 , E = ValueCols.size (); I < E; I++) {
@@ -453,22 +452,19 @@ void MapTableEmitter::emitMapFuncBody(raw_ostream &OS, unsigned TableSize) {
453
452
OS << " && " ;
454
453
}
455
454
OS << " )\n " ;
456
- OS << " return " << InstrMapDesc.getName ();
457
- OS << " Table[mid][" << I + 1 << " ];\n " ;
455
+ OS << " return Table[mid][" << I + 1 << " ];\n " ;
458
456
}
459
457
OS << " return -1;" ;
460
- } else
461
- OS << " return " << InstrMapDesc.getName () << " Table[mid][1];\n " ;
462
-
463
- OS << " }\n\n " ;
458
+ } else {
459
+ OS << " return Table[mid][1];\n " ;
460
+ }
464
461
}
465
462
466
463
// ===----------------------------------------------------------------------===//
467
464
// Emit relation tables and the functions to query them.
468
465
// ===----------------------------------------------------------------------===//
469
466
470
467
void MapTableEmitter::emitTablesWithFunc (raw_ostream &OS) {
471
-
472
468
// Emit function name and the input parameters : mostly opcode value of the
473
469
// current instruction. However, if a table has multiple columns (more than 2
474
470
// since first column is used for the key instructions), then we also need
@@ -491,14 +487,16 @@ void MapTableEmitter::emitTablesWithFunc(raw_ostream &OS) {
491
487
492
488
// Emit rest of the function body.
493
489
emitMapFuncBody (OS, TableSize);
490
+
491
+ OS << " }\n\n " ;
494
492
}
495
493
496
494
// ===----------------------------------------------------------------------===//
497
495
// Emit enums for the column fields across all the instruction maps.
498
496
// ===----------------------------------------------------------------------===//
499
497
500
498
static void emitEnums (raw_ostream &OS, const RecordKeeper &Records) {
501
- std::map<std::string, std::vector <const Init *>> ColFieldValueMap;
499
+ std::map<std::string, SetVector <const Init *>> ColFieldValueMap;
502
500
503
501
// Iterate over all InstrMapping records and create a map between column
504
502
// fields and their possible values across all records.
@@ -507,10 +505,9 @@ static void emitEnums(raw_ostream &OS, const RecordKeeper &Records) {
507
505
const ListInit *ColFields = CurMap->getValueAsListInit (" ColFields" );
508
506
const ListInit *List = CurMap->getValueAsListInit (" ValueCols" );
509
507
std::vector<const ListInit *> ValueCols;
510
- unsigned ListSize = List->size ();
511
508
512
- for (unsigned J = 0 ; J < ListSize; J++ ) {
513
- const auto *ListJ = cast<ListInit>(List-> getElement (J) );
509
+ for (const Init *Elem : *List ) {
510
+ const auto *ListJ = cast<ListInit>(Elem );
514
511
515
512
if (ListJ->size () != ColFields->size ())
516
513
PrintFatalError (" Record `" + CurMap->getName () +
@@ -521,37 +518,26 @@ static void emitEnums(raw_ostream &OS, const RecordKeeper &Records) {
521
518
}
522
519
523
520
for (unsigned J = 0 , EndCf = ColFields->size (); J < EndCf; J++) {
524
- for ( unsigned K = 0 ; K < ListSize; K++) {
525
- std::string ColName = ColFields-> getElement (J)-> getAsUnquotedString () ;
526
- ColFieldValueMap[ColName]. push_back (( ValueCols[K])-> getElement (J));
527
- }
521
+ std::string ColName = ColFields-> getElement (J)-> getAsUnquotedString ();
522
+ auto &MapEntry = ColFieldValueMap[ColName] ;
523
+ for ( const ListInit *List : ValueCols)
524
+ MapEntry. insert (List-> getElement (J));
528
525
}
529
526
}
530
527
531
528
for (auto &[EnumName, FieldValues] : ColFieldValueMap) {
532
- // Delete duplicate entries from ColFieldValueMap
533
- for (unsigned i = 0 ; i < FieldValues.size () - 1 ; i++) {
534
- const Init *CurVal = FieldValues[i];
535
- for (unsigned j = i + 1 ; j < FieldValues.size (); j++) {
536
- if (CurVal == FieldValues[j]) {
537
- FieldValues.erase (FieldValues.begin () + j);
538
- --j;
539
- }
540
- }
541
- }
542
-
543
529
// Emit enumerated values for the column fields.
544
530
OS << " enum " << EnumName << " {\n " ;
545
531
ListSeparator LS (" ,\n " );
546
532
for (const Init *Field : FieldValues)
547
- OS << LS << " \t " << EnumName << " _" << Field->getAsUnquotedString ();
533
+ OS << LS << " " << EnumName << " _" << Field->getAsUnquotedString ();
548
534
OS << " \n };\n\n " ;
549
535
}
550
536
}
551
537
552
538
// ===----------------------------------------------------------------------===//
553
539
// Parse 'InstrMapping' records and use the information to form relationship
554
- // between instructions. These relations are emitted as a tables along with the
540
+ // between instructions. These relations are emitted as tables along with the
555
541
// functions to query them.
556
542
// ===----------------------------------------------------------------------===//
557
543
void llvm::EmitMapTable (const RecordKeeper &Records, raw_ostream &OS) {
@@ -565,8 +551,7 @@ void llvm::EmitMapTable(const RecordKeeper &Records, raw_ostream &OS) {
565
551
566
552
OS << " #ifdef GET_INSTRMAP_INFO\n " ;
567
553
OS << " #undef GET_INSTRMAP_INFO\n " ;
568
- OS << " namespace llvm {\n\n " ;
569
- OS << " namespace " << NameSpace << " {\n\n " ;
554
+ OS << " namespace llvm::" << NameSpace << " {\n\n " ;
570
555
571
556
// Emit coulumn field names and their values as enums.
572
557
emitEnums (OS, Records);
@@ -589,7 +574,6 @@ void llvm::EmitMapTable(const RecordKeeper &Records, raw_ostream &OS) {
589
574
// Emit map tables and the functions to query them.
590
575
IMap.emitTablesWithFunc (OS);
591
576
}
592
- OS << " } // end namespace " << NameSpace << " \n " ;
593
- OS << " } // end namespace llvm\n " ;
577
+ OS << " } // end namespace llvm::" << NameSpace << ' \n ' ;
594
578
OS << " #endif // GET_INSTRMAP_INFO\n\n " ;
595
579
}
0 commit comments