@@ -466,6 +466,9 @@ enum bitAttr_t {
466466// / decide what further remaining bits to look at.
467467
468468class FilterChooser {
469+ // TODO: Unfriend by providing the necessary accessors.
470+ friend class DecoderTableBuilder ;
471+
469472 // Vector of encodings to choose our filter.
470473 ArrayRef<InstructionEncoding> Encodings;
471474
@@ -578,30 +581,6 @@ class FilterChooser {
578581 // decoded bits in order to verify that the instruction matches the Opcode.
579582 std::vector<Island> getIslands (const KnownBits &EncodingBits) const ;
580583
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-
605584 // reportRegion is a helper function for filterProcessor to mark a region as
606585 // eligible for use as a filter region.
607586 void reportRegion (std::vector<std::unique_ptr<Filter>> &Filters, bitAttr_t RA,
@@ -622,12 +601,51 @@ class FilterChooser {
622601 void doFilter ();
623602
624603public:
625- // / Emits state machine entries to decode our share of instructions.
626- void emitTableEntries (DecoderTableInfo &TableInfo) const ;
627-
628604 void dump () const ;
629605};
630606
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+
631649} // end anonymous namespace
632650
633651// /////////////////////////
@@ -1062,8 +1080,8 @@ FilterChooser::getIslands(const KnownBits &EncodingBits) const {
10621080 return Islands;
10631081}
10641082
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 {
10671085 const std::string &Decoder = OpInfo.Decoder ;
10681086
10691087 bool UseInsertBits = OpInfo.numFields () != 1 || OpInfo.InitValue != 0 ;
@@ -1098,8 +1116,8 @@ void FilterChooser::emitBinaryParser(raw_ostream &OS, indent Indent,
10981116 }
10991117}
11001118
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 {
11031121 const InstructionEncoding &Encoding = Encodings[EncodingID];
11041122
11051123 // If a custom instruction decoder was specified, use that.
@@ -1117,8 +1135,7 @@ void FilterChooser::emitDecoder(raw_ostream &OS, indent Indent,
11171135 emitBinaryParser (OS, Indent, Op);
11181136}
11191137
1120- unsigned FilterChooser::getDecoderIndex (DecoderSet &Decoders,
1121- unsigned EncodingID) const {
1138+ unsigned DecoderTableBuilder::getDecoderIndex (unsigned EncodingID) const {
11221139 // Build up the predicate string.
11231140 SmallString<256 > Decoder;
11241141 // FIXME: emitDecoder() function can take a buffer directly rather than
@@ -1134,15 +1151,17 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
11341151 // overkill for now, though.
11351152
11361153 // Make sure the predicate is in the table.
1154+ DecoderSet &Decoders = TableInfo.Decoders ;
11371155 Decoders.insert (CachedHashString (Decoder));
11381156 // Now figure out the index for when we write out the table.
11391157 DecoderSet::const_iterator P = find (Decoders, Decoder.str ());
11401158 return std::distance (Decoders.begin (), P);
11411159}
11421160
11431161// 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 {
11461165 if (const auto *D = dyn_cast<DefInit>(&Val)) {
11471166 if (!D->getDef ()->isSubClassOf (" SubtargetFeature" ))
11481167 return true ;
@@ -1173,8 +1192,8 @@ bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
11731192 return true ;
11741193}
11751194
1176- bool FilterChooser ::emitPredicateMatch (raw_ostream &OS,
1177- unsigned EncodingID) const {
1195+ bool DecoderTableBuilder ::emitPredicateMatch (raw_ostream &OS,
1196+ unsigned EncodingID) const {
11781197 const ListInit *Predicates =
11791198 Encodings[EncodingID].getRecord ()->getValueAsListInit (" Predicates" );
11801199 bool IsFirstEmission = true ;
@@ -1196,7 +1215,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &OS,
11961215 return !Predicates->empty ();
11971216}
11981217
1199- bool FilterChooser ::doesOpcodeNeedPredicate (unsigned EncodingID) const {
1218+ bool DecoderTableBuilder ::doesOpcodeNeedPredicate (unsigned EncodingID) const {
12001219 const ListInit *Predicates =
12011220 Encodings[EncodingID].getRecord ()->getValueAsListInit (" Predicates" );
12021221 for (unsigned i = 0 ; i < Predicates->size (); ++i) {
@@ -1210,8 +1229,7 @@ bool FilterChooser::doesOpcodeNeedPredicate(unsigned EncodingID) const {
12101229 return false ;
12111230}
12121231
1213- unsigned FilterChooser::getPredicateIndex (DecoderTableInfo &TableInfo,
1214- StringRef Predicate) const {
1232+ unsigned DecoderTableBuilder::getPredicateIndex (StringRef Predicate) const {
12151233 // Using the full predicate string as the key value here is a bit
12161234 // heavyweight, but is effective. If the string comparisons become a
12171235 // performance concern, we can implement a mangling of the predicate
@@ -1225,8 +1243,7 @@ unsigned FilterChooser::getPredicateIndex(DecoderTableInfo &TableInfo,
12251243 return (unsigned )(P - TableInfo.Predicates .begin ());
12261244}
12271245
1228- void FilterChooser::emitPredicateTableEntry (DecoderTableInfo &TableInfo,
1229- unsigned EncodingID) const {
1246+ void DecoderTableBuilder::emitPredicateTableEntry (unsigned EncodingID) const {
12301247 if (!doesOpcodeNeedPredicate (EncodingID))
12311248 return ;
12321249
@@ -1239,7 +1256,7 @@ void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
12391256
12401257 // Figure out the index into the predicate table for the predicate just
12411258 // computed.
1242- unsigned PIdx = getPredicateIndex (TableInfo, PS.str ());
1259+ unsigned PIdx = getPredicateIndex (PS.str ());
12431260
12441261 const MCD::DecoderOps DecoderOp = TableInfo.isOutermostScope ()
12451262 ? MCD::OPC_CheckPredicateOrFail
@@ -1253,8 +1270,7 @@ void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
12531270 }
12541271}
12551272
1256- void FilterChooser::emitSoftFailTableEntry (DecoderTableInfo &TableInfo,
1257- unsigned EncodingID) const {
1273+ void DecoderTableBuilder::emitSoftFailTableEntry (unsigned EncodingID) const {
12581274 const InstructionEncoding &Encoding = Encodings[EncodingID];
12591275 const KnownBits &InstBits = Encoding.getInstBits ();
12601276 const APInt &SFBits = Encoding.getSoftFailBits ();
@@ -1290,19 +1306,20 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
12901306}
12911307
12921308// 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 ;
12951312 const InstructionEncoding &Encoding = Encodings[EncodingID];
12961313 KnownBits EncodingBits = Encoding.getMandatoryBits ();
12971314
12981315 // 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);
13001317
13011318 // Emit the predicate table entry if one is needed.
1302- emitPredicateTableEntry (TableInfo, EncodingID);
1319+ emitPredicateTableEntry (EncodingID);
13031320
13041321 // Check any additional encoding fields needed.
1305- for (const Island &Ilnd : reverse (Islands)) {
1322+ for (const FilterChooser:: Island &Ilnd : reverse (Islands)) {
13061323 const MCD::DecoderOps DecoderOp = TableInfo.isOutermostScope ()
13071324 ? MCD::OPC_CheckFieldOrFail
13081325 : MCD::OPC_CheckField;
@@ -1321,9 +1338,9 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
13211338 }
13221339
13231340 // Check for soft failure of the match.
1324- emitSoftFailTableEntry (TableInfo, EncodingID);
1341+ emitSoftFailTableEntry (EncodingID);
13251342
1326- unsigned DIdx = getDecoderIndex (TableInfo. Decoders , EncodingID);
1343+ unsigned DIdx = getDecoderIndex (EncodingID);
13271344
13281345 // Produce OPC_Decode or OPC_TryDecode opcode based on the information
13291346 // whether the instruction decoder is complete or not. If it is complete
@@ -1641,41 +1658,41 @@ void FilterChooser::dump() const {
16411658 }
16421659}
16431660
1644- void FilterChooser ::emitTableEntries (DecoderTableInfo &TableInfo ) const {
1661+ void DecoderTableBuilder ::emitTableEntries (const FilterChooser &FC ) const {
16451662 // If there are other encodings that could match if those with all bits
16461663 // known don't, enter a scope so that they have a chance.
1647- if (VariableFC)
1664+ if (FC. VariableFC )
16481665 TableInfo.pushScope ();
16491666
1650- if (SingletonEncodingID) {
1651- assert (FilterChooserMap.empty ());
1667+ if (FC. SingletonEncodingID ) {
1668+ assert (FC. FilterChooserMap .empty ());
16521669 // There is only one encoding in which all bits in the filtered range are
16531670 // fully defined, but we still need to check if the remaining (unfiltered)
16541671 // bits are valid for this encoding. We also need to check predicates etc.
1655- emitSingletonTableEntry (TableInfo, *SingletonEncodingID );
1672+ emitSingletonTableEntry (FC );
16561673 } else {
16571674 // The general case: emit a switch over the field value.
16581675 DecoderTable &Table = TableInfo.Table ;
16591676 Table.insertOpcode (MCD::OPC_ExtractField);
1660- Table.insertULEB128 (StartBit);
1661- Table.insertUInt8 (NumBits);
1677+ Table.insertULEB128 (FC. StartBit );
1678+ Table.insertUInt8 (FC. NumBits );
16621679
16631680 // 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 )) {
16651682 Table.insertOpcode (MCD::OPC_FilterValue);
16661683 Table.insertULEB128 (FilterVal);
16671684 size_t FixupPos = Table.insertNumToSkip ();
16681685
16691686 // Emit table entries for this case.
1670- Delegate-> emitTableEntries (TableInfo );
1687+ emitTableEntries (*Delegate );
16711688
16721689 // Patch the previous OPC_FilterValue to fall through to the next case.
16731690 Table.patchNumToSkip (FixupPos, Table.size ());
16741691 }
16751692
16761693 // Emit a switch case for the last element. It never falls through;
16771694 // 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 ();
16791696 Table.insertOpcode (!TableInfo.isOutermostScope ()
16801697 ? MCD::OPC_FilterValue
16811698 : MCD::OPC_FilterValueOrFail);
@@ -1684,12 +1701,12 @@ void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
16841701 TableInfo.FixupStack .back ().push_back (Table.insertNumToSkip ());
16851702
16861703 // Emit table entries for the last case.
1687- Delegate-> emitTableEntries (TableInfo );
1704+ emitTableEntries (*Delegate );
16881705 }
16891706
1690- if (VariableFC) {
1707+ if (FC. VariableFC ) {
16911708 TableInfo.popScope ();
1692- VariableFC-> emitTableEntries (TableInfo );
1709+ emitTableEntries (*FC. VariableFC );
16931710 }
16941711}
16951712
@@ -2538,6 +2555,7 @@ namespace {
25382555 }
25392556
25402557 DecoderTableInfo TableInfo;
2558+ DecoderTableBuilder TableBuilder (Target, Encodings, TableInfo);
25412559 unsigned OpcodeMask = 0 ;
25422560
25432561 for (const auto &[Key, EncodingIDs] : EncMap) {
@@ -2550,8 +2568,7 @@ namespace {
25502568 // predicates and decoders themselves, however, are shared across all
25512569 // decoders to give more opportunities for uniqueing.
25522570 TableInfo.Table .clear ();
2553- FC.emitTableEntries (TableInfo);
2554- assert (TableInfo.isOutermostScope () && " fixup stack phasing error!" );
2571+ TableBuilder.buildTable (FC);
25552572
25562573 // Print the table to the output stream.
25572574 OpcodeMask |= emitTable (OS, TableInfo.Table , DecoderNamespace, HwModeID,
0 commit comments