diff options
author | Sergei Barannikov <barannikov88@gmail.com> | 2025-08-23 02:21:45 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-22 23:21:45 +0000 |
commit | 8aba413497e5eb11fb7f71ae5f13d3314e4d770a (patch) | |
tree | d916464a18d9568253fb7d9c45af255bf73bdc93 /llvm/utils/TableGen/DecoderEmitter.cpp | |
parent | 51d9f31954fefe3e372cec080429adfe3e464947 (diff) | |
download | llvm-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.cpp | 106 |
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 |