[llvm] 9ae0bd2 - [TableGen][DecoderEmitter] Move Operands to InstructionEncoding (NFCI) (#154456)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 19 21:10:38 PDT 2025
Author: Sergei Barannikov
Date: 2025-08-20T07:10:34+03:00
New Revision: 9ae0bd2c9f98ee706ad278354b3c074566007fa0
URL: https://github.com/llvm/llvm-project/commit/9ae0bd2c9f98ee706ad278354b3c074566007fa0
DIFF: https://github.com/llvm/llvm-project/commit/9ae0bd2c9f98ee706ad278354b3c074566007fa0.diff
LOG: [TableGen][DecoderEmitter] Move Operands to InstructionEncoding (NFCI) (#154456)
This is where they belong, no need to maintain a separate map keyed by
encoding ID.
`populateInstruction()` has been made a member of `InstructionEncoding`
and is now called from the constructor.
Added:
Modified:
llvm/utils/TableGen/DecoderEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 945df0af47d88..1924cf8a3adcd 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -140,6 +140,12 @@ class InstructionEncoding {
/// The name of this encoding (for debugging purposes).
std::string Name;
+ /// The size of this encoding, in bits.
+ unsigned BitWidth;
+
+ /// Information about the operands' contribution to this encoding.
+ SmallVector<OperandInfo, 16> Operands;
+
public:
InstructionEncoding(const Record *EncodingDef, const CodeGenInstruction *Inst)
: EncodingDef(EncodingDef), Inst(Inst) {
@@ -149,6 +155,8 @@ class InstructionEncoding {
if (EncodingDef != InstDef)
Name = (EncodingDef->getName() + Twine(':')).str();
Name.append(InstDef->getName());
+
+ BitWidth = populateEncoding();
}
/// Returns the Record this encoding originates from.
@@ -159,6 +167,17 @@ class InstructionEncoding {
/// Returns the name of this encoding, for debugging purposes.
StringRef getName() const { return Name; }
+
+ /// Returns the size of this encoding, in bits.
+ unsigned getBitWidth() const { return BitWidth; }
+
+ /// Returns information about the operands' contribution to this encoding.
+ ArrayRef<OperandInfo> getOperands() const { return Operands; }
+
+private:
+ void populateVarLenEncoding();
+
+ unsigned populateEncoding();
};
typedef std::vector<uint32_t> FixupList;
@@ -522,9 +541,6 @@ class FilterChooser {
// Vector of encoding IDs for this filter chooser to work on.
ArrayRef<unsigned> EncodingIDs;
- // Lookup table for the operand decoding of instructions.
- const std::map<unsigned, std::vector<OperandInfo>> &Operands;
-
// The selected filter, if any.
std::unique_ptr<Filter> BestFilter;
@@ -549,10 +565,9 @@ class FilterChooser {
public:
FilterChooser(ArrayRef<InstructionEncoding> Encodings,
- ArrayRef<unsigned> EncodingIDs,
- const std::map<unsigned, std::vector<OperandInfo>> &Ops,
- unsigned BW, const DecoderEmitter *E)
- : Encodings(Encodings), EncodingIDs(EncodingIDs), Operands(Ops),
+ ArrayRef<unsigned> EncodingIDs, unsigned BW,
+ const DecoderEmitter *E)
+ : Encodings(Encodings), EncodingIDs(EncodingIDs),
FilterBitValues(BW, BitValue::BIT_UNFILTERED), Parent(nullptr),
BitWidth(BW), Emitter(E) {
doFilter();
@@ -560,10 +575,9 @@ class FilterChooser {
FilterChooser(ArrayRef<InstructionEncoding> Encodings,
ArrayRef<unsigned> EncodingIDs,
- const std::map<unsigned, std::vector<OperandInfo>> &Ops,
const std::vector<BitValue> &ParentFilterBitValues,
const FilterChooser &parent)
- : Encodings(Encodings), EncodingIDs(EncodingIDs), Operands(Ops),
+ : Encodings(Encodings), EncodingIDs(EncodingIDs),
FilterBitValues(ParentFilterBitValues), Parent(&parent),
BitWidth(parent.BitWidth), Emitter(parent.Emitter) {
doFilter();
@@ -728,8 +742,8 @@ void Filter::recurse() {
// Delegates to an inferior filter chooser for further processing on this
// group of instructions whose segment values are variable.
- VariableFC = std::make_unique<FilterChooser>(
- Owner.Encodings, VariableIDs, Owner.Operands, BitValueArray, Owner);
+ VariableFC = std::make_unique<FilterChooser>(Owner.Encodings, VariableIDs,
+ BitValueArray, Owner);
}
// No need to recurse for a singleton filtered instruction.
@@ -750,9 +764,8 @@ void Filter::recurse() {
// Delegates to an inferior filter chooser for further processing on this
// category of instructions.
FilterChooserMap.try_emplace(
- FilterVal,
- std::make_unique<FilterChooser>(Owner.Encodings, EncodingIDs,
- Owner.Operands, BitValueArray, Owner));
+ FilterVal, std::make_unique<FilterChooser>(Owner.Encodings, EncodingIDs,
+ BitValueArray, Owner));
}
}
@@ -1235,7 +1248,7 @@ bool FilterChooser::emitDecoder(raw_ostream &OS, indent Indent,
unsigned EncodingID) const {
bool HasCompleteDecoder = true;
- for (const OperandInfo &Op : Operands.find(EncodingID)->second) {
+ for (const OperandInfo &Op : Encodings[EncodingID].getOperands()) {
// If a custom instruction decoder was specified, use that.
if (Op.numFields() == 0 && !Op.Decoder.empty()) {
HasCompleteDecoder = Op.HasCompleteDecoder;
@@ -1849,9 +1862,7 @@ OperandInfo getOpInfo(const Record *TypeRecord) {
return OperandInfo(findOperandDecoderMethod(TypeRecord), HasCompleteDecoder);
}
-static void parseVarLenInstOperand(const Record *EncodingDef,
- std::vector<OperandInfo> &Operands,
- const CodeGenInstruction *Inst) {
+void InstructionEncoding::populateVarLenEncoding() {
const RecordVal *RV = EncodingDef->getValue("Inst");
VarLenInst VLI(cast<DagInit>(RV->getValue()), RV);
SmallVector<int> TiedTo;
@@ -1950,21 +1961,13 @@ static void addOneOperandFields(const Record *EncodingDef, const BitsInit &Bits,
}
}
-static unsigned populateInstruction(
- const CodeGenTarget &Target, const Record *EncodingDef,
- const CodeGenInstruction *Inst, unsigned EncodingID,
- std::map<unsigned, std::vector<OperandInfo>> &EncodingOperands,
- bool IsVarLenInst) {
+unsigned InstructionEncoding::populateEncoding() {
+ bool IsVarLenInst = isa<DagInit>(EncodingDef->getValueInit("Inst"));
const Record &Def = *Inst->TheDef;
- // If all the bit positions are not specified; do not decode this instruction.
- // We are bound to fail! For proper disassembly, the well-known encoding bits
- // of the instruction must be fully specified.
const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
- if (Bits.allInComplete())
- return 0;
-
- std::vector<OperandInfo> Operands;
+ assert(!Bits.allInComplete() &&
+ "Invalid encodings should have been filtered out");
// If the instruction has specified a custom decoding hook, use that instead
// of trying to auto-generate the decoder.
@@ -1973,7 +1976,6 @@ static unsigned populateInstruction(
bool HasCompleteInstDecoder =
EncodingDef->getValueAsBit("hasCompleteDecoder");
Operands.push_back(OperandInfo(InstDecoder.str(), HasCompleteInstDecoder));
- EncodingOperands[EncodingID] = std::move(Operands);
return Bits.getNumBits();
}
@@ -2014,7 +2016,7 @@ static unsigned populateInstruction(
}
if (IsVarLenInst) {
- parseVarLenInstOperand(EncodingDef, Operands, Inst);
+ populateVarLenEncoding();
} else {
// For each operand, see if we can figure out where it is encoded.
for (const auto &Op : InOutOperands) {
@@ -2095,7 +2097,6 @@ static unsigned populateInstruction(
Operands.push_back(std::move(OpInfo));
}
}
- EncodingOperands[EncodingID] = std::move(Operands);
#if 0
LLVM_DEBUG({
@@ -2606,22 +2607,16 @@ namespace {
emitInsertBits(OS);
emitCheck(OS);
- std::map<unsigned, std::vector<OperandInfo>> Operands;
+ // Do extra bookkeeping for variable-length encodings.
std::vector<unsigned> InstrLen;
bool IsVarLenInst = Target.hasVariableLengthEncodings();
- if (IsVarLenInst)
- InstrLen.resize(Target.getInstructions().size(), 0);
unsigned MaxInstLen = 0;
-
- for (auto [EncodingID, Encoding] : enumerate(Encodings)) {
- const Record *EncodingDef = Encoding.getRecord();
- const CodeGenInstruction *Inst = Encoding.getInstruction();
- unsigned BitWidth = populateInstruction(Target, EncodingDef, Inst,
- EncodingID, Operands, IsVarLenInst);
- assert(BitWidth && "Invalid encodings should have been filtered out");
- if (IsVarLenInst) {
- MaxInstLen = std::max(MaxInstLen, BitWidth);
- InstrLen[Target.getInstrIntValue(Inst->TheDef)] = BitWidth;
+ if (IsVarLenInst) {
+ InstrLen.resize(Target.getInstructions().size(), 0);
+ for (const InstructionEncoding &Encoding : Encodings) {
+ MaxInstLen = std::max(MaxInstLen, Encoding.getBitWidth());
+ InstrLen[Target.getInstrIntValue(Encoding.getInstruction()->TheDef)] =
+ Encoding.getBitWidth();
}
}
@@ -2645,7 +2640,7 @@ namespace {
auto [DecoderNamespace, HwModeID, Size] = Key;
const unsigned BitWidth = IsVarLenInst ? MaxInstLen : 8 * Size;
// Emit the decoder for this (namespace, hwmode, width) combination.
- FilterChooser FC(Encodings, EncodingIDs, Operands, BitWidth, this);
+ FilterChooser FC(Encodings, EncodingIDs, BitWidth, this);
// The decode table is cleared for each top level decoder function. The
// predicates and decoders themselves, however, are shared across all
More information about the llvm-commits
mailing list