[llvm] 56ce40b - [TableGen][DecoderEmitter] Stop duplicating encodings (NFC) (#154288)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 19 02:02:25 PDT 2025
Author: Sergei Barannikov
Date: 2025-08-19T09:02:22Z
New Revision: 56ce40bc7378d8d8d94ec788a9d589b1ad990dc7
URL: https://github.com/llvm/llvm-project/commit/56ce40bc7378d8d8d94ec788a9d589b1ad990dc7
DIFF: https://github.com/llvm/llvm-project/commit/56ce40bc7378d8d8d94ec788a9d589b1ad990dc7.diff
LOG: [TableGen][DecoderEmitter] Stop duplicating encodings (NFC) (#154288)
When HwModes are involved, we can duplicate an instruction encoding that
does not belong to any HwMode multiple times. We can do better by
mapping HwMode to a list of encoding IDs it contains. (That is,
duplicate IDs instead of encodings.)
The encodings that were duplicated are still processed multiple times
(e.g., we call an expensive populateInstruction() on each instance).
This is going to be fixed in subsequent patches.
Added:
Modified:
llvm/utils/TableGen/DecoderEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 0634fac72bd18..abf29f9d7beb9 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -208,11 +208,9 @@ struct DecoderTableInfo {
struct EncodingAndInst {
const Record *EncodingDef;
const CodeGenInstruction *Inst;
- unsigned HwModeID;
- EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
- unsigned HwModeID = DefaultMode)
- : EncodingDef(EncodingDef), Inst(Inst), HwModeID(HwModeID) {}
+ EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst)
+ : EncodingDef(EncodingDef), Inst(Inst) {}
};
using NamespacesHwModesMap = std::map<std::string, std::set<unsigned>>;
@@ -221,8 +219,13 @@ class DecoderEmitter {
const RecordKeeper &RK;
CodeGenTarget Target;
const CodeGenHwModes &CGH;
+
+ /// All parsed encodings.
std::vector<EncodingAndInst> Encodings;
+ /// Encodings IDs for each HwMode. An ID is an index into Encodings.
+ SmallDenseMap<unsigned, std::vector<unsigned>> EncodingIDsByHwMode;
+
public:
DecoderEmitter(const RecordKeeper &RK, StringRef PredicateNamespace);
@@ -249,7 +252,7 @@ class DecoderEmitter {
NamespacesHwModesMap &NamespacesWithHwModes) const;
void
- handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
+ handleHwModesUnrelatedEncodings(unsigned EncodingID,
ArrayRef<unsigned> HwModeIDs,
NamespacesHwModesMap &NamespacesWithHwModes);
@@ -2425,32 +2428,31 @@ void DecoderEmitter::collectHwModesReferencedForEncodings(
}
void DecoderEmitter::handleHwModesUnrelatedEncodings(
- const CodeGenInstruction *Instr, ArrayRef<unsigned> HwModeIDs,
+ unsigned EncodingID, ArrayRef<unsigned> HwModeIDs,
NamespacesHwModesMap &NamespacesWithHwModes) {
- const Record *InstDef = Instr->TheDef;
-
switch (DecoderEmitterSuppressDuplicates) {
case SUPPRESSION_DISABLE: {
for (unsigned HwModeID : HwModeIDs)
- Encodings.emplace_back(InstDef, Instr, HwModeID);
+ EncodingIDsByHwMode[HwModeID].push_back(EncodingID);
break;
}
case SUPPRESSION_LEVEL1: {
+ const Record *InstDef = Encodings[EncodingID].Inst->TheDef;
std::string DecoderNamespace =
InstDef->getValueAsString("DecoderNamespace").str();
auto It = NamespacesWithHwModes.find(DecoderNamespace);
if (It != NamespacesWithHwModes.end()) {
for (unsigned HwModeID : It->second)
- Encodings.emplace_back(InstDef, Instr, HwModeID);
+ EncodingIDsByHwMode[HwModeID].push_back(EncodingID);
} else {
// Only emit the encoding once, as it's DecoderNamespace doesn't
// contain any HwModes.
- Encodings.emplace_back(InstDef, Instr, DefaultMode);
+ EncodingIDsByHwMode[DefaultMode].push_back(EncodingID);
}
break;
}
case SUPPRESSION_LEVEL2:
- Encodings.emplace_back(InstDef, Instr, DefaultMode);
+ EncodingIDsByHwMode[DefaultMode].push_back(EncodingID);
break;
}
}
@@ -2474,13 +2476,21 @@ void DecoderEmitter::parseInstructionEncodings() {
const Record *InstDef = Inst->TheDef;
if (const Record *RV = InstDef->getValueAsOptionalDef("EncodingInfos")) {
EncodingInfoByHwMode EBM(RV, CGH);
- for (auto [HwModeID, EncodingDef] : EBM)
- Encodings.emplace_back(EncodingDef, Inst, HwModeID);
+ for (auto [HwModeID, EncodingDef] : EBM) {
+ unsigned EncodingID = Encodings.size();
+ Encodings.emplace_back(EncodingDef, Inst);
+ EncodingIDsByHwMode[HwModeID].push_back(EncodingID);
+ }
continue;
}
+
+ unsigned EncodingID = Encodings.size();
+ Encodings.emplace_back(InstDef, Inst);
+
// This instruction is encoded the same on all HwModes.
- // According to user needs, provide varying degrees of suppression.
- handleHwModesUnrelatedEncodings(Inst, HwModeIDs, NamespacesWithHwModes);
+ // According to user needs, add it to all, some, or only the default HwMode.
+ handleHwModesUnrelatedEncodings(EncodingID, HwModeIDs,
+ NamespacesWithHwModes);
}
for (const Record *EncodingDef :
@@ -2528,35 +2538,39 @@ namespace {
InstrLen.resize(Target.getInstructions().size(), 0);
unsigned MaxInstLen = 0;
- for (const auto &[EncodingID, Encoding] : enumerate(Encodings)) {
- const Record *EncodingDef = Encoding.EncodingDef;
- const CodeGenInstruction *Inst = Encoding.Inst;
- const Record *Def = Inst->TheDef;
- unsigned Size = EncodingDef->getValueAsInt("Size");
- if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
- Def->getValueAsBit("isPseudo") ||
- Def->getValueAsBit("isAsmParserOnly") ||
- Def->getValueAsBit("isCodeGenOnly")) {
- NumEncodingsLackingDisasm++;
- continue;
- }
+ 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 Record *Def = Inst->TheDef;
+ unsigned Size = EncodingDef->getValueAsInt("Size");
+ if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
+ Def->getValueAsBit("isPseudo") ||
+ Def->getValueAsBit("isAsmParserOnly") ||
+ Def->getValueAsBit("isCodeGenOnly")) {
+ NumEncodingsLackingDisasm++;
+ continue;
+ }
- NumEncodings++;
+ NumEncodings++;
- if (!Size && !IsVarLenInst)
- continue;
+ if (!Size && !IsVarLenInst)
+ continue;
- if (unsigned Len = populateInstruction(
- Target, *EncodingDef, *Inst, EncodingID, Operands, IsVarLenInst)) {
- if (IsVarLenInst) {
- MaxInstLen = std::max(MaxInstLen, Len);
- InstrLen[EncodingID] = Len;
+ if (unsigned Len =
+ populateInstruction(Target, *EncodingDef, *Inst, EncodingID,
+ Operands, IsVarLenInst)) {
+ if (IsVarLenInst) {
+ MaxInstLen = std::max(MaxInstLen, Len);
+ InstrLen[EncodingID] = Len;
+ }
+ StringRef DecoderNamespace =
+ EncodingDef->getValueAsString("DecoderNamespace");
+ EncMap[{DecoderNamespace, HwModeID, Size}].push_back(EncodingID);
+ } else {
+ NumEncodingsOmitted++;
}
- StringRef DecoderNamespace =
- EncodingDef->getValueAsString("DecoderNamespace");
- EncMap[{DecoderNamespace, Encoding.HwModeID, Size}].push_back(EncodingID);
- } else {
- NumEncodingsOmitted++;
}
}
More information about the llvm-commits
mailing list