Skip to content

Commit 56ce40b

Browse files
authored
[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.
1 parent eb76404 commit 56ce40b

File tree

1 file changed

+55
-41
lines changed

1 file changed

+55
-41
lines changed

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,9 @@ struct DecoderTableInfo {
208208
struct EncodingAndInst {
209209
const Record *EncodingDef;
210210
const CodeGenInstruction *Inst;
211-
unsigned HwModeID;
212211

213-
EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst,
214-
unsigned HwModeID = DefaultMode)
215-
: EncodingDef(EncodingDef), Inst(Inst), HwModeID(HwModeID) {}
212+
EncodingAndInst(const Record *EncodingDef, const CodeGenInstruction *Inst)
213+
: EncodingDef(EncodingDef), Inst(Inst) {}
216214
};
217215

218216
using NamespacesHwModesMap = std::map<std::string, std::set<unsigned>>;
@@ -221,8 +219,13 @@ class DecoderEmitter {
221219
const RecordKeeper &RK;
222220
CodeGenTarget Target;
223221
const CodeGenHwModes &CGH;
222+
223+
/// All parsed encodings.
224224
std::vector<EncodingAndInst> Encodings;
225225

226+
/// Encodings IDs for each HwMode. An ID is an index into Encodings.
227+
SmallDenseMap<unsigned, std::vector<unsigned>> EncodingIDsByHwMode;
228+
226229
public:
227230
DecoderEmitter(const RecordKeeper &RK, StringRef PredicateNamespace);
228231

@@ -249,7 +252,7 @@ class DecoderEmitter {
249252
NamespacesHwModesMap &NamespacesWithHwModes) const;
250253

251254
void
252-
handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
255+
handleHwModesUnrelatedEncodings(unsigned EncodingID,
253256
ArrayRef<unsigned> HwModeIDs,
254257
NamespacesHwModesMap &NamespacesWithHwModes);
255258

@@ -2425,32 +2428,31 @@ void DecoderEmitter::collectHwModesReferencedForEncodings(
24252428
}
24262429

24272430
void DecoderEmitter::handleHwModesUnrelatedEncodings(
2428-
const CodeGenInstruction *Instr, ArrayRef<unsigned> HwModeIDs,
2431+
unsigned EncodingID, ArrayRef<unsigned> HwModeIDs,
24292432
NamespacesHwModesMap &NamespacesWithHwModes) {
2430-
const Record *InstDef = Instr->TheDef;
2431-
24322433
switch (DecoderEmitterSuppressDuplicates) {
24332434
case SUPPRESSION_DISABLE: {
24342435
for (unsigned HwModeID : HwModeIDs)
2435-
Encodings.emplace_back(InstDef, Instr, HwModeID);
2436+
EncodingIDsByHwMode[HwModeID].push_back(EncodingID);
24362437
break;
24372438
}
24382439
case SUPPRESSION_LEVEL1: {
2440+
const Record *InstDef = Encodings[EncodingID].Inst->TheDef;
24392441
std::string DecoderNamespace =
24402442
InstDef->getValueAsString("DecoderNamespace").str();
24412443
auto It = NamespacesWithHwModes.find(DecoderNamespace);
24422444
if (It != NamespacesWithHwModes.end()) {
24432445
for (unsigned HwModeID : It->second)
2444-
Encodings.emplace_back(InstDef, Instr, HwModeID);
2446+
EncodingIDsByHwMode[HwModeID].push_back(EncodingID);
24452447
} else {
24462448
// Only emit the encoding once, as it's DecoderNamespace doesn't
24472449
// contain any HwModes.
2448-
Encodings.emplace_back(InstDef, Instr, DefaultMode);
2450+
EncodingIDsByHwMode[DefaultMode].push_back(EncodingID);
24492451
}
24502452
break;
24512453
}
24522454
case SUPPRESSION_LEVEL2:
2453-
Encodings.emplace_back(InstDef, Instr, DefaultMode);
2455+
EncodingIDsByHwMode[DefaultMode].push_back(EncodingID);
24542456
break;
24552457
}
24562458
}
@@ -2474,13 +2476,21 @@ void DecoderEmitter::parseInstructionEncodings() {
24742476
const Record *InstDef = Inst->TheDef;
24752477
if (const Record *RV = InstDef->getValueAsOptionalDef("EncodingInfos")) {
24762478
EncodingInfoByHwMode EBM(RV, CGH);
2477-
for (auto [HwModeID, EncodingDef] : EBM)
2478-
Encodings.emplace_back(EncodingDef, Inst, HwModeID);
2479+
for (auto [HwModeID, EncodingDef] : EBM) {
2480+
unsigned EncodingID = Encodings.size();
2481+
Encodings.emplace_back(EncodingDef, Inst);
2482+
EncodingIDsByHwMode[HwModeID].push_back(EncodingID);
2483+
}
24792484
continue;
24802485
}
2486+
2487+
unsigned EncodingID = Encodings.size();
2488+
Encodings.emplace_back(InstDef, Inst);
2489+
24812490
// This instruction is encoded the same on all HwModes.
2482-
// According to user needs, provide varying degrees of suppression.
2483-
handleHwModesUnrelatedEncodings(Inst, HwModeIDs, NamespacesWithHwModes);
2491+
// According to user needs, add it to all, some, or only the default HwMode.
2492+
handleHwModesUnrelatedEncodings(EncodingID, HwModeIDs,
2493+
NamespacesWithHwModes);
24842494
}
24852495

24862496
for (const Record *EncodingDef :
@@ -2528,35 +2538,39 @@ namespace {
25282538
InstrLen.resize(Target.getInstructions().size(), 0);
25292539
unsigned MaxInstLen = 0;
25302540

2531-
for (const auto &[EncodingID, Encoding] : enumerate(Encodings)) {
2532-
const Record *EncodingDef = Encoding.EncodingDef;
2533-
const CodeGenInstruction *Inst = Encoding.Inst;
2534-
const Record *Def = Inst->TheDef;
2535-
unsigned Size = EncodingDef->getValueAsInt("Size");
2536-
if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
2537-
Def->getValueAsBit("isPseudo") ||
2538-
Def->getValueAsBit("isAsmParserOnly") ||
2539-
Def->getValueAsBit("isCodeGenOnly")) {
2540-
NumEncodingsLackingDisasm++;
2541-
continue;
2542-
}
2541+
for (const auto &[HwModeID, EncodingIDs] : EncodingIDsByHwMode) {
2542+
for (unsigned EncodingID : EncodingIDs) {
2543+
const EncodingAndInst &Encoding = Encodings[EncodingID];
2544+
const Record *EncodingDef = Encoding.EncodingDef;
2545+
const CodeGenInstruction *Inst = Encoding.Inst;
2546+
const Record *Def = Inst->TheDef;
2547+
unsigned Size = EncodingDef->getValueAsInt("Size");
2548+
if (Def->getValueAsString("Namespace") == "TargetOpcode" ||
2549+
Def->getValueAsBit("isPseudo") ||
2550+
Def->getValueAsBit("isAsmParserOnly") ||
2551+
Def->getValueAsBit("isCodeGenOnly")) {
2552+
NumEncodingsLackingDisasm++;
2553+
continue;
2554+
}
25432555

2544-
NumEncodings++;
2556+
NumEncodings++;
25452557

2546-
if (!Size && !IsVarLenInst)
2547-
continue;
2558+
if (!Size && !IsVarLenInst)
2559+
continue;
25482560

2549-
if (unsigned Len = populateInstruction(
2550-
Target, *EncodingDef, *Inst, EncodingID, Operands, IsVarLenInst)) {
2551-
if (IsVarLenInst) {
2552-
MaxInstLen = std::max(MaxInstLen, Len);
2553-
InstrLen[EncodingID] = Len;
2561+
if (unsigned Len =
2562+
populateInstruction(Target, *EncodingDef, *Inst, EncodingID,
2563+
Operands, IsVarLenInst)) {
2564+
if (IsVarLenInst) {
2565+
MaxInstLen = std::max(MaxInstLen, Len);
2566+
InstrLen[EncodingID] = Len;
2567+
}
2568+
StringRef DecoderNamespace =
2569+
EncodingDef->getValueAsString("DecoderNamespace");
2570+
EncMap[{DecoderNamespace, HwModeID, Size}].push_back(EncodingID);
2571+
} else {
2572+
NumEncodingsOmitted++;
25542573
}
2555-
StringRef DecoderNamespace =
2556-
EncodingDef->getValueAsString("DecoderNamespace");
2557-
EncMap[{DecoderNamespace, Encoding.HwModeID, Size}].push_back(EncodingID);
2558-
} else {
2559-
NumEncodingsOmitted++;
25602574
}
25612575
}
25622576

0 commit comments

Comments
 (0)