[llvm] [TableGen][DecoderEmitter] Replace opcode mask with booleans (NFC) (PR #159113)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 16 08:46:24 PDT 2025
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/159113
>From eeb8c147fefeb1f204397113457aa1e3463ba06f Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 16 Sep 2025 18:24:42 +0300
Subject: [PATCH 1/3] [TableGen][DecoderEmitter] Replace opcode mask with
booleans (NFC)
To make the future diff smaller.
---
llvm/utils/TableGen/DecoderEmitter.cpp | 59 ++++++++++++--------------
1 file changed, 28 insertions(+), 31 deletions(-)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 95146a1e6c313..1a5712199f1ee 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -226,6 +226,9 @@ struct DecoderTableInfo {
DecoderTable Table;
PredicateSet Predicates;
DecoderSet Decoders;
+ bool HasSoftFail;
+ bool HasCheckPredicate;
+ bool HasTryDecode;
void insertPredicate(StringRef Predicate) {
Predicates.insert(CachedHashString(Predicate));
@@ -266,11 +269,10 @@ class DecoderEmitter {
const CodeGenTarget &getTarget() const { return Target; }
- // Emit the decoder state machine table. Returns a mask of MCD decoder ops
- // that were emitted.
- unsigned emitTable(formatted_raw_ostream &OS, DecoderTable &Table,
- StringRef Namespace, unsigned HwModeID, unsigned BitWidth,
- ArrayRef<unsigned> EncodingIDs) const;
+ // Emit the decoder state machine table.
+ void emitTable(formatted_raw_ostream &OS, DecoderTableInfo &TableInfo,
+ StringRef Namespace, unsigned HwModeID, unsigned BitWidth,
+ ArrayRef<unsigned> EncodingIDs) const;
void emitInstrLenTable(formatted_raw_ostream &OS,
ArrayRef<unsigned> InstrLen) const;
void emitPredicateFunction(formatted_raw_ostream &OS,
@@ -629,12 +631,11 @@ static StringRef getDecoderOpName(DecoderOps Op) {
llvm_unreachable("Unknown decoder op");
}
-// Emit the decoder state machine table. Returns a mask of MCD decoder ops
-// that were emitted.
-unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
- DecoderTable &Table, StringRef Namespace,
- unsigned HwModeID, unsigned BitWidth,
- ArrayRef<unsigned> EncodingIDs) const {
+// Emit the decoder state machine table.
+void DecoderEmitter::emitTable(formatted_raw_ostream &OS,
+ DecoderTableInfo &TableInfo, StringRef Namespace,
+ unsigned HwModeID, unsigned BitWidth,
+ ArrayRef<unsigned> EncodingIDs) const {
// We'll need to be able to map from a decoded opcode into the corresponding
// EncodingID for this specific combination of BitWidth and Namespace. This
// is used below to index into Encodings.
@@ -648,7 +649,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << "static const uint8_t DecoderTable" << Namespace;
if (HwModeID != DefaultMode)
OS << '_' << Target.getHwModes().getModeName(HwModeID);
- OS << BitWidth << "[" << Table.size() << "] = {\n";
+ OS << BitWidth << "[" << TableInfo.Table.size() << "] = {\n";
// Emit ULEB128 encoded value to OS, returning the number of bytes emitted.
auto EmitULEB128 = [](DecoderTable::const_iterator &I,
@@ -678,6 +679,7 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
// FIXME: We may be able to use the NumToSkip values to recover
// appropriate indentation levels.
+ DecoderTable &Table = TableInfo.Table;
DecoderTable::const_iterator I = Table.begin();
DecoderTable::const_iterator E = Table.end();
const uint8_t *const EndPtr = Table.data() + Table.size();
@@ -826,8 +828,6 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
OS << '\n';
}
OS << "};\n\n";
-
- return OpcodeMask;
}
void DecoderEmitter::emitInstrLenTable(formatted_raw_ostream &OS,
@@ -1114,6 +1114,7 @@ void DecoderTableBuilder::emitPredicateTableEntry(unsigned EncodingID) const {
TableInfo.Table.insertOpcode(OPC_CheckPredicate);
TableInfo.Table.insertULEB128(PredicateIndex);
+ TableInfo.HasCheckPredicate = true;
}
void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
@@ -1130,6 +1131,7 @@ void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
TableInfo.Table.insertOpcode(OPC_SoftFail);
TableInfo.Table.insertULEB128(PositiveMask.getZExtValue());
TableInfo.Table.insertULEB128(NegativeMask.getZExtValue());
+ TableInfo.HasCheckPredicate = true;
}
// Emits table entries to decode the singleton.
@@ -1180,6 +1182,8 @@ void DecoderTableBuilder::emitSingletonTableEntry(
const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
TableInfo.Table.insertULEB128(Target.getInstrIntValue(InstDef));
TableInfo.Table.insertULEB128(DecoderIndex);
+ if (DecoderOp == OPC_TryDecode)
+ TableInfo.HasTryDecode = true;
}
std::unique_ptr<Filter>
@@ -1523,11 +1527,7 @@ void DecoderTableBuilder::emitTableEntries(const FilterChooser &FC) const {
// emitDecodeInstruction - Emit the templated helper function
// decodeInstruction().
static void emitDecodeInstruction(formatted_raw_ostream &OS, bool IsVarLenInst,
- unsigned OpcodeMask) {
- const bool HasTryDecode = OpcodeMask & (1 << OPC_TryDecode);
- const bool HasCheckPredicate = OpcodeMask & (1 << OPC_CheckPredicate);
- const bool HasSoftFail = OpcodeMask & (1 << OPC_SoftFail);
-
+ const DecoderTableInfo &TableInfo) {
OS << R"(
static unsigned decodeNumToSkip(const uint8_t *&Ptr) {
unsigned NumToSkip = *Ptr++;
@@ -1548,7 +1548,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
"llvm::function_ref<void(APInt &, uint64_t)> makeUp";
}
OS << ") {\n";
- if (HasCheckPredicate)
+ if (TableInfo.HasCheckPredicate)
OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n";
OS << " const uint8_t *Ptr = DecodeTable;\n";
@@ -1657,7 +1657,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
}
break;
})";
- if (HasCheckPredicate) {
+ if (TableInfo.HasCheckPredicate) {
OS << R"(
case OPC_CheckPredicate: {
// Decode the Predicate Index value.
@@ -1701,7 +1701,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
<< (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
return S;
})";
- if (HasTryDecode) {
+ if (TableInfo.HasTryDecode) {
OS << R"(
case OPC_TryDecode: {
// Decode the Opcode value.
@@ -1735,7 +1735,7 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
break;
})";
}
- if (HasSoftFail) {
+ if (TableInfo.HasSoftFail) {
OS << R"(
case OPC_SoftFail: {
// Decode the mask values.
@@ -1994,9 +1994,8 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
// Entries in `EncMap` are already sorted by bitwidth. So bucketing per
// bitwidth can be done on-the-fly as we iterate over the map.
- DecoderTableInfo TableInfo;
+ DecoderTableInfo TableInfo{};
DecoderTableBuilder TableBuilder(Target, Encodings, TableInfo);
- unsigned OpcodeMask = 0;
bool HasConflict = false;
for (const auto &[BitWidth, BWMap] : EncMap) {
@@ -2021,8 +2020,8 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
TableBuilder.buildTable(FC, BitWidth);
// Print the table to the output stream.
- OpcodeMask |= emitTable(OS, TableInfo.Table, DecoderNamespace, HwModeID,
- BitWidth, EncodingIDs);
+ emitTable(OS, TableInfo, DecoderNamespace, HwModeID, BitWidth,
+ EncodingIDs);
}
// Each BitWidth get's its own decoders and decoder function if
@@ -2041,14 +2040,12 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
if (!SpecializeDecodersPerBitwidth)
emitDecoderFunction(OS, TableInfo.Decoders, 0);
- const bool HasCheckPredicate = OpcodeMask & (1 << OPC_CheckPredicate);
-
// Emit the predicate function.
- if (HasCheckPredicate)
+ if (TableInfo.HasCheckPredicate)
emitPredicateFunction(OS, TableInfo.Predicates);
// Emit the main entry point for the decoder, decodeInstruction().
- emitDecodeInstruction(OS, IsVarLenInst, OpcodeMask);
+ emitDecodeInstruction(OS, IsVarLenInst, TableInfo);
OS << "\n} // namespace\n";
}
>From 4c47f47b2d479c36ec2f18fffa8fb4a5b69db331 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 16 Sep 2025 18:32:30 +0300
Subject: [PATCH 2/3] Review comments
---
llvm/utils/TableGen/DecoderEmitter.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 1a5712199f1ee..65af4d760f70f 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -1131,7 +1131,7 @@ void DecoderTableBuilder::emitSoftFailTableEntry(unsigned EncodingID) const {
TableInfo.Table.insertOpcode(OPC_SoftFail);
TableInfo.Table.insertULEB128(PositiveMask.getZExtValue());
TableInfo.Table.insertULEB128(NegativeMask.getZExtValue());
- TableInfo.HasCheckPredicate = true;
+ TableInfo.HasSoftFail = true;
}
// Emits table entries to decode the singleton.
@@ -1182,8 +1182,7 @@ void DecoderTableBuilder::emitSingletonTableEntry(
const Record *InstDef = Encodings[EncodingID].getInstruction()->TheDef;
TableInfo.Table.insertULEB128(Target.getInstrIntValue(InstDef));
TableInfo.Table.insertULEB128(DecoderIndex);
- if (DecoderOp == OPC_TryDecode)
- TableInfo.HasTryDecode = true;
+ TableInfo.HasTryDecode |= DecoderOp == OPC_TryDecode;
}
std::unique_ptr<Filter>
>From 3816c48b7edd14c97c7f922b6bba0f97bafdeca5 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Tue, 16 Sep 2025 18:43:42 +0300
Subject: [PATCH 3/3] Remove unused variable
---
llvm/utils/TableGen/DecoderEmitter.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 65af4d760f70f..0f3ee5a2f7717 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -721,15 +721,12 @@ void DecoderEmitter::emitTable(formatted_raw_ostream &OS,
return Value;
};
- unsigned OpcodeMask = 0;
-
while (I != E) {
assert(I < E && "incomplete decode table entry!");
uint32_t Pos = I - Table.begin();
EmitPos(Pos);
const uint8_t DecoderOp = *I++;
- OpcodeMask |= (1 << DecoderOp);
OS << getDecoderOpName(static_cast<DecoderOps>(DecoderOp)) << ", ";
switch (DecoderOp) {
default:
More information about the llvm-commits
mailing list