@@ -167,10 +167,6 @@ class DecoderEmitter {
167
167
168
168
const CodeGenTarget &getTarget () const { return Target; }
169
169
170
- // Emit the decoder state machine table.
171
- void emitTable (formatted_raw_ostream &OS, DecoderTableInfo &TableInfo,
172
- StringRef Namespace, unsigned HwModeID, unsigned BitWidth,
173
- const DecoderTreeNode *Tree) const ;
174
170
void emitInstrLenTable (formatted_raw_ostream &OS,
175
171
ArrayRef<unsigned > InstrLen) const ;
176
172
void emitPredicateFunction (formatted_raw_ostream &OS,
@@ -1189,9 +1185,7 @@ class DecoderTreeBuilder {
1189
1185
ArrayRef<InstructionEncoding> Encodings)
1190
1186
: Target(Target), Encodings(Encodings) {}
1191
1187
1192
- std::unique_ptr<DecoderTreeNode> buildTree (const FilterChooser &FC) {
1193
- return convertFilterChooser (&FC);
1194
- }
1188
+ std::unique_ptr<DecoderTreeNode> buildTree (ArrayRef<unsigned > EncodingIDs);
1195
1189
1196
1190
private:
1197
1191
std::unique_ptr<DecoderTreeNode>
@@ -1271,6 +1265,14 @@ DecoderTreeBuilder::convertFilterChooser(const FilterChooser *FC) {
1271
1265
return N;
1272
1266
}
1273
1267
1268
+ std::unique_ptr<DecoderTreeNode>
1269
+ DecoderTreeBuilder::buildTree (ArrayRef<unsigned > EncodingIDs) {
1270
+ FilterChooser FC (Encodings, EncodingIDs);
1271
+ if (FC.hasConflict ())
1272
+ return nullptr ;
1273
+ return convertFilterChooser (&FC);
1274
+ }
1275
+
1274
1276
// / Collects all HwModes referenced by the target for encoding purposes.
1275
1277
void DecoderEmitter::collectHwModesReferencedForEncodings (
1276
1278
std::vector<unsigned > &HwModeIDs,
@@ -1438,22 +1440,6 @@ DecoderEmitter::DecoderEmitter(const RecordKeeper &RK)
1438
1440
parseInstructionEncodings ();
1439
1441
}
1440
1442
1441
- // Emit the decoder state machine table.
1442
- void DecoderEmitter::emitTable (formatted_raw_ostream &OS,
1443
- DecoderTableInfo &TableInfo, StringRef Namespace,
1444
- unsigned HwModeID, unsigned BitWidth,
1445
- const DecoderTreeNode *Tree) const {
1446
- SmallString<32 > TableName (" DecoderTable" );
1447
- TableName.append (Namespace);
1448
- if (HwModeID != DefaultMode)
1449
- TableName.append ({" _" , Target.getHwModes ().getModeName (HwModeID)});
1450
- TableName.append (utostr (BitWidth));
1451
-
1452
- DecoderTableEmitter TableEmitter (TableInfo, OS);
1453
- TableEmitter.emitTable (TableName,
1454
- SpecializeDecodersPerBitwidth ? BitWidth : 0 , Tree);
1455
- }
1456
-
1457
1443
// Emits disassembler code for instruction decoding.
1458
1444
void DecoderEmitter::run (raw_ostream &o) const {
1459
1445
formatted_raw_ostream OS (o);
@@ -1522,35 +1508,40 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
1522
1508
PrintFatalError (
1523
1509
" Cannot specialize decoders for variable length instuctions" );
1524
1510
1525
- // Entries in `EncMap` are already sorted by bitwidth. So bucketing per
1526
- // bitwidth can be done on-the-fly as we iterate over the map.
1527
1511
DecoderTableInfo TableInfo{};
1512
+ DecoderTreeBuilder TreeBuilder (Target, Encodings);
1513
+ DecoderTableEmitter TableEmitter (TableInfo, OS);
1528
1514
1515
+ // Emit a table for each (namespace, hwmode, bitwidth) combination.
1516
+ // Predicates and decoders are shared across the tables to provide more
1517
+ // opportunities for uniqueness. If SpecializeDecodersPerBitwidth is enabled,
1518
+ // decoders are shared across all tables for a given bitwidth, else they are
1519
+ // shared across all tables. Predicates are always shared across all tables.
1520
+ //
1521
+ // Entries in `EncMap` are already sorted by bitwidth. So bucketing per
1522
+ // bitwidth can be done on-the-fly as we iterate over the map.
1529
1523
bool HasConflict = false ;
1530
1524
for (const auto &[BitWidth, BWMap] : EncMap) {
1531
1525
for (const auto &[Key, EncodingIDs] : BWMap) {
1532
1526
auto [DecoderNamespace, HwModeID] = Key;
1533
1527
1534
- // Emit the decoder for this (namespace, hwmode, width) combination.
1535
- FilterChooser FC (Encodings, EncodingIDs);
1536
- HasConflict |= FC.hasConflict ();
1537
- // Skip emitting table entries if a conflict has been detected.
1538
- if (HasConflict)
1528
+ std::unique_ptr<DecoderTreeNode> Tree =
1529
+ TreeBuilder.buildTree (EncodingIDs);
1530
+
1531
+ // Skip emitting the table if a conflict has been detected.
1532
+ if (!Tree) {
1533
+ HasConflict = true ;
1539
1534
continue ;
1535
+ }
1536
+
1537
+ // Form the table name.
1538
+ SmallString<32 > TableName ({" DecoderTable" , DecoderNamespace});
1539
+ if (HwModeID != DefaultMode)
1540
+ TableName.append ({" _" , Target.getHwModes ().getModeName (HwModeID)});
1541
+ TableName.append (utostr (BitWidth));
1540
1542
1541
- DecoderTreeBuilder TreeBuilder (Target, Encodings);
1542
- std::unique_ptr<DecoderTreeNode> Tree = TreeBuilder.buildTree (FC);
1543
-
1544
- // The decode table is cleared for each top level decoder function. The
1545
- // predicates and decoders themselves, however, are shared across
1546
- // different decoders to give more opportunities for uniqueing.
1547
- // - If `SpecializeDecodersPerBitwidth` is enabled, decoders are shared
1548
- // across all decoder tables for a given bitwidth, else they are shared
1549
- // across all decoder tables.
1550
- // - predicates are shared across all decoder tables.
1551
- // Print the table to the output stream.
1552
- emitTable (OS, TableInfo, DecoderNamespace, HwModeID, BitWidth,
1553
- Tree.get ());
1543
+ TableEmitter.emitTable (
1544
+ TableName, SpecializeDecodersPerBitwidth ? BitWidth : 0 , Tree.get ());
1554
1545
}
1555
1546
1556
1547
// Each BitWidth get's its own decoders and decoder function if
0 commit comments