Skip to content

Commit b2a9206

Browse files
author
z30050559
committed
[TableGen] Introduce a less aggressive suppression for HwMode DecoderTable
1. Remove 'AllModes' and 'DefaultMode' suffixes for DecoderTables under default HwMode. 2. Introduce a less aggressive suppression for HwMode DecoderTable, only reduce necessary tables duplications. This allows encodings under different HwModes to retain the original DecoderNamespace. 3. Change 'suppress-per-hwmode-duplicates' command option from bool type to enum type, allowing users to choose what level of suppression to use.
1 parent 631248d commit b2a9206

File tree

3 files changed

+140
-47
lines changed

3 files changed

+140
-47
lines changed

llvm/test/TableGen/HwModeEncodeDecode2.td

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | \
22
// RUN: FileCheck %s --check-prefix=DECODER
3-
// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates -I \
3+
// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O2 -I \
44
// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS
55

66
// Test duplicate table suppression for per-HwMode decoders.
@@ -105,11 +105,10 @@ let OutOperandList = (outs) in {
105105
// DECODER-DAG: Opcode: fooTypeEncA:baz
106106
// DECODER-DAG: Opcode: bar
107107

108-
109-
// DECODER-SUPPRESS-LABEL: DecoderTableAlt_AllModes32[] =
110-
// DECODER-SUPPRESS-DAG: Opcode: unrelated
111-
// DECODER-SUPPRESS-LABEL: DecoderTable_AllModes32[] =
108+
// DECODER-SUPPRESS-LABEL: DecoderTable32[] =
112109
// DECODER-SUPPRESS-DAG: Opcode: bar
110+
// DECODER-SUPPRESS-LABEL: DecoderTableAlt32[] =
111+
// DECODER-SUPPRESS-DAG: Opcode: unrelated
113112
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeA32[] =
114113
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:foo
115114
// DECODER-SUPPRESS-NOT: Opcode: bar

llvm/test/TableGen/HwModeEncodeDecode3.td

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// RUN: FileCheck %s --check-prefix=ENCODER
33
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | \
44
// RUN: FileCheck %s --check-prefix=DECODER
5-
// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates -I \
6-
// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS
5+
// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O1 -I \
6+
// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS-O1
7+
// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O2 -I \
8+
// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS-O2
79

810
include "llvm/Target/Target.td"
911

@@ -99,16 +101,20 @@ def unrelated: Instruction {
99101
}
100102

101103

102-
// DECODER-LABEL: DecoderTableAlt_DefaultMode32[] =
104+
// Under default settings, using 'HwMode' to dictate instruction encodings results in
105+
// significant duplication of DecoderTables. The three tables ‘DecoderTableAlt32’,
106+
// ‘DecoderTableAlt_ModeA32’, and ‘DecoderTableAlt_ModeB32’ are exact duplicates and
107+
// could effectively be merged into one.
108+
// DECODER-LABEL: DecoderTable32[] =
109+
// DECODER-DAG: Opcode: bar
110+
// DECODER-LABEL: DecoderTable64[] =
111+
// DECODER-DAG: Opcode: fooTypeEncDefault:foo
112+
// DECODER-LABEL: DecoderTableAlt32[] =
103113
// DECODER-DAG: Opcode: unrelated
104114
// DECODER-LABEL: DecoderTableAlt_ModeA32[] =
105115
// DECODER-DAG: Opcode: unrelated
106116
// DECODER-LABEL: DecoderTableAlt_ModeB32[] =
107117
// DECODER-DAG: Opcode: unrelated
108-
// DECODER-LABEL: DecoderTable_DefaultMode32[] =
109-
// DECODER-DAG: Opcode: bar
110-
// DECODER-LABEL: DecoderTable_DefaultMode64[] =
111-
// DECODER-DAG: Opcode: fooTypeEncDefault:foo
112118
// DECODER-LABEL: DecoderTable_ModeA32[] =
113119
// DECODER-DAG: Opcode: fooTypeEncA:foo
114120
// DECODER-DAG: Opcode: bar
@@ -117,21 +123,42 @@ def unrelated: Instruction {
117123
// DECODER-DAG: Opcode: fooTypeEncA:baz
118124
// DECODER-DAG: Opcode: bar
119125

120-
121-
// DECODER-SUPPRESS-LABEL: DecoderTableAlt_AllModes32[] =
122-
// DECODER-SUPPRESS-DAG: Opcode: unrelated
123-
// DECODER-SUPPRESS-LABEL: DecoderTable_AllModes32[] =
124-
// DECODER-SUPPRESS-DAG: Opcode: bar
125-
// DECODER-SUPPRESS-LABEL: DecoderTable_DefaultMode64[] =
126-
// DECODER-SUPPRESS-NOT: Opcode: bar
127-
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncDefault:foo
128-
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeA32[] =
129-
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:foo
130-
// DECODER-SUPPRESS-NOT: Opcode: bar
131-
// DECODER-SUPPRESS-LABEL: DecoderTable_ModeB32[] =
132-
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncB:foo
133-
// DECODER-SUPPRESS-DAG: Opcode: fooTypeEncA:baz
134-
// DECODER-SUPPRESS-NOT: Opcode: bar
126+
// Under the 'O1' optimization level, unnecessary duplicate tables will be eliminated,
127+
// reducing the three ‘Alt’ tables down to just one.
128+
// DECODER-SUPPRESS-O1-LABEL: DecoderTable32[] =
129+
// DECODER-SUPPRESS-O1-DAG: Opcode: bar
130+
// DECODER-SUPPRESS-O1-LABEL: DecoderTable64[] =
131+
// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncDefault:foo
132+
// DECODER-SUPPRESS-O1-LABEL: DecoderTableAlt32[] =
133+
// DECODER-SUPPRESS-O1-DAG: Opcode: unrelated
134+
// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeA32[] =
135+
// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:foo
136+
// DECODER-SUPPRESS-O1-DAG: Opcode: bar
137+
// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeB32[] =
138+
// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncB:foo
139+
// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:baz
140+
// DECODER-SUPPRESS-O1-DAG: Opcode: bar
141+
142+
// Under the 'O2' optimization condition, instructions possessing the 'EncodingByHwMode'
143+
// attribute will be extracted from their original DecoderNamespace and placed into their
144+
// respective HwMode tables. Meanwhile, other instructions that do not have the 'EncodingByHwMode'
145+
// attribute but are within the same DecoderNamespace will be stored in the 'Default' table. This
146+
// approach will significantly reduce instruction redundancy, but it necessitates users to thoroughly
147+
// consider the interplay between HwMode and DecoderNamespace for their instructions.
148+
// DECODER-SUPPRESS-O2-LABEL: DecoderTable32[] =
149+
// DECODER-SUPPRESS-O2-DAG: Opcode: bar
150+
// DECODER-SUPPRESS-O2-LABEL: DecoderTable64[] =
151+
// DECODER-SUPPRESS-O2-NOT: Opcode: bar
152+
// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncDefault:foo
153+
// DECODER-SUPPRESS-O2-LABEL: DecoderTableAlt32[] =
154+
// DECODER-SUPPRESS-O2-DAG: Opcode: unrelated
155+
// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeA32[] =
156+
// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:foo
157+
// DECODER-SUPPRESS-O2-NOT: Opcode: bar
158+
// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeB32[] =
159+
// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncB:foo
160+
// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:baz
161+
// DECODER-SUPPRESS-O2-NOT: Opcode: bar
135162

136163
// ENCODER-LABEL: static const uint64_t InstBits_DefaultMode[] = {
137164
// ENCODER: UINT64_C(2), // bar

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,27 @@ using namespace llvm;
5454

5555
extern cl::OptionCategory DisassemblerEmitterCat;
5656

57-
cl::opt<bool> DecoderEmitterSuppressDuplicates(
57+
enum SuppressLevel {
58+
SUPPRESSION_DISABLE,
59+
SUPPRESSION_LEVEL1,
60+
SUPPRESSION_LEVEL2
61+
};
62+
63+
cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates(
5864
"suppress-per-hwmode-duplicates",
5965
cl::desc("Suppress duplication of instrs into per-HwMode decoder tables"),
60-
cl::init(false), cl::cat(DisassemblerEmitterCat));
66+
cl::values(
67+
clEnumValN(
68+
SUPPRESSION_DISABLE, "O0",
69+
"Do not prevent DecoderTable duplications caused by HwModes"),
70+
clEnumValN(
71+
SUPPRESSION_LEVEL1, "O1",
72+
"Remove duplicate DecoderTable entries generated due to HwModes"),
73+
clEnumValN(
74+
SUPPRESSION_LEVEL2, "O2",
75+
"Extract HwModes-specific instructions into new DecoderTables, "
76+
"significantly reducing Table Duplications")),
77+
cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
6178

6279
namespace {
6380

@@ -128,6 +145,8 @@ struct EncodingIDAndOpcode {
128145
};
129146

130147
using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
148+
using NamespacesHwModesMap =
149+
std::map<std::string, std::map<StringRef, unsigned>>;
131150

132151
raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {
133152
if (Value.EncodingDef != Value.Inst->TheDef)
@@ -2417,21 +2436,67 @@ static bool Check(DecodeStatus &Out, DecodeStatus In) {
24172436

24182437
// Collect all HwModes referenced by the target for encoding purposes,
24192438
// returning a vector of corresponding names.
2420-
static void
2421-
collectHwModesReferencedForEncodings(const CodeGenHwModes &HWM,
2422-
std::vector<StringRef> &Names) {
2439+
static void collectHwModesReferencedForEncodings(
2440+
const CodeGenHwModes &HWM, std::vector<StringRef> &Names,
2441+
NamespacesHwModesMap &NamespacesWithHwModes) {
24232442
SmallBitVector BV(HWM.getNumModeIds());
24242443
for (const auto &MS : HWM.getHwModeSelects()) {
24252444
for (const HwModeSelect::PairType &P : MS.second.Items) {
2426-
if (P.second->isSubClassOf("InstructionEncoding"))
2445+
if (P.second->isSubClassOf("InstructionEncoding")) {
2446+
std::string DecoderNamespace =
2447+
std::string(P.second->getValueAsString("DecoderNamespace"));
2448+
if (P.first == DefaultMode) {
2449+
NamespacesWithHwModes[DecoderNamespace][""] = 1;
2450+
} else {
2451+
NamespacesWithHwModes[DecoderNamespace][HWM.getMode(P.first).Name] =
2452+
1;
2453+
}
24272454
BV.set(P.first);
2455+
}
24282456
}
24292457
}
24302458
transform(BV.set_bits(), std::back_inserter(Names), [&HWM](const int &M) {
2459+
if (M == DefaultMode)
2460+
return StringRef("");
24312461
return HWM.getModeName(M, /*IncludeDefault=*/true);
24322462
});
24332463
}
24342464

2465+
static void
2466+
handleHwModesUnrelatedEncodings(const CodeGenInstruction *Instr,
2467+
const std::vector<StringRef> &HwModeNames,
2468+
NamespacesHwModesMap &NamespacesWithHwModes,
2469+
std::vector<EncodingAndInst> &GlobalEncodings) {
2470+
const Record *InstDef = Instr->TheDef;
2471+
2472+
switch (DecoderEmitterSuppressDuplicates) {
2473+
case SUPPRESSION_DISABLE: {
2474+
for (StringRef HwModeName : HwModeNames)
2475+
GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2476+
break;
2477+
}
2478+
case SUPPRESSION_LEVEL1: {
2479+
std::string DecoderNamespace =
2480+
std::string(InstDef->getValueAsString("DecoderNamespace"));
2481+
for (StringRef HwModeName : HwModeNames) {
2482+
if (NamespacesWithHwModes.count(DecoderNamespace) > 0) {
2483+
if (NamespacesWithHwModes[DecoderNamespace].count(HwModeName) > 0)
2484+
GlobalEncodings.emplace_back(InstDef, Instr, HwModeName);
2485+
} else {
2486+
// Only emit the encoding once, as it's DecoderNamespace doesn't
2487+
// contain any HwModes.
2488+
GlobalEncodings.emplace_back(InstDef, Instr, "");
2489+
break;
2490+
}
2491+
}
2492+
break;
2493+
}
2494+
case SUPPRESSION_LEVEL2:
2495+
GlobalEncodings.emplace_back(InstDef, Instr, "");
2496+
break;
2497+
}
2498+
}
2499+
24352500
// Emits disassembler code for instruction decoding.
24362501
void DecoderEmitter::run(raw_ostream &o) {
24372502
formatted_raw_ostream OS(o);
@@ -2457,10 +2522,12 @@ namespace llvm {
24572522
// Parameterize the decoders based on namespace and instruction width.
24582523

24592524
// First, collect all encoding-related HwModes referenced by the target.
2525+
// And establish a mapping table between DecoderNamespace and HwMode.
24602526
// If HwModeNames is empty, add the empty string so we always have one HwMode.
24612527
const CodeGenHwModes &HWM = Target.getHwModes();
24622528
std::vector<StringRef> HwModeNames;
2463-
collectHwModesReferencedForEncodings(HWM, HwModeNames);
2529+
NamespacesHwModesMap NamespacesWithHwModes;
2530+
collectHwModesReferencedForEncodings(HWM, HwModeNames, NamespacesWithHwModes);
24642531
if (HwModeNames.empty())
24652532
HwModeNames.push_back("");
24662533

@@ -2471,22 +2538,22 @@ namespace llvm {
24712538
if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) {
24722539
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
24732540
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
2474-
for (auto &KV : EBM)
2475-
NumberedEncodings.emplace_back(
2476-
KV.second, NumberedInstruction,
2477-
HWM.getModeName(KV.first, /*IncludeDefault=*/true));
2541+
for (auto &[ModeId, Encoding] : EBM) {
2542+
// DecoderTables with DefaultMode should not have any suffix.
2543+
if (ModeId == DefaultMode) {
2544+
NumberedEncodings.emplace_back(Encoding, NumberedInstruction, "");
2545+
} else {
2546+
NumberedEncodings.emplace_back(Encoding, NumberedInstruction,
2547+
HWM.getMode(ModeId).Name);
2548+
}
2549+
}
24782550
continue;
24792551
}
24802552
}
2481-
// This instruction is encoded the same on all HwModes. Emit it for all
2482-
// HwModes by default, otherwise leave it in a single common table.
2483-
if (DecoderEmitterSuppressDuplicates) {
2484-
NumberedEncodings.emplace_back(InstDef, NumberedInstruction, "AllModes");
2485-
} else {
2486-
for (StringRef HwModeName : HwModeNames)
2487-
NumberedEncodings.emplace_back(InstDef, NumberedInstruction,
2488-
HwModeName);
2489-
}
2553+
// This instruction is encoded the same on all HwModes.
2554+
// According to user needs, provide varying degrees of suppression.
2555+
handleHwModesUnrelatedEncodings(NumberedInstruction, HwModeNames,
2556+
NamespacesWithHwModes, NumberedEncodings);
24902557
}
24912558
for (const auto &NumberedAlias :
24922559
RK.getAllDerivedDefinitions("AdditionalEncoding"))

0 commit comments

Comments
 (0)