1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Macro Fusion Predicators *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9#ifdef GET_RISCV_MACRO_FUSION_PRED_DECL
10#undef GET_RISCV_MACRO_FUSION_PRED_DECL
11
12namespace llvm {
13
14bool isTuneADDILoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
15bool isTuneADDLoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
16bool isTuneAUIPCADDIFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
17bool isTuneAUIPCLoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
18bool isTuneBFExtFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
19bool isTuneFusionAddMem(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
20bool isTuneFusionLogicImmReg(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
21bool isTuneFusionLogicRegImm(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
22bool isTuneFusionLogicRegReg(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
23bool isTuneFusionMulAdd(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
24bool isTuneFusionShiftBitExtract(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
25bool isTuneLDADDFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
26bool isTuneLUIADDIFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
27bool isTuneLUILoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
28bool isTuneQCELILoadStoreFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
29bool isTuneSHXADDLoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
30bool isTuneShiftedZExtWFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
31bool isTuneZExtHFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
32bool isTuneZExtWFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &);
33
34} // namespace llvm
35
36#endif // GET_RISCV_MACRO_FUSION_PRED_DECL
37
38
39#ifdef GET_RISCV_MACRO_FUSION_PRED_IMPL
40#undef GET_RISCV_MACRO_FUSION_PRED_IMPL
41
42namespace llvm {
43
44STATISTIC(NumTuneADDILoadFusionPreRA, "Times TuneADDILoadFusion Triggered (pre-ra)");
45STATISTIC(NumTuneADDILoadFusionPostRA, "Times TuneADDILoadFusion Triggered (post-ra)");
46bool isTuneADDILoadFusion(
47 const TargetInstrInfo &TII,
48 const TargetSubtargetInfo &STI,
49 const MachineInstr *FirstMI,
50 const MachineInstr &SecondMI) {
51 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
52 {
53 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
54 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
55 return false;
56 }
57 if (!FirstMI)
58 return true;
59 {
60 [[maybe_unused]] const MachineInstr *MI = FirstMI;
61 if (( MI->getOpcode() != RISCV::ADDI ))
62 return false;
63 }
64 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
65 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
66 return false;
67 }
68 {
69 Register FirstDest = FirstMI->getOperand(0).getReg();
70 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
71 return false;
72 }
73 if (!(FirstMI->getOperand(0).isReg() &&
74 SecondMI.getOperand(1).isReg() &&
75 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
76 return false;
77 if (SecondMI.getMF()->getProperties().hasNoVRegs())
78 ++NumTuneADDILoadFusionPostRA;
79 else
80 ++NumTuneADDILoadFusionPreRA;
81 return true;
82}
83STATISTIC(NumTuneADDLoadFusionPreRA, "Times TuneADDLoadFusion Triggered (pre-ra)");
84STATISTIC(NumTuneADDLoadFusionPostRA, "Times TuneADDLoadFusion Triggered (post-ra)");
85bool isTuneADDLoadFusion(
86 const TargetInstrInfo &TII,
87 const TargetSubtargetInfo &STI,
88 const MachineInstr *FirstMI,
89 const MachineInstr &SecondMI) {
90 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
91 {
92 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
93 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
94 return false;
95 }
96 if (!FirstMI)
97 return true;
98 {
99 [[maybe_unused]] const MachineInstr *MI = FirstMI;
100 if (!llvm::is_contained({RISCV::ADD, RISCV::ADD_UW}, MI->getOpcode()))
101 return false;
102 }
103 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
104 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
105 return false;
106 }
107 {
108 Register FirstDest = FirstMI->getOperand(0).getReg();
109 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
110 return false;
111 }
112 if (!(FirstMI->getOperand(0).isReg() &&
113 SecondMI.getOperand(1).isReg() &&
114 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
115 return false;
116 if (SecondMI.getMF()->getProperties().hasNoVRegs())
117 ++NumTuneADDLoadFusionPostRA;
118 else
119 ++NumTuneADDLoadFusionPreRA;
120 return true;
121}
122STATISTIC(NumTuneAUIPCADDIFusionPreRA, "Times TuneAUIPCADDIFusion Triggered (pre-ra)");
123STATISTIC(NumTuneAUIPCADDIFusionPostRA, "Times TuneAUIPCADDIFusion Triggered (post-ra)");
124bool isTuneAUIPCADDIFusion(
125 const TargetInstrInfo &TII,
126 const TargetSubtargetInfo &STI,
127 const MachineInstr *FirstMI,
128 const MachineInstr &SecondMI) {
129 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
130 {
131 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
132 if (( MI->getOpcode() != RISCV::ADDI ))
133 return false;
134 }
135 if (!FirstMI)
136 return true;
137 {
138 [[maybe_unused]] const MachineInstr *MI = FirstMI;
139 if (( MI->getOpcode() != RISCV::AUIPC ))
140 return false;
141 }
142 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
143 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
144 return false;
145 }
146 {
147 Register FirstDest = FirstMI->getOperand(0).getReg();
148 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
149 return false;
150 }
151 if (!(FirstMI->getOperand(0).isReg() &&
152 SecondMI.getOperand(1).isReg() &&
153 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
154 return false;
155 if (SecondMI.getMF()->getProperties().hasNoVRegs())
156 ++NumTuneAUIPCADDIFusionPostRA;
157 else
158 ++NumTuneAUIPCADDIFusionPreRA;
159 return true;
160}
161STATISTIC(NumTuneAUIPCLoadFusionPreRA, "Times TuneAUIPCLoadFusion Triggered (pre-ra)");
162STATISTIC(NumTuneAUIPCLoadFusionPostRA, "Times TuneAUIPCLoadFusion Triggered (post-ra)");
163bool isTuneAUIPCLoadFusion(
164 const TargetInstrInfo &TII,
165 const TargetSubtargetInfo &STI,
166 const MachineInstr *FirstMI,
167 const MachineInstr &SecondMI) {
168 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
169 {
170 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
171 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
172 return false;
173 }
174 if (!FirstMI)
175 return true;
176 {
177 [[maybe_unused]] const MachineInstr *MI = FirstMI;
178 if (( MI->getOpcode() != RISCV::AUIPC ))
179 return false;
180 }
181 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
182 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
183 return false;
184 }
185 {
186 Register FirstDest = FirstMI->getOperand(0).getReg();
187 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
188 return false;
189 }
190 if (!(FirstMI->getOperand(0).isReg() &&
191 SecondMI.getOperand(1).isReg() &&
192 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
193 return false;
194 if (SecondMI.getMF()->getProperties().hasNoVRegs())
195 ++NumTuneAUIPCLoadFusionPostRA;
196 else
197 ++NumTuneAUIPCLoadFusionPreRA;
198 return true;
199}
200STATISTIC(NumTuneBFExtFusionPreRA, "Times TuneBFExtFusion Triggered (pre-ra)");
201STATISTIC(NumTuneBFExtFusionPostRA, "Times TuneBFExtFusion Triggered (post-ra)");
202bool isTuneBFExtFusion(
203 const TargetInstrInfo &TII,
204 const TargetSubtargetInfo &STI,
205 const MachineInstr *FirstMI,
206 const MachineInstr &SecondMI) {
207 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
208 {
209 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
210 if (( MI->getOpcode() != RISCV::SRLI ))
211 return false;
212 }
213 if (!FirstMI)
214 return true;
215 {
216 [[maybe_unused]] const MachineInstr *MI = FirstMI;
217 if (( MI->getOpcode() != RISCV::SLLI ))
218 return false;
219 }
220 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
221 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
222 return false;
223 }
224 {
225 Register FirstDest = FirstMI->getOperand(0).getReg();
226 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
227 return false;
228 }
229 if (!(FirstMI->getOperand(0).isReg() &&
230 SecondMI.getOperand(1).isReg() &&
231 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
232 return false;
233 if (SecondMI.getMF()->getProperties().hasNoVRegs())
234 ++NumTuneBFExtFusionPostRA;
235 else
236 ++NumTuneBFExtFusionPreRA;
237 return true;
238}
239STATISTIC(NumTuneFusionAddMemPreRA, "Times TuneFusionAddMem Triggered (pre-ra)");
240STATISTIC(NumTuneFusionAddMemPostRA, "Times TuneFusionAddMem Triggered (post-ra)");
241bool isTuneFusionAddMem(
242 const TargetInstrInfo &TII,
243 const TargetSubtargetInfo &STI,
244 const MachineInstr *FirstMI,
245 const MachineInstr &SecondMI) {
246 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
247 {
248 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
249 if (!(
250 llvm::is_contained({RISCV::LB, RISCV::LBU, RISCV::LH, RISCV::LHU, RISCV::LW, RISCV::LWU, RISCV::LD, RISCV::FLH, RISCV::FLW, RISCV::FLD, RISCV::SB, RISCV::SH, RISCV::SW, RISCV::SD, RISCV::FSH, RISCV::FSW, RISCV::FSD}, MI->getOpcode())
251 && MI->getOperand(2).isImm()
252 && MI->getOperand(2).getImm() == 0
253 ))
254 return false;
255 }
256 if (!FirstMI)
257 return true;
258 {
259 [[maybe_unused]] const MachineInstr *MI = FirstMI;
260 if (!(
261 ( MI->getOpcode() == RISCV::ADD )
262 && MI->getOperand(0).getReg() != MI->getOperand(1).getReg()
263 && MI->getOperand(0).getReg() != MI->getOperand(2).getReg()
264 ))
265 return false;
266 }
267 if (!(FirstMI->getOperand(0).isReg() &&
268 SecondMI.getOperand(1).isReg() &&
269 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
270 return false;
271 if (SecondMI.getMF()->getProperties().hasNoVRegs())
272 ++NumTuneFusionAddMemPostRA;
273 else
274 ++NumTuneFusionAddMemPreRA;
275 return true;
276}
277STATISTIC(NumTuneFusionLogicImmRegPreRA, "Times TuneFusionLogicImmReg Triggered (pre-ra)");
278STATISTIC(NumTuneFusionLogicImmRegPostRA, "Times TuneFusionLogicImmReg Triggered (post-ra)");
279bool isTuneFusionLogicImmReg(
280 const TargetInstrInfo &TII,
281 const TargetSubtargetInfo &STI,
282 const MachineInstr *FirstMI,
283 const MachineInstr &SecondMI) {
284 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
285 {
286 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
287 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
288 return false;
289 }
290 if (!FirstMI)
291 return true;
292 {
293 [[maybe_unused]] const MachineInstr *MI = FirstMI;
294 if (!llvm::is_contained({RISCV::ANDI, RISCV::ORI, RISCV::XORI}, MI->getOpcode()))
295 return false;
296 }
297 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
298 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) {
299 if (!SecondMI.getDesc().isCommutable())
300 return false;
301 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
302 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
303 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
304 return false;
305 }
306 }
307 {
308 Register FirstDest = FirstMI->getOperand(0).getReg();
309 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
310 return false;
311 }
312 if (!(FirstMI->getOperand(0).isReg() &&
313 SecondMI.getOperand(1).isReg() &&
314 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
315 if (!SecondMI.getDesc().isCommutable())
316 return false;
317 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
318 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
319 if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
320 return false;
321 }
322 if (SecondMI.getMF()->getProperties().hasNoVRegs())
323 ++NumTuneFusionLogicImmRegPostRA;
324 else
325 ++NumTuneFusionLogicImmRegPreRA;
326 return true;
327}
328STATISTIC(NumTuneFusionLogicRegImmPreRA, "Times TuneFusionLogicRegImm Triggered (pre-ra)");
329STATISTIC(NumTuneFusionLogicRegImmPostRA, "Times TuneFusionLogicRegImm Triggered (post-ra)");
330bool isTuneFusionLogicRegImm(
331 const TargetInstrInfo &TII,
332 const TargetSubtargetInfo &STI,
333 const MachineInstr *FirstMI,
334 const MachineInstr &SecondMI) {
335 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
336 {
337 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
338 if (!llvm::is_contained({RISCV::ANDI, RISCV::ORI, RISCV::XORI}, MI->getOpcode()))
339 return false;
340 }
341 if (!FirstMI)
342 return true;
343 {
344 [[maybe_unused]] const MachineInstr *MI = FirstMI;
345 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
346 return false;
347 }
348 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
349 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
350 return false;
351 }
352 {
353 Register FirstDest = FirstMI->getOperand(0).getReg();
354 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
355 return false;
356 }
357 if (!(FirstMI->getOperand(0).isReg() &&
358 SecondMI.getOperand(1).isReg() &&
359 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
360 return false;
361 if (SecondMI.getMF()->getProperties().hasNoVRegs())
362 ++NumTuneFusionLogicRegImmPostRA;
363 else
364 ++NumTuneFusionLogicRegImmPreRA;
365 return true;
366}
367STATISTIC(NumTuneFusionLogicRegRegPreRA, "Times TuneFusionLogicRegReg Triggered (pre-ra)");
368STATISTIC(NumTuneFusionLogicRegRegPostRA, "Times TuneFusionLogicRegReg Triggered (post-ra)");
369bool isTuneFusionLogicRegReg(
370 const TargetInstrInfo &TII,
371 const TargetSubtargetInfo &STI,
372 const MachineInstr *FirstMI,
373 const MachineInstr &SecondMI) {
374 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
375 {
376 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
377 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
378 return false;
379 }
380 if (!FirstMI)
381 return true;
382 {
383 [[maybe_unused]] const MachineInstr *MI = FirstMI;
384 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
385 return false;
386 }
387 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
388 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) {
389 if (!SecondMI.getDesc().isCommutable())
390 return false;
391 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
392 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
393 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
394 return false;
395 }
396 }
397 {
398 Register FirstDest = FirstMI->getOperand(0).getReg();
399 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
400 return false;
401 }
402 if (!(FirstMI->getOperand(0).isReg() &&
403 SecondMI.getOperand(1).isReg() &&
404 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
405 if (!SecondMI.getDesc().isCommutable())
406 return false;
407 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
408 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
409 if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
410 return false;
411 }
412 if (SecondMI.getMF()->getProperties().hasNoVRegs())
413 ++NumTuneFusionLogicRegRegPostRA;
414 else
415 ++NumTuneFusionLogicRegRegPreRA;
416 return true;
417}
418STATISTIC(NumTuneFusionMulAddPreRA, "Times TuneFusionMulAdd Triggered (pre-ra)");
419STATISTIC(NumTuneFusionMulAddPostRA, "Times TuneFusionMulAdd Triggered (post-ra)");
420bool isTuneFusionMulAdd(
421 const TargetInstrInfo &TII,
422 const TargetSubtargetInfo &STI,
423 const MachineInstr *FirstMI,
424 const MachineInstr &SecondMI) {
425 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
426 {
427 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
428 if (!llvm::is_contained({RISCV::ADD, RISCV::ADDW}, MI->getOpcode()))
429 return false;
430 }
431 if (!FirstMI)
432 return true;
433 {
434 [[maybe_unused]] const MachineInstr *MI = FirstMI;
435 if (!llvm::is_contained({RISCV::MUL, RISCV::MULW}, MI->getOpcode()))
436 return false;
437 }
438 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
439 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
440 return false;
441 }
442 {
443 Register FirstDest = FirstMI->getOperand(0).getReg();
444 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
445 return false;
446 }
447 if (!(FirstMI->getOperand(0).isReg() &&
448 SecondMI.getOperand(1).isReg() &&
449 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
450 return false;
451
452 if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
453 (SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
454 return false;
455 {
456 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
457 if (MI->getOperand(0).getReg() == MI->getOperand(2).getReg())
458 return false;
459 }
460 if (SecondMI.getMF()->getProperties().hasNoVRegs())
461 ++NumTuneFusionMulAddPostRA;
462 else
463 ++NumTuneFusionMulAddPreRA;
464 return true;
465}
466STATISTIC(NumTuneFusionShiftBitExtractPreRA, "Times TuneFusionShiftBitExtract Triggered (pre-ra)");
467STATISTIC(NumTuneFusionShiftBitExtractPostRA, "Times TuneFusionShiftBitExtract Triggered (post-ra)");
468bool isTuneFusionShiftBitExtract(
469 const TargetInstrInfo &TII,
470 const TargetSubtargetInfo &STI,
471 const MachineInstr *FirstMI,
472 const MachineInstr &SecondMI) {
473 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
474 {
475 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
476 if (!llvm::is_contained({RISCV::SRLI, RISCV::SRLIW, RISCV::SRAI, RISCV::SRAIW}, MI->getOpcode()))
477 return false;
478 }
479 if (!FirstMI)
480 return true;
481 {
482 [[maybe_unused]] const MachineInstr *MI = FirstMI;
483 if (!llvm::is_contained({RISCV::SLLI, RISCV::SLLIW}, MI->getOpcode()))
484 return false;
485 }
486 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
487 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
488 return false;
489 }
490 {
491 Register FirstDest = FirstMI->getOperand(0).getReg();
492 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
493 return false;
494 }
495 if (!(FirstMI->getOperand(0).isReg() &&
496 SecondMI.getOperand(1).isReg() &&
497 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
498 return false;
499
500 if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
501 (SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
502 return false;
503
504 if (!(FirstMI->getOperand(2).isImm() &&
505 SecondMI.getOperand(2).isImm() &&
506 FirstMI->getOperand(2).getImm() <=
507 SecondMI.getOperand(2).getImm()))
508 return false;
509 if (SecondMI.getMF()->getProperties().hasNoVRegs())
510 ++NumTuneFusionShiftBitExtractPostRA;
511 else
512 ++NumTuneFusionShiftBitExtractPreRA;
513 return true;
514}
515STATISTIC(NumTuneLDADDFusionPreRA, "Times TuneLDADDFusion Triggered (pre-ra)");
516STATISTIC(NumTuneLDADDFusionPostRA, "Times TuneLDADDFusion Triggered (post-ra)");
517bool isTuneLDADDFusion(
518 const TargetInstrInfo &TII,
519 const TargetSubtargetInfo &STI,
520 const MachineInstr *FirstMI,
521 const MachineInstr &SecondMI) {
522 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
523 {
524 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
525 if (!(
526 ( MI->getOpcode() == RISCV::LD )
527 && MI->getOperand(2).isImm()
528 && MI->getOperand(2).getImm() == 0
529 ))
530 return false;
531 }
532 if (!FirstMI)
533 return true;
534 {
535 [[maybe_unused]] const MachineInstr *MI = FirstMI;
536 if (( MI->getOpcode() != RISCV::ADD ))
537 return false;
538 }
539 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
540 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
541 return false;
542 }
543 {
544 Register FirstDest = FirstMI->getOperand(0).getReg();
545 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
546 return false;
547 }
548 if (!(FirstMI->getOperand(0).isReg() &&
549 SecondMI.getOperand(1).isReg() &&
550 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
551 return false;
552 if (SecondMI.getMF()->getProperties().hasNoVRegs())
553 ++NumTuneLDADDFusionPostRA;
554 else
555 ++NumTuneLDADDFusionPreRA;
556 return true;
557}
558STATISTIC(NumTuneLUIADDIFusionPreRA, "Times TuneLUIADDIFusion Triggered (pre-ra)");
559STATISTIC(NumTuneLUIADDIFusionPostRA, "Times TuneLUIADDIFusion Triggered (post-ra)");
560bool isTuneLUIADDIFusion(
561 const TargetInstrInfo &TII,
562 const TargetSubtargetInfo &STI,
563 const MachineInstr *FirstMI,
564 const MachineInstr &SecondMI) {
565 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
566 {
567 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
568 if (!llvm::is_contained({RISCV::ADDI, RISCV::ADDIW}, MI->getOpcode()))
569 return false;
570 }
571 if (!FirstMI)
572 return true;
573 {
574 [[maybe_unused]] const MachineInstr *MI = FirstMI;
575 if (( MI->getOpcode() != RISCV::LUI ))
576 return false;
577 }
578 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
579 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
580 return false;
581 }
582 {
583 Register FirstDest = FirstMI->getOperand(0).getReg();
584 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
585 return false;
586 }
587 if (!(FirstMI->getOperand(0).isReg() &&
588 SecondMI.getOperand(1).isReg() &&
589 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
590 return false;
591 if (SecondMI.getMF()->getProperties().hasNoVRegs())
592 ++NumTuneLUIADDIFusionPostRA;
593 else
594 ++NumTuneLUIADDIFusionPreRA;
595 return true;
596}
597STATISTIC(NumTuneLUILoadFusionPreRA, "Times TuneLUILoadFusion Triggered (pre-ra)");
598STATISTIC(NumTuneLUILoadFusionPostRA, "Times TuneLUILoadFusion Triggered (post-ra)");
599bool isTuneLUILoadFusion(
600 const TargetInstrInfo &TII,
601 const TargetSubtargetInfo &STI,
602 const MachineInstr *FirstMI,
603 const MachineInstr &SecondMI) {
604 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
605 {
606 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
607 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
608 return false;
609 }
610 if (!FirstMI)
611 return true;
612 {
613 [[maybe_unused]] const MachineInstr *MI = FirstMI;
614 if (( MI->getOpcode() != RISCV::LUI ))
615 return false;
616 }
617 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
618 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
619 return false;
620 }
621 {
622 Register FirstDest = FirstMI->getOperand(0).getReg();
623 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
624 return false;
625 }
626 if (!(FirstMI->getOperand(0).isReg() &&
627 SecondMI.getOperand(1).isReg() &&
628 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
629 return false;
630 if (SecondMI.getMF()->getProperties().hasNoVRegs())
631 ++NumTuneLUILoadFusionPostRA;
632 else
633 ++NumTuneLUILoadFusionPreRA;
634 return true;
635}
636STATISTIC(NumTuneQCELILoadStoreFusionPreRA, "Times TuneQCELILoadStoreFusion Triggered (pre-ra)");
637STATISTIC(NumTuneQCELILoadStoreFusionPostRA, "Times TuneQCELILoadStoreFusion Triggered (post-ra)");
638bool isTuneQCELILoadStoreFusion(
639 const TargetInstrInfo &TII,
640 const TargetSubtargetInfo &STI,
641 const MachineInstr *FirstMI,
642 const MachineInstr &SecondMI) {
643 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
644 {
645 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
646 if (!llvm::is_contained({RISCV::LB, RISCV::LBU, RISCV::LH, RISCV::LHU, RISCV::LW, RISCV::SB, RISCV::SH, RISCV::SW}, MI->getOpcode()))
647 return false;
648 }
649 if (!FirstMI)
650 return true;
651 {
652 [[maybe_unused]] const MachineInstr *MI = FirstMI;
653 if (( MI->getOpcode() != RISCV::QC_E_LI ))
654 return false;
655 }
656 {
657 Register FirstDest = FirstMI->getOperand(0).getReg();
658 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
659 return false;
660 }
661 if (!(FirstMI->getOperand(0).isReg() &&
662 SecondMI.getOperand(1).isReg() &&
663 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
664 return false;
665 if (SecondMI.getMF()->getProperties().hasNoVRegs())
666 ++NumTuneQCELILoadStoreFusionPostRA;
667 else
668 ++NumTuneQCELILoadStoreFusionPreRA;
669 return true;
670}
671STATISTIC(NumTuneSHXADDLoadFusionPreRA, "Times TuneSHXADDLoadFusion Triggered (pre-ra)");
672STATISTIC(NumTuneSHXADDLoadFusionPostRA, "Times TuneSHXADDLoadFusion Triggered (post-ra)");
673bool isTuneSHXADDLoadFusion(
674 const TargetInstrInfo &TII,
675 const TargetSubtargetInfo &STI,
676 const MachineInstr *FirstMI,
677 const MachineInstr &SecondMI) {
678 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
679 {
680 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
681 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
682 return false;
683 }
684 if (!FirstMI)
685 return true;
686 {
687 [[maybe_unused]] const MachineInstr *MI = FirstMI;
688 if (!llvm::is_contained({RISCV::SH1ADD, RISCV::SH2ADD, RISCV::SH3ADD, RISCV::SH1ADD_UW, RISCV::SH2ADD_UW, RISCV::SH3ADD_UW}, MI->getOpcode()))
689 return false;
690 }
691 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
692 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
693 return false;
694 }
695 {
696 Register FirstDest = FirstMI->getOperand(0).getReg();
697 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
698 return false;
699 }
700 if (!(FirstMI->getOperand(0).isReg() &&
701 SecondMI.getOperand(1).isReg() &&
702 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
703 return false;
704 if (SecondMI.getMF()->getProperties().hasNoVRegs())
705 ++NumTuneSHXADDLoadFusionPostRA;
706 else
707 ++NumTuneSHXADDLoadFusionPreRA;
708 return true;
709}
710STATISTIC(NumTuneShiftedZExtWFusionPreRA, "Times TuneShiftedZExtWFusion Triggered (pre-ra)");
711STATISTIC(NumTuneShiftedZExtWFusionPostRA, "Times TuneShiftedZExtWFusion Triggered (post-ra)");
712bool isTuneShiftedZExtWFusion(
713 const TargetInstrInfo &TII,
714 const TargetSubtargetInfo &STI,
715 const MachineInstr *FirstMI,
716 const MachineInstr &SecondMI) {
717 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
718 {
719 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
720 if (!(
721 ( MI->getOpcode() == RISCV::SRLI )
722 && MI->getOperand(2).isImm()
723 && (
724 MI->getOperand(2).getImm() >= 0
725 && MI->getOperand(2).getImm() <= 31
726 )
727 ))
728 return false;
729 }
730 if (!FirstMI)
731 return true;
732 {
733 [[maybe_unused]] const MachineInstr *MI = FirstMI;
734 if (!(
735 ( MI->getOpcode() == RISCV::SLLI )
736 && MI->getOperand(2).isImm()
737 && MI->getOperand(2).getImm() == 32
738 ))
739 return false;
740 }
741 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
742 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
743 return false;
744 }
745 {
746 Register FirstDest = FirstMI->getOperand(0).getReg();
747 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
748 return false;
749 }
750 if (!(FirstMI->getOperand(0).isReg() &&
751 SecondMI.getOperand(1).isReg() &&
752 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
753 return false;
754 if (SecondMI.getMF()->getProperties().hasNoVRegs())
755 ++NumTuneShiftedZExtWFusionPostRA;
756 else
757 ++NumTuneShiftedZExtWFusionPreRA;
758 return true;
759}
760STATISTIC(NumTuneZExtHFusionPreRA, "Times TuneZExtHFusion Triggered (pre-ra)");
761STATISTIC(NumTuneZExtHFusionPostRA, "Times TuneZExtHFusion Triggered (post-ra)");
762bool isTuneZExtHFusion(
763 const TargetInstrInfo &TII,
764 const TargetSubtargetInfo &STI,
765 const MachineInstr *FirstMI,
766 const MachineInstr &SecondMI) {
767 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
768 {
769 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
770 if (!(
771 ( MI->getOpcode() == RISCV::SRLI )
772 && MI->getOperand(2).isImm()
773 && MI->getOperand(2).getImm() == 48
774 ))
775 return false;
776 }
777 if (!FirstMI)
778 return true;
779 {
780 [[maybe_unused]] const MachineInstr *MI = FirstMI;
781 if (!(
782 ( MI->getOpcode() == RISCV::SLLI )
783 && MI->getOperand(2).isImm()
784 && MI->getOperand(2).getImm() == 48
785 ))
786 return false;
787 }
788 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
789 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
790 return false;
791 }
792 {
793 Register FirstDest = FirstMI->getOperand(0).getReg();
794 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
795 return false;
796 }
797 if (!(FirstMI->getOperand(0).isReg() &&
798 SecondMI.getOperand(1).isReg() &&
799 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
800 return false;
801 if (SecondMI.getMF()->getProperties().hasNoVRegs())
802 ++NumTuneZExtHFusionPostRA;
803 else
804 ++NumTuneZExtHFusionPreRA;
805 return true;
806}
807STATISTIC(NumTuneZExtWFusionPreRA, "Times TuneZExtWFusion Triggered (pre-ra)");
808STATISTIC(NumTuneZExtWFusionPostRA, "Times TuneZExtWFusion Triggered (post-ra)");
809bool isTuneZExtWFusion(
810 const TargetInstrInfo &TII,
811 const TargetSubtargetInfo &STI,
812 const MachineInstr *FirstMI,
813 const MachineInstr &SecondMI) {
814 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
815 {
816 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
817 if (!(
818 ( MI->getOpcode() == RISCV::SRLI )
819 && MI->getOperand(2).isImm()
820 && MI->getOperand(2).getImm() == 32
821 ))
822 return false;
823 }
824 if (!FirstMI)
825 return true;
826 {
827 [[maybe_unused]] const MachineInstr *MI = FirstMI;
828 if (!(
829 ( MI->getOpcode() == RISCV::SLLI )
830 && MI->getOperand(2).isImm()
831 && MI->getOperand(2).getImm() == 32
832 ))
833 return false;
834 }
835 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
836 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
837 return false;
838 }
839 {
840 Register FirstDest = FirstMI->getOperand(0).getReg();
841 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
842 return false;
843 }
844 if (!(FirstMI->getOperand(0).isReg() &&
845 SecondMI.getOperand(1).isReg() &&
846 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
847 return false;
848 if (SecondMI.getMF()->getProperties().hasNoVRegs())
849 ++NumTuneZExtWFusionPostRA;
850 else
851 ++NumTuneZExtWFusionPreRA;
852 return true;
853}
854
855} // namespace llvm
856
857#endif // GET_RISCV_MACRO_FUSION_PRED_IMPL
858
859