[llvm] [TableGen][DecoderEmitter] Improve conflicts dump (PR #154001)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 16 22:37:49 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-tablegen
Author: Sergei Barannikov (s-barannikov)
<details>
<summary>Changes</summary>
* Print filter stack in non-reversed order.
* Print encoding name to the right of encoding bits.
* Use the correct bit width when printing encoding bits.
Example of old output:
```
01000100........
01000...........
0100............
................
tADDhirr 000000000000000001000100________
tADDrSP 000000000000000001000100_1101___
tADDspr 0000000000000000010001001____101
```
New output:
```
................
0100............
01000...........
01000100........
01000100________ tADDhirr
01000100_1101___ tADDrSP
010001001____101 tADDspr
```
---
Full diff: https://github.com/llvm/llvm-project/pull/154001.diff
1 Files Affected:
- (modified) llvm/utils/TableGen/DecoderEmitter.cpp (+30-30)
``````````diff
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 7803509356419..b92f8d7940d43 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -319,9 +319,10 @@ static raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
}
// Prints the bit value for each position.
-static void dumpBits(raw_ostream &OS, const BitsInit &Bits) {
- for (const Init *Bit : reverse(Bits.getBits()))
- OS << BitValue(Bit);
+static void dumpBits(raw_ostream &OS, const BitsInit &Bits, unsigned BitWidth) {
+ iota_range<unsigned> BitIndices(0, BitWidth, /*Inclusive=*/false);
+ for (unsigned BitIndex : reverse(BitIndices))
+ OS << BitValue(Bits.getBit(BitIndex));
}
static const BitsInit &getBitsField(const Record &Def, StringRef FieldName) {
@@ -371,16 +372,16 @@ class FilterChooser;
///
/// An example of a conflict is
///
-/// Conflict:
-/// 111101000.00........00010000....
-/// 111101000.00........0001........
-/// 1111010...00........0001........
-/// 1111010...00....................
-/// 1111010.........................
-/// 1111............................
-/// ................................
-/// VST4q8a 111101000_00________00010000____
-/// VST4q8b 111101000_00________00010000____
+/// Decoding Conflict:
+/// ................................
+/// 1111............................
+/// 1111010.........................
+/// 1111010...00....................
+/// 1111010...00........0001........
+/// 111101000.00........0001........
+/// 111101000.00........00010000....
+/// 111101000_00________00010000____ VST4q8a
+/// 111101000_00________00010000____ VST4q8b
///
/// The Debug output shows the path that the decoding tree follows to reach the
/// the conclusion that there is a conflict. VST4q8a is a vst4 to double-spaced
@@ -573,7 +574,7 @@ class FilterChooser {
/// dumpStack - dumpStack traverses the filter chooser chain and calls
/// dumpFilterArray on each filter chooser up to the top level one.
- void dumpStack(raw_ostream &OS, const char *prefix) const;
+ void dumpStack(raw_ostream &OS, indent Indent) const;
bool PositionFiltered(unsigned Idx) const {
return FilterBitValues[Idx].isSet();
@@ -692,9 +693,8 @@ void Filter::recurse() {
std::vector<BitValue> BitValueArray(Owner.FilterBitValues);
if (!VariableInstructions.empty()) {
- // Conservatively marks each segment position as BIT_UNSET.
for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
- BitValueArray[StartBit + bitIndex] = BitValue::BIT_UNSET;
+ BitValueArray[StartBit + bitIndex] = BitValue::BIT_UNFILTERED;
// Delegates to an inferior filter chooser for further processing on this
// group of instructions whose segment values are variable.
@@ -1131,15 +1131,12 @@ void FilterChooser::dumpFilterArray(raw_ostream &OS,
/// dumpStack - dumpStack traverses the filter chooser chain and calls
/// dumpFilterArray on each filter chooser up to the top level one.
-void FilterChooser::dumpStack(raw_ostream &OS, const char *prefix) const {
- const FilterChooser *current = this;
-
- while (current) {
- OS << prefix;
- dumpFilterArray(OS, current->FilterBitValues);
- OS << '\n';
- current = current->Parent;
- }
+void FilterChooser::dumpStack(raw_ostream &OS, indent Indent) const {
+ if (Parent)
+ Parent->dumpStack(OS, Indent);
+ OS << Indent;
+ dumpFilterArray(OS, FilterBitValues);
+ OS << '\n';
}
// Calculates the island(s) needed to decode the instruction.
@@ -1778,13 +1775,16 @@ void FilterChooser::doFilter() {
// Print out useful conflict information for postmortem analysis.
errs() << "Decoding Conflict:\n";
- dumpStack(errs(), "\t\t");
+ // Dump filters.
+ indent Indent(4);
+ dumpStack(errs(), Indent);
- for (auto Opcode : Opcodes) {
+ // Dump encodings.
+ for (EncodingIDAndOpcode Opcode : Opcodes) {
const EncodingAndInst &Enc = AllInstructions[Opcode.EncodingID];
- errs() << '\t' << Enc << ' ';
- dumpBits(errs(), getBitsField(*Enc.EncodingDef, "Inst"));
- errs() << '\n';
+ errs() << Indent;
+ dumpBits(errs(), getBitsField(*Enc.EncodingDef, "Inst"), BitWidth);
+ errs() << " " << Enc << '\n';
}
PrintFatalError("Decoding conflict encountered");
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/154001
More information about the llvm-commits
mailing list