@@ -490,6 +490,7 @@ class FilterChooser {
490
490
// / If the selected filter matches multiple encodings, and there is
491
491
// / *exactly one* encoding in which all bits are known in the filtered range,
492
492
// / then this is the ID of that encoding.
493
+ // / Also used when there is only one encoding.
493
494
std::optional<unsigned > SingletonEncodingID;
494
495
495
496
// / If the selected filter matches multiple encodings, and there is
@@ -591,13 +592,6 @@ class FilterChooser {
591
592
void emitSingletonTableEntry (DecoderTableInfo &TableInfo,
592
593
unsigned EncodingID) const ;
593
594
594
- // Emits code to decode the singleton, and then to decode the rest.
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 ;
600
-
601
595
void emitBinaryParser (raw_ostream &OS, indent Indent,
602
596
const OperandInfo &OpInfo) const ;
603
597
@@ -624,8 +618,7 @@ class FilterChooser {
624
618
void doFilter ();
625
619
626
620
public:
627
- // emitTableEntries - Emit state machine entries to decode our share of
628
- // instructions.
621
+ // / Emits state machine entries to decode our share of instructions.
629
622
void emitTableEntries (DecoderTableInfo &TableInfo) const ;
630
623
631
624
void dump () const ;
@@ -700,70 +693,6 @@ void FilterChooser::applyFilter(const Filter &F) {
700
693
}
701
694
}
702
695
703
- // Emit table entries to decode instructions given a segment or segments
704
- // of bits.
705
- void FilterChooser::emitTableEntry (DecoderTableInfo &TableInfo) const {
706
- assert (isUInt<8 >(NumBits) && " NumBits overflowed uint8 table entry!" );
707
- TableInfo.Table .push_back (MCD::OPC_ExtractField);
708
-
709
- TableInfo.Table .insertULEB128 (StartBit);
710
- TableInfo.Table .push_back (NumBits);
711
-
712
- // If VariableFC is present, we need to add a new scope for this filter.
713
- // Otherwise, we can skip adding a new scope and any patching added will
714
- // automatically be added to the enclosing scope.
715
- const uint64_t LastFilter = FilterChooserMap.rbegin ()->first ;
716
- if (VariableFC)
717
- TableInfo.FixupStack .emplace_back ();
718
-
719
- DecoderTable &Table = TableInfo.Table ;
720
-
721
- size_t PrevFilter = 0 ;
722
- for (const auto &[FilterVal, Delegate] : FilterChooserMap) {
723
- // The last filtervalue emitted can be OPC_FilterValue if we are at
724
- // outermost scope.
725
- const uint8_t DecoderOp =
726
- FilterVal == LastFilter && TableInfo.isOutermostScope ()
727
- ? MCD::OPC_FilterValueOrFail
728
- : MCD::OPC_FilterValue;
729
- Table.push_back (DecoderOp);
730
- Table.insertULEB128 (FilterVal);
731
- if (DecoderOp == MCD::OPC_FilterValue) {
732
- // Reserve space for the NumToSkip entry. We'll backpatch the value later.
733
- PrevFilter = Table.insertNumToSkip ();
734
- } else {
735
- PrevFilter = 0 ;
736
- }
737
-
738
- // We arrive at a category of instructions with the same segment value.
739
- // Now delegate to the sub filter chooser for further decodings.
740
- // The case may fallthrough, which happens if the remaining well-known
741
- // encoding bits do not match exactly.
742
- Delegate->emitTableEntries (TableInfo);
743
-
744
- // Now that we've emitted the body of the handler, update the NumToSkip
745
- // of the filter itself to be able to skip forward when false.
746
- if (PrevFilter)
747
- Table.patchNumToSkip (PrevFilter, Table.size ());
748
- }
749
-
750
- if (VariableFC) {
751
- // Each scope should always have at least one filter value to check for.
752
- assert (PrevFilter != 0 && " empty filter set!" );
753
- TableInfo.popScope ();
754
- PrevFilter = 0 ; // Don't re-process the filter's fallthrough.
755
-
756
- // Delegate to the sub filter chooser for further decoding.
757
- VariableFC->emitTableEntries (TableInfo);
758
- }
759
-
760
- // If there is no fallthrough and the final filter was not in the outermost
761
- // scope, then it must be fixed up according to the enclosing scope rather
762
- // than the current position.
763
- if (PrevFilter)
764
- TableInfo.FixupStack .back ().push_back (PrevFilter);
765
- }
766
-
767
696
// Returns the number of fanout produced by the filter. More fanout implies
768
697
// the filter distinguishes more categories of instructions.
769
698
unsigned Filter::usefulness () const {
@@ -1425,17 +1354,6 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
1425
1354
}
1426
1355
}
1427
1356
1428
- // Emits table entries to decode the singleton, and then to decode the rest.
1429
- void FilterChooser::emitSingletonTableEntry (DecoderTableInfo &TableInfo) const {
1430
- // complex singletons need predicate checks from the first singleton
1431
- // to refer forward to the variable filterchooser that follows.
1432
- TableInfo.pushScope ();
1433
- emitSingletonTableEntry (TableInfo, *SingletonEncodingID);
1434
- TableInfo.popScope ();
1435
-
1436
- VariableFC->emitTableEntries (TableInfo);
1437
- }
1438
-
1439
1357
// reportRegion is a helper function for filterProcessor to mark a region as
1440
1358
// eligible for use as a filter region.
1441
1359
void FilterChooser::reportRegion (std::vector<std::unique_ptr<Filter>> &Filters,
@@ -1694,8 +1612,10 @@ void FilterChooser::doFilter() {
1694
1612
assert (!EncodingIDs.empty () && " FilterChooser created with no instructions" );
1695
1613
1696
1614
// No filter needed.
1697
- if (EncodingIDs.size () < 2 )
1615
+ if (EncodingIDs.size () == 1 ) {
1616
+ SingletonEncodingID = EncodingIDs.front ();
1698
1617
return ;
1618
+ }
1699
1619
1700
1620
std::unique_ptr<Filter> BestFilter = findBestFilter ();
1701
1621
if (BestFilter) {
@@ -1726,22 +1646,56 @@ void FilterChooser::dump() const {
1726
1646
}
1727
1647
}
1728
1648
1729
- // emitTableEntries - Emit state machine entries to decode our share of
1730
- // instructions.
1731
1649
void FilterChooser::emitTableEntries (DecoderTableInfo &TableInfo) const {
1732
- if (EncodingIDs.size () == 1 ) {
1733
- // There is only one instruction in the set, which is great!
1734
- // Call emitSingletonDecoder() to see whether there are any remaining
1735
- // encodings bits.
1736
- emitSingletonTableEntry (TableInfo, EncodingIDs[0 ]);
1737
- return ;
1650
+ // If there are other encodings that could match if those with all bits
1651
+ // known don't, enter a scope so that they have a chance.
1652
+ if (VariableFC)
1653
+ TableInfo.pushScope ();
1654
+
1655
+ if (SingletonEncodingID) {
1656
+ assert (FilterChooserMap.empty ());
1657
+ // There is only one encoding in which all bits in the filtered range are
1658
+ // fully defined, but we still need to check if the remaining (unfiltered)
1659
+ // bits are valid for this encoding. We also need to check predicates etc.
1660
+ emitSingletonTableEntry (TableInfo, *SingletonEncodingID);
1661
+ } else {
1662
+ // The general case: emit a switch over the field value.
1663
+ DecoderTable &Table = TableInfo.Table ;
1664
+ Table.push_back (MCD::OPC_ExtractField);
1665
+ Table.insertULEB128 (StartBit);
1666
+ assert (isUInt<8 >(NumBits) && " NumBits overflowed uint8 table entry!" );
1667
+ Table.push_back (NumBits);
1668
+
1669
+ // Emit switch cases for all but the last element.
1670
+ for (const auto &[FilterVal, Delegate] : drop_end (FilterChooserMap)) {
1671
+ Table.push_back (MCD::OPC_FilterValue);
1672
+ Table.insertULEB128 (FilterVal);
1673
+ size_t FixupPos = Table.insertNumToSkip ();
1674
+
1675
+ // Emit table entries for this case.
1676
+ Delegate->emitTableEntries (TableInfo);
1677
+
1678
+ // Patch the previous OPC_FilterValue to fall through to the next case.
1679
+ Table.patchNumToSkip (FixupPos, Table.size ());
1680
+ }
1681
+
1682
+ // Emit a switch case for the last element. It never falls through;
1683
+ // if it doesn't match, we leave the current scope.
1684
+ const auto &[FilterVal, Delegate] = *FilterChooserMap.rbegin ();
1685
+ Table.push_back (!TableInfo.isOutermostScope () ? MCD::OPC_FilterValue
1686
+ : MCD::OPC_FilterValueOrFail);
1687
+ Table.insertULEB128 (FilterVal);
1688
+ if (!TableInfo.isOutermostScope ())
1689
+ TableInfo.FixupStack .back ().push_back (Table.insertNumToSkip ());
1690
+
1691
+ // Emit table entries for the last case.
1692
+ Delegate->emitTableEntries (TableInfo);
1738
1693
}
1739
1694
1740
- // Use the best filter to do the decoding!
1741
- if (SingletonEncodingID)
1742
- emitSingletonTableEntry (TableInfo);
1743
- else
1744
- emitTableEntry (TableInfo);
1695
+ if (VariableFC) {
1696
+ TableInfo.popScope ();
1697
+ VariableFC->emitTableEntries (TableInfo);
1698
+ }
1745
1699
}
1746
1700
1747
1701
static std::string findOperandDecoderMethod (const Record *Record) {
0 commit comments