@@ -193,7 +193,7 @@ class InstructionEncoding {
193193 // / The namespace in which this encoding exists.
194194 StringRef DecoderNamespace;
195195
196- // / The decoder order.
196+ // / The decode order.
197197 int64_t DecodeOrder;
198198
199199 // / Known bits of this encoding. This is the value of the `Inst` field
@@ -232,7 +232,7 @@ class InstructionEncoding {
232232 // / Returns the namespace in which this encoding exists.
233233 StringRef getDecoderNamespace () const { return DecoderNamespace; }
234234
235- // / Returns the decoder order for this encoding.
235+ // / Returns the decode order for this encoding.
236236 int64_t getDecodeOrder () const { return DecodeOrder; }
237237
238238 // / Returns the size of this encoding, in bits.
@@ -533,7 +533,7 @@ class FilterChooser {
533533 std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
534534
535535 // / Per decode order filter choosers. Applicable when the set of candidates
536- // / have more than 1 decode order .
536+ // / have more than 1 decode orders .
537537 SmallVector<std::unique_ptr<const FilterChooser>> PerDecodeOrderChoosers;
538538
539539 // / Handle this chooser by attempting to decode all endodings.
@@ -606,6 +606,7 @@ class FilterChooser {
606606 // decoded bits in order to verify that the instruction matches the Opcode.
607607 std::vector<Island> getIslands (const KnownBits &EncodingBits) const ;
608608
609+ // Returns the decode order for the given encoding ID.
609610 int64_t getDecodeOrder (unsigned ID) const {
610611 return Encodings[ID].getDecodeOrder ();
611612 }
@@ -721,18 +722,25 @@ void FilterChooser::applyFilter(const Filter &F) {
721722 // When a filter has both fixed and variable encodings, we give priority to
722723 // the fixed encoding (FilteredIDs) and if that fails, we attempt the variable
723724 // encodings. See DecoderTableBuilder::emitTableEntries. This order may not be
724- // the right order for certain backends . To control this, they can use the
725+ // the right order for certain targets . To control this, they can use the
725726 // DecodeOrder. If we have multiple decode orders, the filter chooser will
726- // attempt the fixed-then-variable encoding per decode order, so if we want
727- // certain variable encoding to be prioritized over fixed ones, the fixed ones
728- // can get a larger decode order.
729-
730- // If we have multiple decode order, we want to attempt decoding in the
731- // following order: fixed0, variable0, fixed1, variable1 etc.
732- // If we do not split, we will attempt to decode as: fixed, variable.
733- // That may be ok if all fixed IDs have decode order <= all variable IDs, that
734- // is max(fixed decode order) <= min(variable decode order). Otherwise we
735- // split per decode order.
727+ // effectively attempt the fixed-then-variable encoding per decode order. This
728+ // allows targets to prioritize certain variable encoding over fixed ones by
729+ // assigning the fixed ones a larger decode order.
730+
731+ // If we always split per decode order, we get the following attempt order
732+ // f[0] -> v[0] -> f[1] -> v[1]
733+ //
734+ // However, instead of always splitting a chooser with multiple decode orders
735+ // we can split only when necessary and only the smallest number of splits
736+ // as long as we effectively get the same attempt order as above. As an
737+ // example, if the max decode order among the fixed encoding is <= min
738+ // decode order among varying encoding, then even if we do not split, we get
739+ // the same effective attempt order. This simple criteria is implemented
740+ // below (i.e, we fully split when this criteria is not met). There may be
741+ // more refined ways to do the decode order splitting. For example, not
742+ // splitting all the decode orders fully put doing partial splits. This can
743+ // be implemented in future as an optimization if desired.
736744 if (hasMultipleDecodeOrders () && !F.VariableIDs .empty () &&
737745 !F.FilteredIDs .empty ()) {
738746 auto LessDecodeOrder = [&](unsigned A, unsigned B) {
@@ -1654,7 +1662,7 @@ std::unique_ptr<Filter> FilterChooser::findBestFilter() const {
16541662bool FilterChooser::hasMultipleDecodeOrders () const {
16551663 if (EncodingIDs.size () <= 1 )
16561664 return false ;
1657- // Encodings are sorted by decoder order, so there are multiple decode orders
1665+ // Encodings are sorted by decode order, so there are multiple decode orders
16581666 // if the first and last decode order do not match.
16591667 return getDecodeOrder (EncodingIDs.front ()) !=
16601668 getDecodeOrder (EncodingIDs.back ());
@@ -1669,7 +1677,7 @@ void FilterChooser::splitByDecodeOrder() {
16691677 int64_t LastOrder = getDecodeOrder (IDs.front ());
16701678 size_t LastIndex = 0 ;
16711679 // Note: first iteration here is redundant, but this allows us to keep Idx
1672- // value correct.
1680+ // value correct (as opposed to using Idx + 1) .
16731681 for (const auto &[Idx, ID] : enumerate(IDs)) {
16741682 int64_t CurrentOrder = getDecodeOrder (ID);
16751683 if (CurrentOrder != LastOrder) {
@@ -1705,8 +1713,9 @@ void FilterChooser::doFilter() {
17051713 return ;
17061714 }
17071715
1708- // If there are multiple decode orders, then splin the candidates by decode
1709- // order if we are unable to find a filter.
1716+ // If we were unable to find a useful filter and there are multiple decode
1717+ // orders involved, split the candidates by decode order and create per decode
1718+ // order choosers.
17101719 if (hasMultipleDecodeOrders ()) {
17111720 splitByDecodeOrder ();
17121721 return ;
@@ -1797,7 +1806,8 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
17971806 emitTableEntries (*Delegate);
17981807 } else if (FC.PerDecodeOrderChoosers .size () > 1 ) {
17991808 // Attempt to decode all inferior choosers and allow them to fail, except
1800- // the last one.
1809+ // the last one. Note that `PerDecodeOrderChoosers` when preset is expected
1810+ // to have atleast 2 entries, hence the size() > 1 check above.
18011811 for (const auto &Delegate : drop_end (FC.PerDecodeOrderChoosers )) {
18021812 Table.insertOpcode (MCD::OPC_Scope);
18031813 unsigned FixupLoc = Table.insertNumToSkip ();
@@ -1807,6 +1817,8 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
18071817 emitTableEntries (*FC.PerDecodeOrderChoosers .back ());
18081818 } else if (FC.AttemptAll ) {
18091819 // Attempt all encoding and allow them to fail, except the last one.
1820+ // We expect here to have > 1 EncodingIDs, else we could have created a
1821+ // singleton chooser.
18101822 for (const auto ID : drop_end (FC.EncodingIDs )) {
18111823 Table.insertOpcode (MCD::OPC_Scope);
18121824 unsigned FixupLoc = Table.insertNumToSkip ();
0 commit comments