@@ -423,6 +423,9 @@ class FilterChooser {
423423 // / The "field value" here refers to the encoding bits in the filtered range.
424424 std::map<uint64_t , std::unique_ptr<const FilterChooser>> FilterChooserMap;
425425
426+ std::vector<unsigned > AllUnfilteredUnknownIDs;
427+ std::unique_ptr<const FilterChooser> SomeUnfilteredKnownFC;
428+
426429 // / Set to true if decoding conflict was encountered.
427430 bool HasConflict = false ;
428431
@@ -1434,6 +1437,58 @@ void FilterChooser::doFilter() {
14341437 return ;
14351438 }
14361439
1440+ // If we are unable to find the best filter, it generally means for all
1441+ // unfiltered bit positions, we have atleast one instruction that has that
1442+ // bit position unknown. Implement a heuristic to see if we can find
1443+ // instructions that have all unfiltered bits unknown. In such cases, we
1444+ // separate such insts and create a sub-chooser with the remaining
1445+ // instructions with atleast one unfiltered bit known. The idea is to
1446+ // give the remaining insts a first chance to decode since they assert more
1447+ // known bits than the ones with all unknown ones. If the sub-chooser with the
1448+ // remaining instructions is not able to decode, we decode the segregated
1449+ // instructions 1-by-1. That is, we generate:
1450+ //
1451+ // OPC_SCope {
1452+ // sub-chooser for unfiltered known bits;
1453+ // }
1454+ // OPC_Scope {
1455+ // decode unfiltered unknown 0
1456+ // }
1457+ // OPC_Scope {
1458+ // decode unfiltered unknown 1
1459+ // }
1460+ // decode unfiltered unknown (last)
1461+
1462+ unsigned FilterWidth = FilterBits.getBitWidth ();
1463+ std::vector<unsigned > SomeUnfilteredKnownIDs;
1464+ for (unsigned ID : EncodingIDs) {
1465+ bool AllUnfilteredUnknown = true ;
1466+ const InstructionEncoding &Encoding = Encodings[ID];
1467+ KnownBits EncodingBits = Encoding.getMandatoryBits ();
1468+ for (unsigned BitIndex = 0 ; BitIndex != FilterWidth; ++BitIndex) {
1469+ if (isPositionFiltered (BitIndex))
1470+ continue ;
1471+ // We are dealing with an unfiltered bits.
1472+ bool IsKnown = EncodingBits.Zero [BitIndex] || EncodingBits.One [BitIndex];
1473+ if (IsKnown) {
1474+ AllUnfilteredUnknown = false ;
1475+ break ;
1476+ }
1477+ }
1478+ if (AllUnfilteredUnknown) {
1479+ AllUnfilteredUnknownIDs.push_back (ID);
1480+ } else {
1481+ SomeUnfilteredKnownIDs.push_back (ID);
1482+ }
1483+ }
1484+
1485+ if (!AllUnfilteredUnknownIDs.empty ()) {
1486+ if (!SomeUnfilteredKnownIDs.empty ())
1487+ SomeUnfilteredKnownFC = std::make_unique<FilterChooser>(
1488+ Encodings, SomeUnfilteredKnownIDs, FilterBits, *this );
1489+ return ;
1490+ }
1491+
14371492 // Print out useful conflict information for postmortem analysis.
14381493 errs () << " Decoding Conflict:\n " ;
14391494 dump ();
@@ -1460,64 +1515,98 @@ void FilterChooser::dump() const {
14601515void DecoderTableBuilder::emitTableEntries (const FilterChooser &FC) const {
14611516 DecoderTable &Table = TableInfo.Table ;
14621517
1463- // If there are other encodings that could match if those with all bits
1464- // known don't, enter a scope so that they have a chance.
1465- size_t FixupLoc = 0 ;
1466- if (FC.VariableFC ) {
1467- Table.insertOpcode (OPC_Scope);
1468- FixupLoc = Table.insertNumToSkip ();
1469- }
1470-
14711518 if (FC.SingletonEncodingID ) {
14721519 assert (FC.FilterChooserMap .empty ());
14731520 // There is only one encoding in which all bits in the filtered range are
14741521 // fully defined, but we still need to check if the remaining (unfiltered)
14751522 // bits are valid for this encoding. We also need to check predicates etc.
14761523 emitSingletonTableEntry (FC);
1477- } else if (FC.FilterChooserMap .size () == 1 ) {
1478- // If there is only one possible field value, emit a combined OPC_CheckField
1479- // instead of OPC_ExtractField + OPC_FilterValue.
1480- const auto &[FilterVal, Delegate] = *FC.FilterChooserMap .begin ();
1481- Table.insertOpcode (OPC_CheckField);
1482- Table.insertULEB128 (FC.StartBit );
1483- Table.insertUInt8 (FC.NumBits );
1484- Table.insertULEB128 (FilterVal);
1485-
1486- // Emit table entries for the only case.
1487- emitTableEntries (*Delegate);
1488- } else {
1489- // The general case: emit a switch over the field value.
1490- Table.insertOpcode (OPC_ExtractField);
1491- Table.insertULEB128 (FC.StartBit );
1492- Table.insertUInt8 (FC.NumBits );
1493-
1494- // Emit switch cases for all but the last element.
1495- for (const auto &[FilterVal, Delegate] : drop_end (FC.FilterChooserMap )) {
1496- Table.insertOpcode (OPC_FilterValueOrSkip);
1524+ return ;
1525+ }
1526+
1527+ if (!FC.FilterChooserMap .empty ()) {
1528+ // If there are other encodings that could match if those with all bits
1529+ // known don't, enter a scope so that they have a chance.
1530+ size_t FixupLoc = 0 ;
1531+ if (FC.VariableFC ) {
1532+ Table.insertOpcode (OPC_Scope);
1533+ FixupLoc = Table.insertNumToSkip ();
1534+ }
1535+ if (FC.FilterChooserMap .size () == 1 ) {
1536+ // If there is only one possible field value, emit a combined
1537+ // OPC_CheckField instead of OPC_ExtractField + OPC_FilterValue.
1538+ const auto &[FilterVal, Delegate] = *FC.FilterChooserMap .begin ();
1539+ Table.insertOpcode (OPC_CheckField);
1540+ Table.insertULEB128 (FC.StartBit );
1541+ Table.insertUInt8 (FC.NumBits );
14971542 Table.insertULEB128 (FilterVal);
1498- size_t FixupPos = Table.insertNumToSkip ();
14991543
1500- // Emit table entries for this case.
1544+ // Emit table entries for the only case.
15011545 emitTableEntries (*Delegate);
1546+ } else {
1547+ // The general case: emit a switch over the field value.
1548+ Table.insertOpcode (OPC_ExtractField);
1549+ Table.insertULEB128 (FC.StartBit );
1550+ Table.insertUInt8 (FC.NumBits );
1551+
1552+ // Emit switch cases for all but the last element.
1553+ for (const auto &[FilterVal, Delegate] : drop_end (FC.FilterChooserMap )) {
1554+ Table.insertOpcode (OPC_FilterValueOrSkip);
1555+ Table.insertULEB128 (FilterVal);
1556+ size_t FixupPos = Table.insertNumToSkip ();
1557+
1558+ // Emit table entries for this case.
1559+ emitTableEntries (*Delegate);
1560+
1561+ // Patch the previous FilterValueOrSkip to fall through to the next
1562+ // case.
1563+ Table.patchNumToSkip (FixupPos, Table.size ());
1564+ }
15021565
1503- // Patch the previous FilterValueOrSkip to fall through to the next case.
1504- Table.patchNumToSkip (FixupPos, Table.size ());
1505- }
1566+ // Emit a switch case for the last element. It never falls through;
1567+ // if it doesn't match, we leave the current scope.
1568+ const auto &[FilterVal, Delegate] = *FC.FilterChooserMap .rbegin ();
1569+ Table.insertOpcode (OPC_FilterValue);
1570+ Table.insertULEB128 (FilterVal);
15061571
1507- // Emit a switch case for the last element. It never falls through;
1508- // if it doesn't match, we leave the current scope.
1509- const auto &[FilterVal, Delegate] = *FC.FilterChooserMap .rbegin ();
1510- Table.insertOpcode (OPC_FilterValue);
1511- Table.insertULEB128 (FilterVal);
1572+ // Emit table entries for the last case.
1573+ emitTableEntries (*Delegate);
1574+ }
15121575
1513- // Emit table entries for the last case.
1514- emitTableEntries (*Delegate);
1576+ if (FC.VariableFC ) {
1577+ Table.patchNumToSkip (FixupLoc, Table.size ());
1578+ emitTableEntries (*FC.VariableFC );
1579+ }
1580+ return ;
15151581 }
15161582
1517- if (FC.VariableFC ) {
1518- Table.patchNumToSkip (FixupLoc, Table.size ());
1519- emitTableEntries (*FC.VariableFC );
1583+ if (!FC.AllUnfilteredUnknownIDs .empty ()) {
1584+ if (FC.SomeUnfilteredKnownFC ) {
1585+ Table.insertOpcode (OPC_Scope);
1586+ size_t FixupLoc = Table.insertNumToSkip ();
1587+ emitTableEntries (*FC.SomeUnfilteredKnownFC );
1588+ Table.patchNumToSkip (FixupLoc, Table.size ());
1589+ }
1590+
1591+ // For each op in AllUnfilteredUnknownID, except the last one.
1592+ if (FC.AllUnfilteredUnknownIDs .size () > 1 ) {
1593+ for (unsigned ID : drop_end (FC.AllUnfilteredUnknownIDs )) {
1594+ Table.insertOpcode (OPC_Scope);
1595+ size_t FixupLoc = Table.insertNumToSkip ();
1596+ FilterChooser SingletonFC (FC.Encodings , ID, FC.FilterBits , FC);
1597+ emitSingletonTableEntry (SingletonFC);
1598+ Table.patchNumToSkip (FixupLoc, Table.size ());
1599+ }
1600+ }
1601+
1602+ // Last one has no scope.
1603+ unsigned LastID = FC.AllUnfilteredUnknownIDs .back ();
1604+ FilterChooser SingletonFC (FC.Encodings , LastID, FC.FilterBits , FC);
1605+ emitSingletonTableEntry (SingletonFC);
1606+ return ;
15201607 }
1608+
1609+ llvm_unreachable (" invalid filter chooser" );
15211610}
15221611
15231612// emitDecodeInstruction - Emit the templated helper function
0 commit comments