Skip to content

Commit 0b6f53e

Browse files
dzbarskygithub-actions[bot]
authored andcommitted
Automerge: [TableGen] Pool duplicate code-emitter base encodings (#202619)
Pool duplicate multiword instruction base encodings across the default encoding table and all hardware-mode encoding tables as unique `APInt` rows, then emit a pointer-free fixed-width `uint64_t` row table and one smallest-width opcode-to-row index table per mode. Use the pooled representation only when the combined values and indices are smaller than the original tables. On a Release build, the AMDGPU base-encoding payload shrinks by 440,888 bytes, `llvm-mc` and `llc` each shrink by 445,632 bytes, and the LLVM driver shrinks by 429,120 bytes. All 421 TableGen tests passed. Work towards #202616 AI tool disclosure: Co-authored with OpenAI Codex.
2 parents 1a676d6 + ff1a4d3 commit 0b6f53e

3 files changed

Lines changed: 232 additions & 76 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: llvm-tblgen -gen-emitter -I %p/../../include %s | FileCheck %s
2+
3+
include "llvm/Target/Target.td"
4+
5+
def TestInstrInfo : InstrInfo;
6+
7+
def Test : Target {
8+
let InstructionSet = TestInstrInfo;
9+
}
10+
11+
class TestInst<bits<8> LowEncoding, bit HighEncoding> : Instruction {
12+
bits<128> Inst;
13+
let Inst{7...0} = LowEncoding;
14+
let Inst{64} = HighEncoding;
15+
let OutOperandList = (outs);
16+
let InOperandList = (ins);
17+
}
18+
19+
def A0 : TestInst<1, 0>;
20+
def A1 : TestInst<1, 0>;
21+
def A2 : TestInst<1, 0>;
22+
def A3 : TestInst<1, 0>;
23+
def B0 : TestInst<1, 1>;
24+
def B1 : TestInst<1, 1>;
25+
def B2 : TestInst<1, 1>;
26+
def B3 : TestInst<1, 1>;
27+
28+
// CHECK: static const uint64_t InstBits[][2] = {
29+
// CHECK-NEXT: {UINT64_C(1), UINT64_C(0)},
30+
// CHECK-NEXT: {UINT64_C(1), UINT64_C(1)},
31+
// CHECK-NEXT: };
32+
// CHECK: static const uint8_t InstBitsIndices[] = {
33+
// CHECK-NEXT: 0,
34+
// CHECK-NEXT: 0,
35+
// CHECK-NEXT: 0,
36+
// CHECK-NEXT: 0,
37+
// CHECK-NEXT: 1,
38+
// CHECK-NEXT: 1,
39+
// CHECK-NEXT: 1,
40+
// CHECK-NEXT: 1,
41+
// CHECK-NEXT: };
42+
// CHECK: static_assert(sizeof(InstBits) / sizeof(InstBits[0]) <=
43+
// CHECK-NEXT: (UINT64_C(1) << (sizeof(InstBitsIndices[0]) * 8)));
44+
// CHECK: unsigned InstBitsIndex = InstBitsIndices[TableIndex];
45+
// CHECK: Inst = APInt(128, ArrayRef(InstBits[InstBitsIndex]));

llvm/test/TableGen/HwModeEncodeAPInt.td

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -107,45 +107,51 @@ def unrelated: Instruction {
107107
let AsmString = "unrelated $factor";
108108
}
109109

110-
// For 'bar' and 'unrelated', we didn't assign any HwModes for them,
111-
// they should keep the same in the following four tables.
112-
// For 'foo' we assigned four HwModes( includes 'DefaultMode' ),
113-
// it's encodings should be different in the following four tables.
114-
// For 'baz' we only assigned ModeB for it, so it will be presented
115-
// as '0' in the tables of ModeA, ModeC and Default Mode.
116-
// ENCODER-LABEL: static const uint64_t InstBits[] = {
117-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // bar
118-
// ENCODER-NEXT: UINT64_C(0), UINT64_C(0), // baz
119-
// ENCODER-NEXT: UINT64_C(8), UINT64_C(0), // foo
120-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // unrelated
110+
// InstBits contains the unique base encodings from all four HwModes.
111+
// Each InstBitsIndices table maps opcodes for one hardware mode into InstBits.
112+
// ENCODER-LABEL: static const uint64_t InstBits[][2] = {
113+
// ENCODER-NEXT: {UINT64_C(2), UINT64_C(0)},
114+
// ENCODER-NEXT: {UINT64_C(0), UINT64_C(0)},
115+
// ENCODER-NEXT: {UINT64_C(8), UINT64_C(0)},
116+
// ENCODER-NEXT: {UINT64_C(12), UINT64_C(0)},
117+
// ENCODER-NEXT: {UINT64_C(0), UINT64_C(211106232532992)},
118+
// ENCODER-NEXT: {UINT64_C(12582915), UINT64_C(0)},
121119
// ENCODER-NEXT: };
122-
// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = {
123-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // bar
124-
// ENCODER-NEXT: UINT64_C(0), UINT64_C(0), // baz
125-
// ENCODER-NEXT: UINT64_C(12), UINT64_C(0), // foo
126-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // unrelated
120+
// ENCODER-LABEL: static const uint8_t InstBitsIndices[] = {
121+
// ENCODER-NEXT: 0,
122+
// ENCODER-NEXT: 1,
123+
// ENCODER-NEXT: 2,
124+
// ENCODER-NEXT: 0,
127125
// ENCODER-NEXT: };
128-
// ENCODER-LABEL: static const uint64_t InstBits_ModeB[] = {
129-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // bar
130-
// ENCODER-NEXT: UINT64_C(12), UINT64_C(0), // baz
131-
// ENCODER-NEXT: UINT64_C(0), UINT64_C(211106232532992), // foo
132-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // unrelated
126+
// ENCODER-LABEL: static const uint8_t InstBitsIndices_ModeA[] = {
127+
// ENCODER-NEXT: 0,
128+
// ENCODER-NEXT: 1,
129+
// ENCODER-NEXT: 3,
130+
// ENCODER-NEXT: 0,
133131
// ENCODER-NEXT: };
134-
// ENCODER-LABEL: static const uint64_t InstBits_ModeC[] = {
135-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // bar
136-
// ENCODER-NEXT: UINT64_C(0), UINT64_C(0), // baz
137-
// ENCODER-NEXT: UINT64_C(12582915), UINT64_C(0), // foo
138-
// ENCODER-NEXT: UINT64_C(2), UINT64_C(0), // unrelated
132+
// ENCODER-LABEL: static const uint8_t InstBitsIndices_ModeB[] = {
133+
// ENCODER-NEXT: 0,
134+
// ENCODER-NEXT: 3,
135+
// ENCODER-NEXT: 4,
136+
// ENCODER-NEXT: 0,
139137
// ENCODER-NEXT: };
138+
// ENCODER-LABEL: static const uint8_t InstBitsIndices_ModeC[] = {
139+
// ENCODER-NEXT: 0,
140+
// ENCODER-NEXT: 1,
141+
// ENCODER-NEXT: 5,
142+
// ENCODER-NEXT: 0,
143+
// ENCODER-NEXT: };
144+
145+
// ENCODER: const uint8_t *InstBitsIndicesByHw;
140146

141-
// ENCODER: const uint64_t *InstBitsByHw;
142147
// ENCODER: constexpr unsigned FirstSupportedOpcode
143148
// ENCODER: const unsigned opcode = MI.getOpcode();
144149
// ENCODER: if (opcode < FirstSupportedOpcode)
145150
// ENCODER: unsigned TableIndex = opcode - FirstSupportedOpcode
146151
// ENCODER: if (Scratch.getBitWidth() != 128)
147152
// ENCODER: Scratch = Scratch.zext(128);
148-
// ENCODER: Inst = APInt(128, ArrayRef(InstBits + TableIndex * 2, 2));
153+
// ENCODER: unsigned InstBitsIndex = InstBitsIndices[TableIndex];
154+
// ENCODER: Inst = APInt(128, ArrayRef(InstBits[InstBitsIndex]));
149155
// ENCODER: APInt &Value = Inst;
150156
// ENCODER: APInt &op = Scratch;
151157
// ENCODER: switch (opcode) {
@@ -156,12 +162,13 @@ def unrelated: Instruction {
156162
// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);
157163
// ENCODER: switch (HwMode) {
158164
// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
159-
// ENCODER: case 0: InstBitsByHw = InstBits; break;
160-
// ENCODER: case 1: InstBitsByHw = InstBits_ModeA; break;
161-
// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break;
162-
// ENCODER: case 3: InstBitsByHw = InstBits_ModeC; break;
165+
// ENCODER: case 0: InstBitsIndicesByHw = InstBitsIndices; break;
166+
// ENCODER: case 1: InstBitsIndicesByHw = InstBitsIndices_ModeA; break;
167+
// ENCODER: case 2: InstBitsIndicesByHw = InstBitsIndices_ModeB; break;
168+
// ENCODER: case 3: InstBitsIndicesByHw = InstBitsIndices_ModeC; break;
163169
// ENCODER: };
164-
// ENCODER: Inst = APInt(128, ArrayRef(InstBitsByHw + TableIndex * 2, 2));
170+
// ENCODER: InstBitsIndex = InstBitsIndicesByHw[TableIndex];
171+
// ENCODER: Inst = APInt(128, ArrayRef(InstBits[InstBitsIndex]));
165172
// ENCODER: Value = Inst;
166173
// ENCODER: switch (HwMode) {
167174
// ENCODER: default: llvm_unreachable("Unhandled HwMode");
@@ -188,9 +195,10 @@ def unrelated: Instruction {
188195
// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo);
189196
// ENCODER: switch (HwMode) {
190197
// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break;
191-
// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break;
198+
// ENCODER: case 2: InstBitsIndicesByHw = InstBitsIndices_ModeB; break;
192199
// ENCODER: };
193-
// ENCODER: Inst = APInt(128, ArrayRef(InstBitsByHw + TableIndex * 2, 2));
200+
// ENCODER: InstBitsIndex = InstBitsIndicesByHw[TableIndex];
201+
// ENCODER: Inst = APInt(128, ArrayRef(InstBits[InstBitsIndex]));
194202
// ENCODER: Value = Inst;
195203
// ENCODER: switch (HwMode) {
196204
// ENCODER: default: llvm_unreachable("Unhandled HwMode");

0 commit comments

Comments
 (0)