Skip to content

Commit 72b4e1e

Browse files
committed
[TableGen][DecoderEmitter] Use KnownBits for filter values (NFCI)
KnownBits is faster and smaller than std::vector<BitValue>. It is also more convenient to use.
1 parent 5794f99 commit 72b4e1e

File tree

1 file changed

+40
-46
lines changed

1 file changed

+40
-46
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "llvm/Support/ErrorHandling.h"
3535
#include "llvm/Support/FormatVariadic.h"
3636
#include "llvm/Support/FormattedStream.h"
37+
#include "llvm/Support/KnownBits.h"
3738
#include "llvm/Support/LEB128.h"
3839
#include "llvm/Support/MathExtras.h"
3940
#include "llvm/Support/raw_ostream.h"
@@ -101,6 +102,22 @@ STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");
101102

102103
static unsigned getNumToSkipInBytes() { return LargeTable ? 3 : 2; }
103104

105+
/// Similar to KnownBits::print(), but allows you to specify a character to use
106+
/// to print unknown bits.
107+
static void printKnownBits(raw_ostream &OS, const KnownBits &Bits,
108+
char Unknown) {
109+
for (unsigned I = Bits.getBitWidth(); I--;) {
110+
if (Bits.Zero[I] && Bits.One[I])
111+
OS << '!';
112+
else if (Bits.Zero[I])
113+
OS << '0';
114+
else if (Bits.One[I])
115+
OS << '1';
116+
else
117+
OS << Unknown;
118+
}
119+
}
120+
104121
namespace {
105122

106123
struct EncodingField {
@@ -314,15 +331,11 @@ class DecoderEmitter {
314331

315332
// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
316333
// for a bit value.
317-
//
318-
// BIT_UNFILTERED is used as the init value for a filter position. It is used
319-
// only for filter processings.
320334
struct BitValue {
321335
enum bit_value_t : uint8_t {
322-
BIT_FALSE, // '0'
323-
BIT_TRUE, // '1'
324-
BIT_UNSET, // '?', printed as '_'
325-
BIT_UNFILTERED // unfiltered, printed as '.'
336+
BIT_FALSE, // '0'
337+
BIT_TRUE, // '1'
338+
BIT_UNSET, // '?', printed as '_'
326339
};
327340

328341
BitValue(bit_value_t V) : V(V) {}
@@ -351,8 +364,6 @@ struct BitValue {
351364
return "1";
352365
case BIT_UNSET:
353366
return "_";
354-
case BIT_UNFILTERED:
355-
return ".";
356367
}
357368
llvm_unreachable("Unknow bit value");
358369
}
@@ -552,8 +563,8 @@ class FilterChooser {
552563
std::unique_ptr<Filter> BestFilter;
553564

554565
// Array of bit values passed down from our parent.
555-
// Set to all BIT_UNFILTERED's for Parent == NULL.
556-
std::vector<BitValue> FilterBitValues;
566+
// Set to all unknown for Parent == nullptr.
567+
KnownBits FilterBits;
557568

558569
// Links to the FilterChooser above us in the decoding tree.
559570
const FilterChooser *Parent;
@@ -574,19 +585,18 @@ class FilterChooser {
574585
FilterChooser(ArrayRef<InstructionEncoding> Encodings,
575586
ArrayRef<unsigned> EncodingIDs, unsigned BW,
576587
const DecoderEmitter *E)
577-
: Encodings(Encodings), EncodingIDs(EncodingIDs),
578-
FilterBitValues(BW, BitValue::BIT_UNFILTERED), Parent(nullptr),
579-
BitWidth(BW), Emitter(E) {
588+
: Encodings(Encodings), EncodingIDs(EncodingIDs), FilterBits(BW),
589+
Parent(nullptr), BitWidth(BW), Emitter(E) {
580590
doFilter();
581591
}
582592

583593
FilterChooser(ArrayRef<InstructionEncoding> Encodings,
584594
ArrayRef<unsigned> EncodingIDs,
585-
const std::vector<BitValue> &ParentFilterBitValues,
586-
const FilterChooser &parent)
595+
const KnownBits &ParentFilterBits, const FilterChooser &parent)
587596
: Encodings(Encodings), EncodingIDs(EncodingIDs),
588-
FilterBitValues(ParentFilterBitValues), Parent(&parent),
597+
FilterBits(ParentFilterBits), Parent(&parent),
589598
BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
599+
assert(!FilterBits.hasConflict() && "Broken filter");
590600
doFilter();
591601
}
592602

@@ -617,16 +627,12 @@ class FilterChooser {
617627
return Insn;
618628
}
619629

620-
/// dumpFilterArray - dumpFilterArray prints out debugging info for the given
621-
/// filter array as a series of chars.
622-
void dumpFilterArray(raw_ostream &OS, ArrayRef<BitValue> Filter) const;
623-
624630
/// dumpStack - dumpStack traverses the filter chooser chain and calls
625631
/// dumpFilterArray on each filter chooser up to the top level one.
626632
void dumpStack(raw_ostream &OS, indent Indent) const;
627633

628-
bool PositionFiltered(unsigned Idx) const {
629-
return FilterBitValues[Idx].isSet();
634+
bool isPositionFiltered(unsigned Idx) const {
635+
return FilterBits.Zero[Idx] || FilterBits.One[Idx];
630636
}
631637

632638
// Calculates the island(s) needed to decode the instruction.
@@ -740,16 +746,14 @@ Filter::Filter(const FilterChooser &owner, unsigned startBit, unsigned numBits)
740746
// match the remaining undecoded encoding bits against the singleton.
741747
void Filter::recurse() {
742748
// Starts by inheriting our parent filter chooser's filter bit values.
743-
std::vector<BitValue> BitValueArray(Owner.FilterBitValues);
749+
KnownBits FilterBits = Owner.FilterBits;
750+
assert(FilterBits.extractBits(NumBits, StartBit).isUnknown());
744751

745752
if (!VariableIDs.empty()) {
746-
for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
747-
BitValueArray[StartBit + bitIndex] = BitValue::BIT_UNFILTERED;
748-
749753
// Delegates to an inferior filter chooser for further processing on this
750754
// group of instructions whose segment values are variable.
751755
VariableFC = std::make_unique<FilterChooser>(Owner.Encodings, VariableIDs,
752-
BitValueArray, Owner);
756+
FilterBits, Owner);
753757
}
754758

755759
// No need to recurse for a singleton filtered instruction.
@@ -761,17 +765,15 @@ void Filter::recurse() {
761765

762766
// Otherwise, create sub choosers.
763767
for (const auto &[FilterVal, EncodingIDs] : FilteredIDs) {
764-
// Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
765-
for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex)
766-
BitValueArray[StartBit + bitIndex] = FilterVal & (1ULL << bitIndex)
767-
? BitValue::BIT_TRUE
768-
: BitValue::BIT_FALSE;
768+
// Create a new filter by inserting the field bits into the parent filter.
769+
APInt FieldBits(NumBits, FilterVal);
770+
FilterBits.insertBits(KnownBits::makeConstant(FieldBits), StartBit);
769771

770772
// Delegates to an inferior filter chooser for further processing on this
771773
// category of instructions.
772774
FilterChooserMap.try_emplace(
773775
FilterVal, std::make_unique<FilterChooser>(Owner.Encodings, EncodingIDs,
774-
BitValueArray, Owner));
776+
FilterBits, Owner));
775777
}
776778
}
777779

@@ -1143,21 +1145,13 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
11431145
OS << "}\n";
11441146
}
11451147

1146-
/// dumpFilterArray - dumpFilterArray prints out debugging info for the given
1147-
/// filter array as a series of chars.
1148-
void FilterChooser::dumpFilterArray(raw_ostream &OS,
1149-
ArrayRef<BitValue> Filter) const {
1150-
for (unsigned bitIndex = BitWidth; bitIndex > 0; bitIndex--)
1151-
OS << Filter[bitIndex - 1];
1152-
}
1153-
11541148
/// dumpStack - dumpStack traverses the filter chooser chain and calls
11551149
/// dumpFilterArray on each filter chooser up to the top level one.
11561150
void FilterChooser::dumpStack(raw_ostream &OS, indent Indent) const {
11571151
if (Parent)
11581152
Parent->dumpStack(OS, Indent);
11591153
OS << Indent;
1160-
dumpFilterArray(OS, FilterBitValues);
1154+
printKnownBits(OS, FilterBits, '.');
11611155
OS << '\n';
11621156
}
11631157

@@ -1178,7 +1172,7 @@ FilterChooser::getIslands(const insn_t &Insn) const {
11781172

11791173
for (unsigned i = 0; i < BitWidth; ++i) {
11801174
std::optional<uint64_t> Val = Insn[i].getValue();
1181-
bool Filtered = PositionFiltered(i);
1175+
bool Filtered = isPositionFiltered(i);
11821176
switch (State) {
11831177
default:
11841178
llvm_unreachable("Unreachable code!");
@@ -1750,9 +1744,9 @@ void FilterChooser::doFilter() {
17501744
SmallVector<bitAttr_t, 128> BitAttrs(BitWidth, ATTR_NONE);
17511745

17521746
// FILTERED bit positions provide no entropy and are not worthy of pursuing.
1753-
// Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position.
1747+
// Filter::recurse() set either 1 or 0 for each position.
17541748
for (unsigned BitIndex = 0; BitIndex < BitWidth; ++BitIndex)
1755-
if (FilterBitValues[BitIndex].isSet())
1749+
if (isPositionFiltered(BitIndex))
17561750
BitAttrs[BitIndex] = ATTR_FILTERED;
17571751

17581752
for (unsigned EncodingID : EncodingIDs) {

0 commit comments

Comments
 (0)