aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/DecoderEmitter.cpp
diff options
context:
space:
mode:
authorSergei Barannikov <barannikov88@gmail.com>2025-08-23 02:21:45 +0300
committerGitHub <noreply@github.com>2025-08-22 23:21:45 +0000
commit8aba413497e5eb11fb7f71ae5f13d3314e4d770a (patch)
treed916464a18d9568253fb7d9c45af255bf73bdc93 /llvm/utils/TableGen/DecoderEmitter.cpp
parent51d9f31954fefe3e372cec080429adfe3e464947 (diff)
downloadllvm-8aba413497e5eb11fb7f71ae5f13d3314e4d770a.zip
llvm-8aba413497e5eb11fb7f71ae5f13d3314e4d770a.tar.gz
llvm-8aba413497e5eb11fb7f71ae5f13d3314e4d770a.tar.bz2
[TableGen][DecoderEmitter] Extract a couple of methods (NFC) (#155044)
Extract `findBestFilter() const` searching for the best filter and move calls to `recurse()` out of it to a single place. Extract `dump()` as well, it is useful for debugging.
Diffstat (limited to 'llvm/utils/TableGen/DecoderEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/DecoderEmitter.cpp106
1 files changed, 55 insertions, 51 deletions
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index db984e7..ece92c7 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -609,19 +609,19 @@ protected:
void emitDecoder(raw_ostream &OS, indent Indent, unsigned EncodingID) const;
unsigned getDecoderIndex(DecoderSet &Decoders, unsigned EncodingID) const;
- // Assign a single filter and run with it.
- void runSingleFilter(unsigned startBit, unsigned numBit);
-
// reportRegion is a helper function for filterProcessor to mark a region as
// eligible for use as a filter region.
void reportRegion(std::vector<std::unique_ptr<Filter>> &Filters, bitAttr_t RA,
- unsigned StartBit, unsigned BitIndex, bool AllowMixed);
+ unsigned StartBit, unsigned BitIndex,
+ bool AllowMixed) const;
+
+ /// Scans the well-known encoding bits of the encodings and, builds up a list
+ /// of candidate filters, and then returns the best one, if any.
+ std::unique_ptr<Filter> findBestFilter(ArrayRef<bitAttr_t> BitAttrs,
+ bool AllowMixed,
+ bool Greedy = true) const;
- // FilterProcessor scans the well-known encoding bits of the instructions and
- // builds up a list of candidate filters. It chooses the best filter and
- // recursively descends down the decoding tree.
- bool filterProcessor(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
- bool Greedy = true);
+ std::unique_ptr<Filter> findBestFilter() const;
// Decides on the best configuration of filter(s) to use in order to decode
// the instructions. A conflict of instructions may occur, in which case we
@@ -632,6 +632,8 @@ public:
// emitTableEntries - Emit state machine entries to decode our share of
// instructions.
void emitTableEntries(DecoderTableInfo &TableInfo) const;
+
+ void dump() const;
};
} // end anonymous namespace
@@ -1446,28 +1448,19 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
Best.getVariableFC().emitTableEntries(TableInfo);
}
-// Assign a single filter and run with it. Top level API client can initialize
-// with a single filter to start the filtering process.
-void FilterChooser::runSingleFilter(unsigned startBit, unsigned numBit) {
- BestFilter = std::make_unique<Filter>(*this, startBit, numBit);
- BestFilter->recurse();
-}
-
// reportRegion is a helper function for filterProcessor to mark a region as
// eligible for use as a filter region.
void FilterChooser::reportRegion(std::vector<std::unique_ptr<Filter>> &Filters,
bitAttr_t RA, unsigned StartBit,
- unsigned BitIndex, bool AllowMixed) {
+ unsigned BitIndex, bool AllowMixed) const {
if (AllowMixed ? RA == ATTR_MIXED : RA == ATTR_ALL_SET)
Filters.push_back(
std::make_unique<Filter>(*this, StartBit, BitIndex - StartBit));
}
-// FilterProcessor scans the well-known encoding bits of the instructions and
-// builds up a list of candidate filters. It chooses the best filter and
-// recursively descends down the decoding tree.
-bool FilterChooser::filterProcessor(ArrayRef<bitAttr_t> BitAttrs,
- bool AllowMixed, bool Greedy) {
+std::unique_ptr<Filter>
+FilterChooser::findBestFilter(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
+ bool Greedy) const {
assert(EncodingIDs.size() >= 2 && "Nothing to filter");
// Heuristics. See also doFilter()'s "Heuristics" comment when num of
@@ -1483,8 +1476,8 @@ bool FilterChooser::filterProcessor(ArrayRef<bitAttr_t> BitAttrs,
std::vector<Island> Islands = getIslands(EncodingBits);
if (!Islands.empty()) {
// Found an instruction with island(s). Now just assign a filter.
- runSingleFilter(Islands[0].StartBit, Islands[0].NumBits);
- return true;
+ return std::make_unique<Filter>(*this, Islands[0].StartBit,
+ Islands[0].NumBits);
}
}
}
@@ -1623,24 +1616,12 @@ bool FilterChooser::filterProcessor(ArrayRef<bitAttr_t> BitAttrs,
}
if (AllUseless)
- return false;
-
- BestFilter = std::move(Filters[BestIndex]);
- BestFilter->recurse();
- return true;
-
-} // end of FilterChooser::filterProcessor(bool)
-
-// Decides on the best configuration of filter(s) to use in order to decode
-// the instructions. A conflict of instructions may occur, in which case we
-// dump the conflict set to the standard error.
-void FilterChooser::doFilter() {
- assert(!EncodingIDs.empty() && "FilterChooser created with no instructions");
+ return nullptr;
- // No filter needed.
- if (EncodingIDs.size() < 2)
- return;
+ return std::move(Filters[BestIndex]);
+}
+std::unique_ptr<Filter> FilterChooser::findBestFilter() const {
// We maintain BIT_WIDTH copies of the bitAttrs automaton.
// The automaton consumes the corresponding bit from each
// instruction.
@@ -1696,32 +1677,56 @@ void FilterChooser::doFilter() {
}
// Try regions of consecutive known bit values first.
- if (filterProcessor(BitAttrs, /*AllowMixed=*/false))
- return;
+ if (std::unique_ptr<Filter> F =
+ findBestFilter(BitAttrs, /*AllowMixed=*/false))
+ return F;
// Then regions of mixed bits (both known and unitialized bit values allowed).
- if (filterProcessor(BitAttrs, /*AllowMixed=*/true))
- return;
+ if (std::unique_ptr<Filter> F = findBestFilter(BitAttrs, /*AllowMixed=*/true))
+ return F;
// Heuristics to cope with conflict set {t2CMPrs, t2SUBSrr, t2SUBSrs} where
// no single instruction for the maximum ATTR_MIXED region Inst{14-4} has a
// well-known encoding pattern. In such case, we backtrack and scan for the
// the very first consecutive ATTR_ALL_SET region and assign a filter to it.
- if (EncodingIDs.size() == 3 &&
- filterProcessor(BitAttrs, /*AllowMixed=*/true, /*Greedy=*/false))
+ if (EncodingIDs.size() == 3) {
+ if (std::unique_ptr<Filter> F =
+ findBestFilter(BitAttrs, /*AllowMixed=*/true, /*Greedy=*/false))
+ return F;
+ }
+
+ // There is a conflict we could not resolve.
+ return nullptr;
+}
+
+// Decides on the best configuration of filter(s) to use in order to decode
+// the instructions. A conflict of instructions may occur, in which case we
+// dump the conflict set to the standard error.
+void FilterChooser::doFilter() {
+ assert(!EncodingIDs.empty() && "FilterChooser created with no instructions");
+
+ // No filter needed.
+ if (EncodingIDs.size() < 2)
return;
- // We don't know how to decode these instructions! Dump the
- // conflict set and bail.
- assert(!BestFilter);
+ BestFilter = findBestFilter();
+ if (BestFilter) {
+ BestFilter->recurse();
+ return;
+ }
// Print out useful conflict information for postmortem analysis.
errs() << "Decoding Conflict:\n";
+ dump();
+ PrintFatalError("Decoding conflict encountered");
+}
- // Dump filters.
+void FilterChooser::dump() const {
indent Indent(4);
// Helps to keep the output right-justified.
unsigned PadToWidth = getMaxEncodingWidth();
+
+ // Dump filter stack.
dumpStack(errs(), Indent, PadToWidth);
// Dump encodings.
@@ -1731,7 +1736,6 @@ void FilterChooser::doFilter() {
printKnownBits(errs(), Encoding.getMandatoryBits(), '_');
errs() << " " << Encoding.getName() << '\n';
}
- PrintFatalError("Decoding conflict encountered");
}
// emitTableEntries - Emit state machine entries to decode our share of