@@ -466,6 +466,9 @@ enum bitAttr_t {
466
466
// / decide what further remaining bits to look at.
467
467
468
468
class FilterChooser {
469
+ // TODO: Unfriend by providing the necessary accessors.
470
+ friend class DecoderTableBuilder ;
471
+
469
472
// Vector of encodings to choose our filter.
470
473
ArrayRef<InstructionEncoding> Encodings;
471
474
@@ -578,30 +581,6 @@ class FilterChooser {
578
581
// decoded bits in order to verify that the instruction matches the Opcode.
579
582
std::vector<Island> getIslands (const KnownBits &EncodingBits) const ;
580
583
581
- // Emits code to check the Predicates member of an instruction are true.
582
- // Returns true if predicate matches were emitted, false otherwise.
583
- bool emitPredicateMatch (raw_ostream &OS, unsigned EncodingID) const ;
584
- bool emitPredicateMatchAux (const Init &Val, bool ParenIfBinOp,
585
- raw_ostream &OS) const ;
586
-
587
- bool doesOpcodeNeedPredicate (unsigned EncodingID) const ;
588
- unsigned getPredicateIndex (DecoderTableInfo &TableInfo, StringRef P) const ;
589
- void emitPredicateTableEntry (DecoderTableInfo &TableInfo,
590
- unsigned EncodingID) const ;
591
-
592
- void emitSoftFailTableEntry (DecoderTableInfo &TableInfo,
593
- unsigned EncodingID) const ;
594
-
595
- // Emits table entries to decode the singleton.
596
- void emitSingletonTableEntry (DecoderTableInfo &TableInfo,
597
- unsigned EncodingID) const ;
598
-
599
- void emitBinaryParser (raw_ostream &OS, indent Indent,
600
- const OperandInfo &OpInfo) const ;
601
-
602
- void emitDecoder (raw_ostream &OS, indent Indent, unsigned EncodingID) const ;
603
- unsigned getDecoderIndex (DecoderSet &Decoders, unsigned EncodingID) const ;
604
-
605
584
// reportRegion is a helper function for filterProcessor to mark a region as
606
585
// eligible for use as a filter region.
607
586
void reportRegion (std::vector<std::unique_ptr<Filter>> &Filters, bitAttr_t RA,
@@ -622,12 +601,51 @@ class FilterChooser {
622
601
void doFilter ();
623
602
624
603
public:
625
- // / Emits state machine entries to decode our share of instructions.
626
- void emitTableEntries (DecoderTableInfo &TableInfo) const ;
627
-
628
604
void dump () const ;
629
605
};
630
606
607
+ class DecoderTableBuilder {
608
+ const CodeGenTarget &Target;
609
+ ArrayRef<InstructionEncoding> Encodings;
610
+ DecoderTableInfo &TableInfo;
611
+
612
+ public:
613
+ DecoderTableBuilder (const CodeGenTarget &Target,
614
+ ArrayRef<InstructionEncoding> Encodings,
615
+ DecoderTableInfo &TableInfo)
616
+ : Target(Target), Encodings(Encodings), TableInfo(TableInfo) {}
617
+
618
+ void buildTable (const FilterChooser &FC) const {
619
+ emitTableEntries (FC);
620
+ assert (TableInfo.FixupStack .empty () && " Fixup stack phasing error!" );
621
+ }
622
+
623
+ private:
624
+ void emitBinaryParser (raw_ostream &OS, indent Indent,
625
+ const OperandInfo &OpInfo) const ;
626
+
627
+ void emitDecoder (raw_ostream &OS, indent Indent, unsigned EncodingID) const ;
628
+
629
+ unsigned getDecoderIndex (unsigned EncodingID) const ;
630
+
631
+ unsigned getPredicateIndex (StringRef P) const ;
632
+
633
+ bool emitPredicateMatchAux (const Init &Val, bool ParenIfBinOp,
634
+ raw_ostream &OS) const ;
635
+
636
+ bool emitPredicateMatch (raw_ostream &OS, unsigned EncodingID) const ;
637
+
638
+ bool doesOpcodeNeedPredicate (unsigned EncodingID) const ;
639
+
640
+ void emitPredicateTableEntry (unsigned EncodingID) const ;
641
+
642
+ void emitSoftFailTableEntry (unsigned EncodingID) const ;
643
+
644
+ void emitSingletonTableEntry (const FilterChooser &FC) const ;
645
+
646
+ void emitTableEntries (const FilterChooser &FC) const ;
647
+ };
648
+
631
649
} // end anonymous namespace
632
650
633
651
// /////////////////////////
@@ -1062,8 +1080,8 @@ FilterChooser::getIslands(const KnownBits &EncodingBits) const {
1062
1080
return Islands;
1063
1081
}
1064
1082
1065
- void FilterChooser ::emitBinaryParser (raw_ostream &OS, indent Indent,
1066
- const OperandInfo &OpInfo) const {
1083
+ void DecoderTableBuilder ::emitBinaryParser (raw_ostream &OS, indent Indent,
1084
+ const OperandInfo &OpInfo) const {
1067
1085
const std::string &Decoder = OpInfo.Decoder ;
1068
1086
1069
1087
bool UseInsertBits = OpInfo.numFields () != 1 || OpInfo.InitValue != 0 ;
@@ -1098,8 +1116,8 @@ void FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
1098
1116
}
1099
1117
}
1100
1118
1101
- void FilterChooser ::emitDecoder (raw_ostream &OS, indent Indent,
1102
- unsigned EncodingID) const {
1119
+ void DecoderTableBuilder ::emitDecoder (raw_ostream &OS, indent Indent,
1120
+ unsigned EncodingID) const {
1103
1121
const InstructionEncoding &Encoding = Encodings[EncodingID];
1104
1122
1105
1123
// If a custom instruction decoder was specified, use that.
@@ -1117,8 +1135,7 @@ void FilterChooser::emitDecoder(raw_ostream &OS, indent Indent,
1117
1135
emitBinaryParser (OS, Indent, Op);
1118
1136
}
1119
1137
1120
- unsigned FilterChooser::getDecoderIndex (DecoderSet &Decoders,
1121
- unsigned EncodingID) const {
1138
+ unsigned DecoderTableBuilder::getDecoderIndex (unsigned EncodingID) const {
1122
1139
// Build up the predicate string.
1123
1140
SmallString<256 > Decoder;
1124
1141
// FIXME: emitDecoder() function can take a buffer directly rather than
@@ -1134,15 +1151,17 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
1134
1151
// overkill for now, though.
1135
1152
1136
1153
// Make sure the predicate is in the table.
1154
+ DecoderSet &Decoders = TableInfo.Decoders ;
1137
1155
Decoders.insert (CachedHashString (Decoder));
1138
1156
// Now figure out the index for when we write out the table.
1139
1157
DecoderSet::const_iterator P = find (Decoders, Decoder.str ());
1140
1158
return std::distance (Decoders.begin (), P);
1141
1159
}
1142
1160
1143
1161
// If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
1144
- bool FilterChooser::emitPredicateMatchAux (const Init &Val, bool ParenIfBinOp,
1145
- raw_ostream &OS) const {
1162
+ bool DecoderTableBuilder::emitPredicateMatchAux (const Init &Val,
1163
+ bool ParenIfBinOp,
1164
+ raw_ostream &OS) const {
1146
1165
if (const auto *D = dyn_cast<DefInit>(&Val)) {
1147
1166
if (!D->getDef ()->isSubClassOf (" SubtargetFeature" ))
1148
1167
return true ;
@@ -1173,8 +1192,8 @@ bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
1173
1192
return true ;
1174
1193
}
1175
1194
1176
- bool FilterChooser ::emitPredicateMatch (raw_ostream &OS,
1177
- unsigned EncodingID) const {
1195
+ bool DecoderTableBuilder ::emitPredicateMatch (raw_ostream &OS,
1196
+ unsigned EncodingID) const {
1178
1197
const ListInit *Predicates =
1179
1198
Encodings[EncodingID].getRecord ()->getValueAsListInit (" Predicates" );
1180
1199
bool IsFirstEmission = true ;
@@ -1196,7 +1215,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &OS,
1196
1215
return !Predicates->empty ();
1197
1216
}
1198
1217
1199
- bool FilterChooser ::doesOpcodeNeedPredicate (unsigned EncodingID) const {
1218
+ bool DecoderTableBuilder ::doesOpcodeNeedPredicate (unsigned EncodingID) const {
1200
1219
const ListInit *Predicates =
1201
1220
Encodings[EncodingID].getRecord ()->getValueAsListInit (" Predicates" );
1202
1221
for (unsigned i = 0 ; i < Predicates->size (); ++i) {
@@ -1210,8 +1229,7 @@ bool FilterChooser::doesOpcodeNeedPredicate(unsigned EncodingID) const {
1210
1229
return false ;
1211
1230
}
1212
1231
1213
- unsigned FilterChooser::getPredicateIndex (DecoderTableInfo &TableInfo,
1214
- StringRef Predicate) const {
1232
+ unsigned DecoderTableBuilder::getPredicateIndex (StringRef Predicate) const {
1215
1233
// Using the full predicate string as the key value here is a bit
1216
1234
// heavyweight, but is effective. If the string comparisons become a
1217
1235
// performance concern, we can implement a mangling of the predicate
@@ -1225,8 +1243,7 @@ unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
1225
1243
return (unsigned )(P - TableInfo.Predicates .begin ());
1226
1244
}
1227
1245
1228
- void FilterChooser::emitPredicateTableEntry (DecoderTableInfo &TableInfo,
1229
- unsigned EncodingID) const {
1246
+ void DecoderTableBuilder::emitPredicateTableEntry (unsigned EncodingID) const {
1230
1247
if (!doesOpcodeNeedPredicate (EncodingID))
1231
1248
return ;
1232
1249
@@ -1239,7 +1256,7 @@ void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
1239
1256
1240
1257
// Figure out the index into the predicate table for the predicate just
1241
1258
// computed.
1242
- unsigned PIdx = getPredicateIndex (TableInfo, PS.str ());
1259
+ unsigned PIdx = getPredicateIndex (PS.str ());
1243
1260
1244
1261
const MCD::DecoderOps DecoderOp = TableInfo.isOutermostScope ()
1245
1262
? MCD::OPC_CheckPredicateOrFail
@@ -1253,8 +1270,7 @@ void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
1253
1270
}
1254
1271
}
1255
1272
1256
- void FilterChooser::emitSoftFailTableEntry (DecoderTableInfo &TableInfo,
1257
- unsigned EncodingID) const {
1273
+ void DecoderTableBuilder::emitSoftFailTableEntry (unsigned EncodingID) const {
1258
1274
const InstructionEncoding &Encoding = Encodings[EncodingID];
1259
1275
const KnownBits &InstBits = Encoding.getInstBits ();
1260
1276
const APInt &SFBits = Encoding.getSoftFailBits ();
@@ -1290,19 +1306,20 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
1290
1306
}
1291
1307
1292
1308
// Emits table entries to decode the singleton.
1293
- void FilterChooser::emitSingletonTableEntry (DecoderTableInfo &TableInfo,
1294
- unsigned EncodingID) const {
1309
+ void DecoderTableBuilder::emitSingletonTableEntry (
1310
+ const FilterChooser &FC) const {
1311
+ unsigned EncodingID = *FC.SingletonEncodingID ;
1295
1312
const InstructionEncoding &Encoding = Encodings[EncodingID];
1296
1313
KnownBits EncodingBits = Encoding.getMandatoryBits ();
1297
1314
1298
1315
// Look for islands of undecoded bits of the singleton.
1299
- std::vector<Island> Islands = getIslands (EncodingBits);
1316
+ std::vector<FilterChooser:: Island> Islands = FC. getIslands (EncodingBits);
1300
1317
1301
1318
// Emit the predicate table entry if one is needed.
1302
- emitPredicateTableEntry (TableInfo, EncodingID);
1319
+ emitPredicateTableEntry (EncodingID);
1303
1320
1304
1321
// Check any additional encoding fields needed.
1305
- for (const Island &Ilnd : reverse (Islands)) {
1322
+ for (const FilterChooser:: Island &Ilnd : reverse (Islands)) {
1306
1323
const MCD::DecoderOps DecoderOp = TableInfo.isOutermostScope ()
1307
1324
? MCD::OPC_CheckFieldOrFail
1308
1325
: MCD::OPC_CheckField;
@@ -1321,9 +1338,9 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1321
1338
}
1322
1339
1323
1340
// Check for soft failure of the match.
1324
- emitSoftFailTableEntry (TableInfo, EncodingID);
1341
+ emitSoftFailTableEntry (EncodingID);
1325
1342
1326
- unsigned DIdx = getDecoderIndex (TableInfo. Decoders , EncodingID);
1343
+ unsigned DIdx = getDecoderIndex (EncodingID);
1327
1344
1328
1345
// Produce OPC_Decode or OPC_TryDecode opcode based on the information
1329
1346
// whether the instruction decoder is complete or not. If it is complete
@@ -1641,41 +1658,41 @@ void FilterChooser::dump() const {
1641
1658
}
1642
1659
}
1643
1660
1644
- void FilterChooser ::emitTableEntries (DecoderTableInfo &TableInfo ) const {
1661
+ void DecoderTableBuilder ::emitTableEntries (const FilterChooser &FC ) const {
1645
1662
// If there are other encodings that could match if those with all bits
1646
1663
// known don't, enter a scope so that they have a chance.
1647
- if (VariableFC)
1664
+ if (FC. VariableFC )
1648
1665
TableInfo.pushScope ();
1649
1666
1650
- if (SingletonEncodingID) {
1651
- assert (FilterChooserMap.empty ());
1667
+ if (FC. SingletonEncodingID ) {
1668
+ assert (FC. FilterChooserMap .empty ());
1652
1669
// There is only one encoding in which all bits in the filtered range are
1653
1670
// fully defined, but we still need to check if the remaining (unfiltered)
1654
1671
// bits are valid for this encoding. We also need to check predicates etc.
1655
- emitSingletonTableEntry (TableInfo, *SingletonEncodingID );
1672
+ emitSingletonTableEntry (FC );
1656
1673
} else {
1657
1674
// The general case: emit a switch over the field value.
1658
1675
DecoderTable &Table = TableInfo.Table ;
1659
1676
Table.insertOpcode (MCD::OPC_ExtractField);
1660
- Table.insertULEB128 (StartBit);
1661
- Table.insertUInt8 (NumBits);
1677
+ Table.insertULEB128 (FC. StartBit );
1678
+ Table.insertUInt8 (FC. NumBits );
1662
1679
1663
1680
// Emit switch cases for all but the last element.
1664
- for (const auto &[FilterVal, Delegate] : drop_end (FilterChooserMap)) {
1681
+ for (const auto &[FilterVal, Delegate] : drop_end (FC. FilterChooserMap )) {
1665
1682
Table.insertOpcode (MCD::OPC_FilterValue);
1666
1683
Table.insertULEB128 (FilterVal);
1667
1684
size_t FixupPos = Table.insertNumToSkip ();
1668
1685
1669
1686
// Emit table entries for this case.
1670
- Delegate-> emitTableEntries (TableInfo );
1687
+ emitTableEntries (*Delegate );
1671
1688
1672
1689
// Patch the previous OPC_FilterValue to fall through to the next case.
1673
1690
Table.patchNumToSkip (FixupPos, Table.size ());
1674
1691
}
1675
1692
1676
1693
// Emit a switch case for the last element. It never falls through;
1677
1694
// if it doesn't match, we leave the current scope.
1678
- const auto &[FilterVal, Delegate] = *FilterChooserMap.rbegin ();
1695
+ const auto &[FilterVal, Delegate] = *FC. FilterChooserMap .rbegin ();
1679
1696
Table.insertOpcode (!TableInfo.isOutermostScope ()
1680
1697
? MCD::OPC_FilterValue
1681
1698
: MCD::OPC_FilterValueOrFail);
@@ -1684,12 +1701,12 @@ void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
1684
1701
TableInfo.FixupStack .back ().push_back (Table.insertNumToSkip ());
1685
1702
1686
1703
// Emit table entries for the last case.
1687
- Delegate-> emitTableEntries (TableInfo );
1704
+ emitTableEntries (*Delegate );
1688
1705
}
1689
1706
1690
- if (VariableFC) {
1707
+ if (FC. VariableFC ) {
1691
1708
TableInfo.popScope ();
1692
- VariableFC-> emitTableEntries (TableInfo );
1709
+ emitTableEntries (*FC. VariableFC );
1693
1710
}
1694
1711
}
1695
1712
@@ -2538,6 +2555,7 @@ namespace {
2538
2555
}
2539
2556
2540
2557
DecoderTableInfo TableInfo;
2558
+ DecoderTableBuilder TableBuilder (Target, Encodings, TableInfo);
2541
2559
unsigned OpcodeMask = 0 ;
2542
2560
2543
2561
for (const auto &[Key, EncodingIDs] : EncMap) {
@@ -2550,8 +2568,7 @@ namespace {
2550
2568
// predicates and decoders themselves, however, are shared across all
2551
2569
// decoders to give more opportunities for uniqueing.
2552
2570
TableInfo.Table .clear ();
2553
- FC.emitTableEntries (TableInfo);
2554
- assert (TableInfo.isOutermostScope () && " fixup stack phasing error!" );
2571
+ TableBuilder.buildTable (FC);
2555
2572
2556
2573
// Print the table to the output stream.
2557
2574
OpcodeMask |= emitTable (OS, TableInfo.Table , DecoderNamespace, HwModeID,
0 commit comments