Skip to content

Commit d149cef

Browse files
committed
[RISCV] Add macro fusions for Xiangshan
Doc: https://xiangshan-doc.readthedocs.io/zh-cn/latest/frontend/decode/ This PR is to show the usage of TableGen-based macro fusions. Some instrcution pairs can be folded into one MacroFusion definition but I leave them standalone to show the different ways to define a macro fusion.
1 parent 6bc6e1a commit d149cef

File tree

2 files changed

+1144
-1
lines changed

2 files changed

+1144
-1
lines changed

llvm/lib/Target/RISCV/RISCVMacroFusion.td

+219
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,222 @@ def TuneLDADDFusion
9191
CheckIsImmOperand<2>,
9292
CheckImmOperand<2, 0>
9393
]>>;
94+
95+
// Get lower 16 bits:
96+
// slliw r1, r0, 16
97+
// srliw r1, r1, 16
98+
def GetLower16BitsFusion
99+
: SimpleFusion<"get-lower-16bits-fusion", "HasGetLower16BitsFusion",
100+
"Enable SLLIW+SRLIW to be fused to get lower 16 bits",
101+
CheckAll<[
102+
CheckOpcode<[SLLIW]>,
103+
CheckImmOperand<2, 16>
104+
]>,
105+
CheckAll<[
106+
CheckOpcode<[SRLIW]>,
107+
CheckImmOperand<2, 16>
108+
]>>;
109+
110+
// Sign-extend a 16-bit number:
111+
// slliw r1, r0, 16
112+
// sraiw r1, r1, 16
113+
def SExtHFusion
114+
: SimpleFusion<"sign-extend-16bits-fusion","HasSExtHFusion",
115+
"Enable SLLIW+SRAIW to be fused to sign-extend a 16-bit number",
116+
CheckAll<[
117+
CheckOpcode<[SLLIW]>,
118+
CheckImmOperand<2, 16>
119+
]>,
120+
CheckAll<[
121+
CheckOpcode<[SRAIW]>,
122+
CheckImmOperand<2, 16>
123+
]>>;
124+
125+
// These should be covered by Zba extension.
126+
// * shift left by one and add:
127+
// slli r1, r0, 1
128+
// add r1, r1, r2
129+
// * shift left by two and add:
130+
// slli r1, r0, 2
131+
// add r1, r1, r2
132+
// * shift left by three and add:
133+
// slli r1, r0, 3
134+
// add r1, r1, r2
135+
let IsCommutable = 1 in
136+
def ShiftNAddFusion
137+
: SimpleFusion<"shift-n-add-fusion", "HasShiftNAddFusion",
138+
"Enable SLLI+ADD to be fused to shift left by 1/2/3 and add",
139+
CheckAll<[
140+
CheckOpcode<[SLLI]>,
141+
CheckAny<[CheckImmOperand<2, 1>,
142+
CheckImmOperand<2, 2>,
143+
CheckImmOperand<2, 3>]>
144+
]>,
145+
CheckOpcode<[ADD]>>;
146+
147+
// * Shift zero-extended word left by 1:
148+
// slli r1, r0, 32
149+
// srli r1, r0, 31
150+
// * Shift zero-extended word left by 2:
151+
// slli r1, r0, 32
152+
// srli r1, r0, 30
153+
// * Shift zero-extended word left by 3:
154+
// slli r1, r0, 32
155+
// srli r1, r0, 29
156+
def ShiftZExtByNFusion
157+
: SimpleFusion<"shift-zext-by-n-fusion", "HasShiftZExtByNFusion",
158+
"Enable SLLI+SRLI to be fused to shift zero-extended word left by 1/2/3",
159+
CheckAll<[
160+
CheckOpcode<[SLLI]>,
161+
CheckImmOperand<2, 32>
162+
]>,
163+
CheckAll<[
164+
CheckOpcode<[SRLI]>,
165+
CheckAny<[CheckImmOperand<2, 29>,
166+
CheckImmOperand<2, 30>,
167+
CheckImmOperand<2, 31>]>
168+
]>>;
169+
170+
// Get the second byte:
171+
// srli r1, r0, 8
172+
// andi r1, r1, 255
173+
def GetSecondByteFusion
174+
: SimpleFusion<"get-second-byte-fusion", "HasGetSecondByteFusion",
175+
"Enable SRLI+ANDI to be fused to get the second byte",
176+
CheckAll<[
177+
CheckOpcode<[SRLI]>,
178+
CheckImmOperand<2, 8>
179+
]>,
180+
CheckAll<[
181+
CheckOpcode<[ANDI]>,
182+
CheckImmOperand<2, 255>
183+
]>>;
184+
185+
// Shift left by four and add:
186+
// slli r1, r0, 4
187+
// add r1, r1, r2
188+
let IsCommutable = 1 in
189+
def ShiftLeft4AddFusion
190+
: SimpleFusion<"shift-left-four-add-fusion", "HasShiftLeft4AddFusion",
191+
"Enable SLLI+ADD to be fused to shift left by four and add",
192+
CheckAll<[
193+
CheckOpcode<[SLLI]>,
194+
CheckImmOperand<2, 4>
195+
]>,
196+
CheckOpcode<[ADD]>>;
197+
198+
// * Shift right by 29 and add:
199+
// srli r1, r0, 29
200+
// add r1, r1, r2
201+
// * Shift right by 30 and add:
202+
// srli r1, r0, 30
203+
// add r1, r1, r2
204+
// * Shift right by 31 and add:
205+
// srli r1, r0, 31
206+
// add r1, r1, r2
207+
// * Shift right by 32 and add:
208+
// srli r1, r0, 32
209+
// add r1, r1, r2
210+
let IsCommutable = 1 in
211+
def ShiftRightNAddFusion
212+
: SimpleFusion<"shift-right-n-add-fusion", "HasShiftRightNAddFusion",
213+
"Enable SRLI+add to be fused to shift right by 29/30/31/32 and add",
214+
CheckAll<[
215+
CheckOpcode<[SRLI]>,
216+
CheckAny<[CheckImmOperand<2, 29>,
217+
CheckImmOperand<2, 30>,
218+
CheckImmOperand<2, 31>,
219+
CheckImmOperand<2, 32>]>
220+
]>,
221+
CheckOpcode<[ADD]>>;
222+
223+
// Add one if odd, otherwise unchanged:
224+
// andi r1, r0, 1
225+
// add r1, r1, r2
226+
// Add one if odd (in word format), otherwise unchanged:
227+
// andi r1, r0, 1
228+
// addw r1, r1, r2
229+
let IsCommutable = 1 in
230+
def AddOneIfOddFusion
231+
: SimpleFusion<"add-one-if-odd-fusion", "HasAddOneIfOddFusion",
232+
"Enable ANDI+ADDW to be fused to add one if odd",
233+
CheckAll<[
234+
CheckOpcode<[ANDI]>,
235+
CheckImmOperand<2, 1>
236+
]>,
237+
CheckOpcode<[ADD, ADDW]>>;
238+
239+
// * Add word and extract its lower 1 bit:
240+
// andw r1, r1, r0
241+
// andi r1, r1, 1
242+
// * Add word and extract its lower 8 bits:
243+
// andw r1, r1, r0
244+
// andi r1, r1, 255
245+
def AddAndExtractNBitsFusion
246+
: SimpleFusion<"add-and-extract-n-bits-fusion", "HasAddAndExtractNBitsFusion",
247+
"Enable ADDW+ANDI to be fused to get lower 16 bits",
248+
CheckOpcode<[ADDW]>,
249+
CheckAll<[
250+
CheckOpcode<[ANDI]>,
251+
CheckAny<[CheckImmOperand<2, 1>,
252+
CheckImmOperand<2, 255>]>
253+
]>>;
254+
255+
// * Add word and zext.h:
256+
// andw r1, r1, r0
257+
// zext.h r1, r1
258+
// * Add word and sext.h:
259+
// andw r1, r1, r0
260+
// sext.h r1, r1
261+
def AddwAndExtFusion
262+
: SimpleFusion<"addw-and-ext-fusion", "HasAddwAndExtFusion",
263+
"Enable ADDW+ZEXT_H/SEXT_H to be fused",
264+
CheckOpcode<[ADDW]>,
265+
CheckOpcode<[ZEXT_H_RV32, ZEXT_H_RV64, SEXT_H]>>;
266+
267+
// Logic operation and extract its LSB:
268+
// <logic op> r1, r1, r0
269+
// andi r1, r1, 1
270+
def LogicOpAndExtractLSBFusion
271+
: SimpleFusion<"logic-op-and-extract-lsb-fusion", "HasLogicOpAndExtractLSBFusion",
272+
"Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ANDI to be fused to logic operation and extract its LSB",
273+
CheckOpcode<[AND, OR, XOR, ANDI, ORI, XORI, ORC_B]>,
274+
CheckAll<[
275+
CheckOpcode<[ANDI]>,
276+
CheckImmOperand<2, 1>
277+
]>>;
278+
279+
// Logic operation and extract its lower 16 bits:
280+
// <logic op> r1, r1, r0
281+
// zext.h r1, r1
282+
def LogicOpAndExtractLow16BitsFusion
283+
: SimpleFusion<"logic-op-and-extract-low-16bits-fusion", "HasLogicOpAndExtractLow16BitsFusion",
284+
"Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ZEXT_H to be fused to logic operation and extract its lower 16 bits",
285+
CheckOpcode<[AND, OR, XOR, ANDI, ORI, XORI, ORC_B]>,
286+
CheckOpcode<[ZEXT_H_RV32, ZEXT_H_RV64]>>;
287+
288+
// OR(Cat(src1(63, 8), 0.U(8.W)), src2):
289+
// andi r1, r0, -256
290+
// or r1, r1, r2
291+
let IsCommutable = 1 in
292+
def OrCatFusion
293+
: SimpleFusion<"or-cat-fusion", "HasOrCatFusion",
294+
"Enable SLLIW+SRLIW to be fused to get lower 16 bits",
295+
CheckAll<[
296+
CheckOpcode<[ANDI]>,
297+
CheckImmOperand<2, -256>
298+
]>,
299+
CheckOpcode<[OR]>>;
300+
301+
// Multiply 7-bit data with 32-bit data:
302+
// andi r1, r0, 127
303+
// mulw r1, r1, r2
304+
let IsCommutable = 1 in
305+
def Mul7BitsWith32BitsFusion
306+
: SimpleFusion<"mul-7bits-with-32bit-fusion", "HasMul7BitsWith32BitsFusion",
307+
"Enable ANDI+MULW to be fused to multiply 7-bit data with 32-bit data",
308+
CheckAll<[
309+
CheckOpcode<[ANDI]>,
310+
CheckImmOperand<2, 127>
311+
]>,
312+
CheckOpcode<[MULW]>>;

0 commit comments

Comments
 (0)