@@ -371,8 +371,6 @@ class DecoderEmitter {
371371
372372namespace {
373373
374- class FilterChooser ;
375-
376374// / Filter - Filter works with FilterChooser to produce the decoding tree for
377375// / the ISA.
378376// /
@@ -409,9 +407,7 @@ class FilterChooser;
409407// / decoder could try to decode the even/odd register numbering and assign to
410408// / VST4q8a or VST4q8b, but for the time being, the decoder chooses the "a"
411409// / version and return the Opcode since the two have the same Asm format string.
412- class Filter {
413- protected:
414- const FilterChooser &Owner; // FilterChooser who owns this filter
410+ struct Filter {
415411 unsigned StartBit; // the starting bit position
416412 unsigned NumBits; // number of bits to filter
417413
@@ -421,14 +417,8 @@ class Filter {
421417 // Set of uid's with non-constant segment values.
422418 std::vector<unsigned > VariableIDs;
423419
424- // Map of well-known segment value to its delegate.
425- std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
426-
427- // A filter chooser for encodings that contain some '?' in the filtered range.
428- std::unique_ptr<const FilterChooser> VariableFC;
429-
430- public:
431- Filter (const FilterChooser &owner, unsigned startBit, unsigned numBits);
420+ Filter (ArrayRef<InstructionEncoding> Encodings,
421+ ArrayRef<unsigned > EncodingIDs, unsigned StartBit, unsigned NumBits);
432422
433423 bool hasSingleFilteredID () const {
434424 return FilteredIDs.size () == 1 && FilteredIDs.begin ()->second .size () == 1 ;
@@ -439,25 +429,6 @@ class Filter {
439429 return FilteredIDs.begin ()->second .front ();
440430 }
441431
442- // Return the filter chooser for the group of instructions without constant
443- // segment values.
444- const FilterChooser &getVariableFC () const {
445- assert (hasSingleFilteredID () && FilterChooserMap.empty ());
446- return *VariableFC;
447- }
448-
449- // Divides the decoding task into sub tasks and delegates them to the
450- // inferior FilterChooser's.
451- //
452- // A special case arises when there's only one entry in the filtered
453- // instructions. In order to unambiguously decode the singleton, we need to
454- // match the remaining undecoded encoding bits against the singleton.
455- void recurse ();
456-
457- // Emit table entries to decode instructions given a segment or segments of
458- // bits.
459- void emitTableEntry (DecoderTableInfo &TableInfo) const ;
460-
461432 // Returns the number of fanout produced by the filter. More fanout implies
462433 // the filter distinguishes more categories of instructions.
463434 unsigned usefulness () const ;
@@ -490,19 +461,13 @@ enum bitAttr_t {
490461// / decide what further remaining bits to look at.
491462
492463class FilterChooser {
493- protected:
494- friend class Filter ;
495-
496464 // Vector of encodings to choose our filter.
497465 ArrayRef<InstructionEncoding> Encodings;
498466
499467 // / Encoding IDs for this filter chooser to work on.
500468 // / Sorted by non-decreasing encoding width.
501469 SmallVector<unsigned , 0 > EncodingIDs;
502470
503- // The selected filter, if any.
504- std::unique_ptr<Filter> BestFilter;
505-
506471 // Array of bit values passed down from our parent.
507472 // Set to all unknown for Parent == nullptr.
508473 KnownBits FilterBits;
@@ -517,6 +482,29 @@ class FilterChooser {
517482 // Parent emitter
518483 const DecoderEmitter *Emitter;
519484
485+ // / If the selected filter matches multiple encodings, then this is the
486+ // / starting position and the width of the filtered range.
487+ unsigned StartBit;
488+ unsigned NumBits;
489+
490+ // / If the selected filter matches multiple encodings, and there is
491+ // / *exactly one* encoding in which all bits are known in the filtered range,
492+ // / then this is the ID of that encoding.
493+ std::optional<unsigned > SingletonEncodingID;
494+
495+ // / If the selected filter matches multiple encodings, and there is
496+ // / *at least one* encoding in which all bits are known in the filtered range,
497+ // / then this is the FilterChooser created for the subset of encodings that
498+ // / contain some unknown bits in the filtered range.
499+ std::unique_ptr<const FilterChooser> VariableFC;
500+
501+ // / If the selected filter matches multiple encodings, and there is
502+ // / *more than one* encoding in which all bits are known in the filtered
503+ // / range, then this is a map of field values to FilterChoosers created for
504+ // / the subset of encodings sharing that field value.
505+ // / The "field value" here refers to the encoding bits in the filtered range.
506+ std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
507+
520508 struct Island {
521509 unsigned StartBit;
522510 unsigned NumBits;
@@ -566,7 +554,11 @@ class FilterChooser {
566554 return Encodings[EncodingIDs.back ()].getBitWidth ();
567555 }
568556
569- protected:
557+ private:
558+ // / Applies the given filter to the set of encodings this FilterChooser
559+ // / works with, creating inferior FilterChoosers as necessary.
560+ void applyFilter (const Filter &F);
561+
570562 // / dumpStack - dumpStack traverses the filter chooser chain and calls
571563 // / dumpFilterArray on each filter chooser up to the top level one.
572564 void dumpStack (raw_ostream &OS, indent Indent, unsigned PadToWidth) const ;
@@ -600,8 +592,11 @@ class FilterChooser {
600592 unsigned EncodingID) const ;
601593
602594 // Emits code to decode the singleton, and then to decode the rest.
603- void emitSingletonTableEntry (DecoderTableInfo &TableInfo,
604- const Filter &Best) const ;
595+ void emitSingletonTableEntry (DecoderTableInfo &TableInfo) const ;
596+
597+ // Emit table entries to decode instructions given a segment or segments of
598+ // bits.
599+ void emitTableEntry (DecoderTableInfo &TableInfo) const ;
605600
606601 void emitBinaryParser (raw_ostream &OS, indent Indent,
607602 const OperandInfo &OpInfo) const ;
@@ -644,12 +639,12 @@ class FilterChooser {
644639// //
645640// /////////////////////////
646641
647- Filter::Filter (const FilterChooser &owner, unsigned startBit, unsigned numBits)
648- : Owner(owner), StartBit(startBit), NumBits(numBits) {
649- assert (StartBit + NumBits - 1 < Owner. FilterBits . getBitWidth ());
650-
651- for (unsigned EncodingID : Owner. EncodingIDs ) {
652- const InstructionEncoding &Encoding = Owner. Encodings [EncodingID];
642+ Filter::Filter (ArrayRef<InstructionEncoding> Encodings,
643+ ArrayRef< unsigned > EncodingIDs, unsigned StartBit,
644+ unsigned NumBits)
645+ : StartBit(StartBit), NumBits(NumBits) {
646+ for (unsigned EncodingID : EncodingIDs) {
647+ const InstructionEncoding &Encoding = Encodings[EncodingID];
653648 KnownBits EncodingBits = Encoding.getMandatoryBits ();
654649
655650 // Scans the segment for possibly well-specified encoding bits.
@@ -670,48 +665,44 @@ Filter::Filter(const FilterChooser &owner, unsigned startBit, unsigned numBits)
670665 " Filter returns no instruction categories" );
671666}
672667
673- // Divides the decoding task into sub tasks and delegates them to the
674- // inferior FilterChooser's.
675- //
676- // A special case arises when there's only one entry in the filtered
677- // instructions. In order to unambiguously decode the singleton, we need to
678- // match the remaining undecoded encoding bits against the singleton.
679- void Filter::recurse () {
680- assert (Owner.FilterBits .extractBits (NumBits, StartBit).isUnknown ());
668+ void FilterChooser::applyFilter (const Filter &F) {
669+ StartBit = F.StartBit ;
670+ NumBits = F.NumBits ;
671+ assert (FilterBits.extractBits (NumBits, StartBit).isUnknown ());
681672
682- if (!VariableIDs.empty ()) {
673+ if (!F. VariableIDs .empty ()) {
683674 // Delegates to an inferior filter chooser for further processing on this
684675 // group of instructions whose segment values are variable.
685- VariableFC = std::make_unique<FilterChooser>(Owner. Encodings , VariableIDs,
686- Owner. FilterBits , Owner );
676+ VariableFC = std::make_unique<FilterChooser>(Encodings, F. VariableIDs ,
677+ FilterBits, * this );
687678 }
688679
689680 // No need to recurse for a singleton filtered instruction.
690681 // See also Filter::emit*().
691- if (hasSingleFilteredID ()) {
682+ if (F.hasSingleFilteredID ()) {
683+ SingletonEncodingID = F.getSingletonEncodingID ();
692684 assert (VariableFC && " Shouldn't have created a filter for one encoding!" );
693685 return ;
694686 }
695687
696688 // Otherwise, create sub choosers.
697- for (const auto &[FilterVal, InferiorEncodingIDs] : FilteredIDs) {
689+ for (const auto &[FilterVal, InferiorEncodingIDs] : F. FilteredIDs ) {
698690 // Create a new filter by inserting the field bits into the parent filter.
699691 APInt FieldBits (NumBits, FilterVal);
700- KnownBits InferiorFilterBits = Owner. FilterBits ;
692+ KnownBits InferiorFilterBits = FilterBits;
701693 InferiorFilterBits.insertBits (KnownBits::makeConstant (FieldBits), StartBit);
702694
703695 // Delegates to an inferior filter chooser for further processing on this
704696 // category of instructions.
705- FilterChooserMap.try_emplace (
706- FilterVal,
707- std::make_unique<FilterChooser>(Owner.Encodings , InferiorEncodingIDs,
708- InferiorFilterBits, Owner));
697+ FilterChooserMap.try_emplace (FilterVal, std::make_unique<FilterChooser>(
698+ Encodings, InferiorEncodingIDs,
699+ InferiorFilterBits, *this ));
709700 }
710701}
711702
712703// Emit table entries to decode instructions given a segment or segments
713704// of bits.
714- void Filter ::emitTableEntry (DecoderTableInfo &TableInfo) const {
705+ void FilterChooser ::emitTableEntry (DecoderTableInfo &TableInfo) const {
715706 assert (isUInt<8 >(NumBits) && " NumBits overflowed uint8 table entry!" );
716707 TableInfo.Table .push_back (MCD::OPC_ExtractField);
717708
@@ -1436,15 +1427,14 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
14361427}
14371428
14381429// Emits table entries to decode the singleton, and then to decode the rest.
1439- void FilterChooser::emitSingletonTableEntry (DecoderTableInfo &TableInfo,
1440- const Filter &Best) const {
1430+ void FilterChooser::emitSingletonTableEntry (DecoderTableInfo &TableInfo) const {
14411431 // complex singletons need predicate checks from the first singleton
14421432 // to refer forward to the variable filterchooser that follows.
14431433 TableInfo.pushScope ();
1444- emitSingletonTableEntry (TableInfo, Best. getSingletonEncodingID () );
1434+ emitSingletonTableEntry (TableInfo, *SingletonEncodingID );
14451435 TableInfo.popScope ();
14461436
1447- Best. getVariableFC (). emitTableEntries (TableInfo);
1437+ VariableFC-> emitTableEntries (TableInfo);
14481438}
14491439
14501440// reportRegion is a helper function for filterProcessor to mark a region as
@@ -1453,8 +1443,8 @@ void FilterChooser::reportRegion(std::vector<std::unique_ptr<Filter>> &Filters,
14531443 bitAttr_t RA, unsigned StartBit,
14541444 unsigned BitIndex, bool AllowMixed) const {
14551445 if (AllowMixed ? RA == ATTR_MIXED : RA == ATTR_ALL_SET)
1456- Filters.push_back (
1457- std::make_unique<Filter>(* this , StartBit, BitIndex - StartBit));
1446+ Filters.push_back (std::make_unique<Filter>(Encodings, EncodingIDs, StartBit,
1447+ BitIndex - StartBit));
14581448}
14591449
14601450std::unique_ptr<Filter>
@@ -1475,8 +1465,8 @@ FilterChooser::findBestFilter(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
14751465 std::vector<Island> Islands = getIslands (EncodingBits);
14761466 if (!Islands.empty ()) {
14771467 // Found an instruction with island(s). Now just assign a filter.
1478- return std::make_unique<Filter>(* this , Islands[ 0 ]. StartBit ,
1479- Islands[0 ].NumBits );
1468+ return std::make_unique<Filter>(
1469+ Encodings, EncodingIDs, Islands[ 0 ]. StartBit , Islands[0 ].NumBits );
14801470 }
14811471 }
14821472 }
@@ -1708,9 +1698,9 @@ void FilterChooser::doFilter() {
17081698 if (EncodingIDs.size () < 2 )
17091699 return ;
17101700
1711- BestFilter = findBestFilter ();
1701+ std::unique_ptr<Filter> BestFilter = findBestFilter ();
17121702 if (BestFilter) {
1713- BestFilter-> recurse ( );
1703+ applyFilter (*BestFilter );
17141704 return ;
17151705 }
17161706
@@ -1749,10 +1739,10 @@ void FilterChooser::emitTableEntries(DecoderTableInfo &TableInfo) const {
17491739 }
17501740
17511741 // Use the best filter to do the decoding!
1752- if (BestFilter-> hasSingleFilteredID () )
1753- emitSingletonTableEntry (TableInfo, *BestFilter );
1742+ if (SingletonEncodingID )
1743+ emitSingletonTableEntry (TableInfo);
17541744 else
1755- BestFilter-> emitTableEntry (TableInfo);
1745+ emitTableEntry (TableInfo);
17561746}
17571747
17581748static std::string findOperandDecoderMethod (const Record *Record) {
0 commit comments