[llvm] [TableGen][DecoderEmitter] Turn EncodingAndInst into a class (NFC) (PR #154230)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 19 02:04:19 PDT 2025
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/154230
>From 9b009266cd843b76108a838664eb37422b3ab89c Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 19 Aug 2025 11:52:59 +0300
Subject: [PATCH] [TableGen][DecoderEmitter] Turn EncodingAndInst into a class
(NFC)
The class will get more methods in follow-up patches.
---
llvm/utils/TableGen/DecoderEmitter.cpp | 87 +++++++++++++++-----------
1 file changed, 52 insertions(+), 35 deletions(-)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index abf29f9d7beb9..7b7a58681492d 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -129,6 +129,38 @@ struct OperandInfo {
const_iterator end() const { return Fields.end(); }
};
+/// Represents a parsed InstructionEncoding record or a record derived from it.
+class InstructionEncoding {
+ /// The Record this encoding originates from.
+ const Record *EncodingDef;
+
+ /// The instruction this encoding is for.
+ const CodeGenInstruction *Inst;
+
+ /// The name of this encoding (for debugging purposes).
+ std::string Name;
+
+public:
+ InstructionEncoding(const Record *EncodingDef, const CodeGenInstruction *Inst)
+ : EncodingDef(EncodingDef), Inst(Inst) {
+ const Record *InstDef = Inst->TheDef;
+
+ // Give this encoding a name.
+ if (EncodingDef != InstDef)
+ Name = (EncodingDef->getName() + Twine(':')).str();
+ Name.append(InstDef->getName());
+ }
+
+ /// Returns the Record this encoding originates from.
+ const Record *getRecord() const { return EncodingDef; }
+
+ /// Returns the instruction this encoding is for.
+ const CodeGenInstruction *getInstruction() const { return Inst; }
+
+ /// Returns the name of this encoding, for debugging purposes.
+ StringRef getName() const { return Name; }
+};
+
typedef std::vector<uint32_t> FixupList;
typedef std::vector<FixupList> FixupScopeList;
typedef SmallSetVector<CachedHashString, 16> PredicateSet;
@@ -205,14 +237,6 @@ struct DecoderTableInfo {
}
};
-struct EncodingAndInst {
- const Record *EncodingDef;
- const CodeGenInstruction *Inst;
-
- EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst)
- : EncodingDef(EncodingDef), Inst(Inst) {}
-};
-
using NamespacesHwModesMap = std::map<std::string, std::set<unsigned>>;
class DecoderEmitter {
@@ -221,7 +245,7 @@ class DecoderEmitter {
const CodeGenHwModes &CGH;
/// All parsed encodings.
- std::vector<EncodingAndInst> Encodings;
+ std::vector<InstructionEncoding> Encodings;
/// Encodings IDs for each HwMode. An ID is an index into Encodings.
SmallDenseMap<unsigned, std::vector<unsigned>> EncodingIDsByHwMode;
@@ -316,13 +340,6 @@ struct BitValue {
} // end anonymous namespace
-static raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
- if (Value.EncodingDef != Value.Inst->TheDef)
- OS << Value.EncodingDef->getName() << ":";
- OS << Value.Inst->TheDef->getName();
- return OS;
-}
-
// Prints the bit value for each position.
static void dumpBits(raw_ostream &OS, const BitsInit &Bits, unsigned BitWidth) {
for (const Init *Bit : reverse(Bits.getBits().take_front(BitWidth)))
@@ -500,7 +517,7 @@ class FilterChooser {
friend class Filter;
// Vector of encodings to choose our filter.
- ArrayRef<EncodingAndInst> Encodings;
+ ArrayRef<InstructionEncoding> Encodings;
// Vector of encoding IDs for this filter chooser to work on.
ArrayRef<unsigned> EncodingIDs;
@@ -531,7 +548,7 @@ class FilterChooser {
};
public:
- FilterChooser(ArrayRef<EncodingAndInst> Encodings,
+ FilterChooser(ArrayRef<InstructionEncoding> Encodings,
ArrayRef<unsigned> EncodingIDs,
const std::map<unsigned, std::vector<OperandInfo>> &Ops,
unsigned BW, const DecoderEmitter *E)
@@ -541,7 +558,7 @@ class FilterChooser {
doFilter();
}
- FilterChooser(ArrayRef<EncodingAndInst> Encodings,
+ FilterChooser(ArrayRef<InstructionEncoding> Encodings,
ArrayRef<unsigned> EncodingIDs,
const std::map<unsigned, std::vector<OperandInfo>> &Ops,
const std::vector<BitValue> &ParentFilterBitValues,
@@ -560,7 +577,7 @@ class FilterChooser {
protected:
// Populates the insn given the uid.
insn_t insnWithID(unsigned EncodingID) const {
- const Record *EncodingDef = Encodings[EncodingID].EncodingDef;
+ const Record *EncodingDef = Encodings[EncodingID].getRecord();
const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
insn_t Insn(std::max(BitWidth, Bits.getNumBits()), BitValue::BIT_UNSET);
// We may have a SoftFail bitmask, which specifies a mask where an encoding
@@ -827,7 +844,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
DenseMap<unsigned, unsigned> OpcodeToEncodingID;
OpcodeToEncodingID.reserve(EncodingIDs.size());
for (unsigned EncodingID : EncodingIDs) {
- const Record *InstDef = Encodings[EncodingID].Inst->TheDef;
+ const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
OpcodeToEncodingID[Target.getInstrIntValue(InstDef)] = EncodingID;
}
@@ -978,7 +995,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
auto EncodingID = EncI->second;
if (!IsTry) {
- OS << "// Opcode: " << Encodings[EncodingID]
+ OS << "// Opcode: " << Encodings[EncodingID].getName()
<< ", DecodeIdx: " << DecodeIdx << '\n';
break;
}
@@ -986,7 +1003,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
// Fallthrough for OPC_TryDecode.
if (!IsFail) {
uint32_t NumToSkip = emitNumToSkip(I, OS);
- OS << "// Opcode: " << Encodings[EncodingID]
+ OS << "// Opcode: " << Encodings[EncodingID].getName()
<< ", DecodeIdx: " << DecodeIdx;
emitNumToSkipComment(NumToSkip, /*InComment=*/true);
}
@@ -1295,7 +1312,7 @@ bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
bool FilterChooser::emitPredicateMatch(raw_ostream &OS,
unsigned EncodingID) const {
const ListInit *Predicates =
- Encodings[EncodingID].EncodingDef->getValueAsListInit("Predicates");
+ Encodings[EncodingID].getRecord()->getValueAsListInit("Predicates");
bool IsFirstEmission = true;
for (unsigned i = 0; i < Predicates->size(); ++i) {
const Record *Pred = Predicates->getElementAsRecord(i);
@@ -1317,7 +1334,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &OS,
bool FilterChooser::doesOpcodeNeedPredicate(unsigned EncodingID) const {
const ListInit *Predicates =
- Encodings[EncodingID].EncodingDef->getValueAsListInit("Predicates");
+ Encodings[EncodingID].getRecord()->getValueAsListInit("Predicates");
for (unsigned i = 0; i < Predicates->size(); ++i) {
const Record *Pred = Predicates->getElementAsRecord(i);
if (!Pred->getValue("AssemblerMatcherPredicate"))
@@ -1374,7 +1391,7 @@ void FilterChooser::emitPredicateTableEntry(DecoderTableInfo &TableInfo,
void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
unsigned EncodingID) const {
- const Record *EncodingDef = Encodings[EncodingID].EncodingDef;
+ const Record *EncodingDef = Encodings[EncodingID].getRecord();
const RecordVal *RV = EncodingDef->getValue("SoftFail");
const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
@@ -1400,7 +1417,7 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
} else {
// The bit is not set; this must be an error!
errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in "
- << Encodings[EncodingID] << " is set but Inst{" << i
+ << Encodings[EncodingID].getName() << " is set but Inst{" << i
<< "} is unset!\n"
<< " - You can only mark a bit as SoftFail if it is fully defined"
<< " (1/0 - not '?') in Inst\n";
@@ -1473,7 +1490,7 @@ void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,
: MCD::OPC_TryDecode);
TableInfo.Table.push_back(DecoderOp);
NumEncodingsSupported++;
- const Record *InstDef = Encodings[EncodingID].Inst->TheDef;
+ const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
TableInfo.Table.insertULEB128(Emitter->getTarget().getInstrIntValue(InstDef));
TableInfo.Table.insertULEB128(DIdx);
@@ -1768,10 +1785,10 @@ void FilterChooser::doFilter() {
// Dump encodings.
for (unsigned EncodingID : EncodingIDs) {
- const EncodingAndInst &Enc = Encodings[EncodingID];
+ const InstructionEncoding &Enc = Encodings[EncodingID];
errs() << Indent;
- dumpBits(errs(), getBitsField(*Enc.EncodingDef, "Inst"), BitWidth);
- errs() << " " << Enc << '\n';
+ dumpBits(errs(), getBitsField(*Enc.getRecord(), "Inst"), BitWidth);
+ errs() << " " << Enc.getName() << '\n';
}
PrintFatalError("Decoding conflict encountered");
}
@@ -2437,7 +2454,7 @@ void DecoderEmitter::handleHwModesUnrelatedEncodings(
break;
}
case SUPPRESSION_LEVEL1: {
- const Record *InstDef = Encodings[EncodingID].Inst->TheDef;
+ const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
std::string DecoderNamespace =
InstDef->getValueAsString("DecoderNamespace").str();
auto It = NamespacesWithHwModes.find(DecoderNamespace);
@@ -2540,9 +2557,9 @@ namespace {
for (const auto &[HwModeID, EncodingIDs] : EncodingIDsByHwMode) {
for (unsigned EncodingID : EncodingIDs) {
- const EncodingAndInst &Encoding = Encodings[EncodingID];
- const Record *EncodingDef = Encoding.EncodingDef;
- const CodeGenInstruction *Inst = Encoding.Inst;
+ const InstructionEncoding &Encoding = Encodings[EncodingID];
+ const Record *EncodingDef = Encoding.getRecord();
+ const CodeGenInstruction *Inst = Encoding.getInstruction();
const Record *Def = Inst->TheDef;
unsigned Size = EncodingDef->getValueAsInt("Size");
if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
More information about the llvm-commits
mailing list