Skip to content

Commit 56681c9

Browse files
authored
[TableGen][DecoderEmitter] Compute bit attribute once (NFC) (#153530)
Pull the logic to compute bit attributes from `filterProcessor()` to its caller to avoid recomputing them on the second call.
1 parent 8582025 commit 56681c9

File tree

1 file changed

+65
-62
lines changed

1 file changed

+65
-62
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 65 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,8 @@ class FilterChooser {
623623
// FilterProcessor scans the well-known encoding bits of the instructions and
624624
// builds up a list of candidate filters. It chooses the best filter and
625625
// recursively descends down the decoding tree.
626-
bool filterProcessor(bool AllowMixed, bool Greedy = true);
626+
bool filterProcessor(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
627+
bool Greedy = true);
627628

628629
// Decides on the best configuration of filter(s) to use in order to decode
629630
// the instructions. A conflict of instructions may occur, in which case we
@@ -1550,15 +1551,12 @@ void FilterChooser::reportRegion(bitAttr_t RA, unsigned StartBit,
15501551
// FilterProcessor scans the well-known encoding bits of the instructions and
15511552
// builds up a list of candidate filters. It chooses the best filter and
15521553
// recursively descends down the decoding tree.
1553-
bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
1554+
bool FilterChooser::filterProcessor(ArrayRef<bitAttr_t> BitAttrs,
1555+
bool AllowMixed, bool Greedy) {
15541556
Filters.clear();
15551557
BestIndex = -1;
15561558

1557-
assert(!Opcodes.empty() && "Filter created with no instructions");
1558-
1559-
// No further filtering is necessary.
1560-
if (Opcodes.size() == 1)
1561-
return true;
1559+
assert(Opcodes.size() >= 2 && "Nothing to filter");
15621560

15631561
// Heuristics. See also doFilter()'s "Heuristics" comment when num of
15641562
// instructions is 3.
@@ -1578,57 +1576,6 @@ bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
15781576
}
15791577
}
15801578

1581-
// We maintain BIT_WIDTH copies of the bitAttrs automaton.
1582-
// The automaton consumes the corresponding bit from each
1583-
// instruction.
1584-
//
1585-
// Input symbols: 0, 1, and _ (unset).
1586-
// States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
1587-
// Initial state: NONE.
1588-
//
1589-
// (NONE) ------- [01] -> (ALL_SET)
1590-
// (NONE) ------- _ ----> (ALL_UNSET)
1591-
// (ALL_SET) ---- [01] -> (ALL_SET)
1592-
// (ALL_SET) ---- _ ----> (MIXED)
1593-
// (ALL_UNSET) -- [01] -> (MIXED)
1594-
// (ALL_UNSET) -- _ ----> (ALL_UNSET)
1595-
// (MIXED) ------ . ----> (MIXED)
1596-
// (FILTERED)---- . ----> (FILTERED)
1597-
1598-
std::vector<bitAttr_t> bitAttrs(BitWidth, ATTR_NONE);
1599-
1600-
// FILTERED bit positions provide no entropy and are not worthy of pursuing.
1601-
// Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
1602-
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
1603-
if (FilterBitValues[BitIndex].isSet())
1604-
bitAttrs[BitIndex] = ATTR_FILTERED;
1605-
1606-
for (const auto &OpcPair : Opcodes) {
1607-
insn_t insn = insnWithID(OpcPair.EncodingID);
1608-
1609-
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1610-
switch (bitAttrs[BitIndex]) {
1611-
case ATTR_NONE:
1612-
if (insn[BitIndex] == BitValue::BIT_UNSET)
1613-
bitAttrs[BitIndex] = ATTR_ALL_UNSET;
1614-
else
1615-
bitAttrs[BitIndex] = ATTR_ALL_SET;
1616-
break;
1617-
case ATTR_ALL_SET:
1618-
if (insn[BitIndex] == BitValue::BIT_UNSET)
1619-
bitAttrs[BitIndex] = ATTR_MIXED;
1620-
break;
1621-
case ATTR_ALL_UNSET:
1622-
if (insn[BitIndex] != BitValue::BIT_UNSET)
1623-
bitAttrs[BitIndex] = ATTR_MIXED;
1624-
break;
1625-
case ATTR_MIXED:
1626-
case ATTR_FILTERED:
1627-
break;
1628-
}
1629-
}
1630-
}
1631-
16321579
// The regionAttr automaton consumes the bitAttrs automatons' state,
16331580
// lowest-to-highest.
16341581
//
@@ -1653,7 +1600,7 @@ bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
16531600
unsigned StartBit = 0;
16541601

16551602
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1656-
bitAttr_t bitAttr = bitAttrs[BitIndex];
1603+
bitAttr_t bitAttr = BitAttrs[BitIndex];
16571604

16581605
assert(bitAttr != ATTR_NONE && "Bit without attributes");
16591606

@@ -1772,19 +1719,75 @@ bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) {
17721719
void FilterChooser::doFilter() {
17731720
assert(!Opcodes.empty() && "FilterChooser created with no instructions");
17741721

1722+
// No filter needed.
1723+
if (Opcodes.size() < 2)
1724+
return;
1725+
1726+
// We maintain BIT_WIDTH copies of the bitAttrs automaton.
1727+
// The automaton consumes the corresponding bit from each
1728+
// instruction.
1729+
//
1730+
// Input symbols: 0, 1, _ (unset), and . (any of the above).
1731+
// States: NONE, FILTERED, ALL_SET, ALL_UNSET, and MIXED.
1732+
// Initial state: NONE.
1733+
//
1734+
// (NONE) ------- [01] -> (ALL_SET)
1735+
// (NONE) ------- _ ----> (ALL_UNSET)
1736+
// (ALL_SET) ---- [01] -> (ALL_SET)
1737+
// (ALL_SET) ---- _ ----> (MIXED)
1738+
// (ALL_UNSET) -- [01] -> (MIXED)
1739+
// (ALL_UNSET) -- _ ----> (ALL_UNSET)
1740+
// (MIXED) ------ . ----> (MIXED)
1741+
// (FILTERED)---- . ----> (FILTERED)
1742+
1743+
SmallVector<bitAttr_t, 128> BitAttrs(BitWidth, ATTR_NONE);
1744+
1745+
// FILTERED bit positions provide no entropy and are not worthy of pursuing.
1746+
// Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
1747+
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
1748+
if (FilterBitValues[BitIndex].isSet())
1749+
BitAttrs[BitIndex] = ATTR_FILTERED;
1750+
1751+
for (const EncodingIDAndOpcode &OpcPair : Opcodes) {
1752+
insn_t EncodingBits = insnWithID(OpcPair.EncodingID);
1753+
1754+
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {
1755+
switch (BitAttrs[BitIndex]) {
1756+
case ATTR_NONE:
1757+
if (EncodingBits[BitIndex] == BitValue::BIT_UNSET)
1758+
BitAttrs[BitIndex] = ATTR_ALL_UNSET;
1759+
else
1760+
BitAttrs[BitIndex] = ATTR_ALL_SET;
1761+
break;
1762+
case ATTR_ALL_SET:
1763+
if (EncodingBits[BitIndex] == BitValue::BIT_UNSET)
1764+
BitAttrs[BitIndex] = ATTR_MIXED;
1765+
break;
1766+
case ATTR_ALL_UNSET:
1767+
if (EncodingBits[BitIndex] != BitValue::BIT_UNSET)
1768+
BitAttrs[BitIndex] = ATTR_MIXED;
1769+
break;
1770+
case ATTR_MIXED:
1771+
case ATTR_FILTERED:
1772+
break;
1773+
}
1774+
}
1775+
}
1776+
17751777
// Try regions of consecutive known bit values first.
1776-
if (filterProcessor(false))
1778+
if (filterProcessor(BitAttrs, /*AllowMixed=*/false))
17771779
return;
17781780

17791781
// Then regions of mixed bits (both known and unitialized bit values allowed).
1780-
if (filterProcessor(true))
1782+
if (filterProcessor(BitAttrs, /*AllowMixed=*/true))
17811783
return;
17821784

17831785
// Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
17841786
// no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
17851787
// well-known encoding pattern. In such case, we backtrack and scan for the
17861788
// the very first consecutive ATTR_ALL_SET region and assign a filter to it.
1787-
if (Opcodes.size() == 3 && filterProcessor(true, false))
1789+
if (Opcodes.size() == 3 &&
1790+
filterProcessor(BitAttrs, /*AllowMixed=*/true, /*Greedy=*/false))
17881791
return;
17891792

17901793
// If we come to here, the instruction decoding has failed.

0 commit comments

Comments
 (0)