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 &, const SDep *);
15bool isTuneADDLoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
16bool isTuneAUIPCADDIFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
17bool isTuneAUIPCLoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
18bool isTuneBFExtFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
19bool isTuneFusionAddMem(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
20bool isTuneFusionLogicImmReg(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
21bool isTuneFusionLogicRegImm(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
22bool isTuneFusionLogicRegReg(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
23bool isTuneFusionMulAdd(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
24bool isTuneFusionShiftBitExtract(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
25bool isTuneLDADDFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
26bool isTuneLUIADDIFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
27bool isTuneLUILoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
28bool isTuneMOVIMMALUXqciFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
29bool isTuneMOVIMMJumpXqciFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
30bool isTuneMOVIMMLoadStoreXqciFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
31bool isTuneMOVIMMLongAccumXciFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
32bool isTuneMOVIMMMULXqciFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
33bool isTuneMovALUXqciFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
34bool isTuneQCELILoadStoreFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
35bool isTuneSHXADDLoadFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
36bool isTuneShiftedZExtWFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
37bool isTuneZExtHFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
38bool isTuneZExtWFusion(const TargetInstrInfo &, const TargetSubtargetInfo &, const MachineInstr *, const MachineInstr &, const SDep *);
39
40} // namespace llvm
41
42#endif // GET_RISCV_MACRO_FUSION_PRED_DECL
43
44
45#ifdef GET_RISCV_MACRO_FUSION_PRED_IMPL
46#undef GET_RISCV_MACRO_FUSION_PRED_IMPL
47
48namespace llvm {
49
50STATISTIC(NumTuneADDILoadFusionPreRA, "Times TuneADDILoadFusion Triggered (pre-ra)");
51STATISTIC(NumTuneADDILoadFusionPostRA, "Times TuneADDILoadFusion Triggered (post-ra)");
52bool isTuneADDILoadFusion(
53 const TargetInstrInfo &TII,
54 const TargetSubtargetInfo &STI,
55 const MachineInstr *FirstMI,
56 const MachineInstr &SecondMI, const SDep *Dep) {
57 if (isNonDataDep(Dep))
58 return false;
59 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
60 {
61 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
62 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
63 return false;
64 }
65 if (!FirstMI)
66 return true;
67 {
68 [[maybe_unused]] const MachineInstr *MI = FirstMI;
69 if (( MI->getOpcode() != RISCV::ADDI ))
70 return false;
71 }
72 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
73 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
74 return false;
75 }
76 {
77 Register FirstDest = FirstMI->getOperand(0).getReg();
78 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
79 return false;
80 }
81 if (!(FirstMI->getOperand(0).isReg() &&
82 SecondMI.getOperand(1).isReg() &&
83 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
84 return false;
85 if (SecondMI.getMF()->getProperties().hasNoVRegs())
86 ++NumTuneADDILoadFusionPostRA;
87 else
88 ++NumTuneADDILoadFusionPreRA;
89 return true;
90}
91STATISTIC(NumTuneADDLoadFusionPreRA, "Times TuneADDLoadFusion Triggered (pre-ra)");
92STATISTIC(NumTuneADDLoadFusionPostRA, "Times TuneADDLoadFusion Triggered (post-ra)");
93bool isTuneADDLoadFusion(
94 const TargetInstrInfo &TII,
95 const TargetSubtargetInfo &STI,
96 const MachineInstr *FirstMI,
97 const MachineInstr &SecondMI, const SDep *Dep) {
98 if (isNonDataDep(Dep))
99 return false;
100 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
101 {
102 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
103 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
104 return false;
105 }
106 if (!FirstMI)
107 return true;
108 {
109 [[maybe_unused]] const MachineInstr *MI = FirstMI;
110 if (!llvm::is_contained({RISCV::ADD, RISCV::ADD_UW}, MI->getOpcode()))
111 return false;
112 }
113 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
114 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
115 return false;
116 }
117 {
118 Register FirstDest = FirstMI->getOperand(0).getReg();
119 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
120 return false;
121 }
122 if (!(FirstMI->getOperand(0).isReg() &&
123 SecondMI.getOperand(1).isReg() &&
124 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
125 return false;
126 if (SecondMI.getMF()->getProperties().hasNoVRegs())
127 ++NumTuneADDLoadFusionPostRA;
128 else
129 ++NumTuneADDLoadFusionPreRA;
130 return true;
131}
132STATISTIC(NumTuneAUIPCADDIFusionPreRA, "Times TuneAUIPCADDIFusion Triggered (pre-ra)");
133STATISTIC(NumTuneAUIPCADDIFusionPostRA, "Times TuneAUIPCADDIFusion Triggered (post-ra)");
134bool isTuneAUIPCADDIFusion(
135 const TargetInstrInfo &TII,
136 const TargetSubtargetInfo &STI,
137 const MachineInstr *FirstMI,
138 const MachineInstr &SecondMI, const SDep *Dep) {
139 if (isNonDataDep(Dep))
140 return false;
141 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
142 {
143 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
144 if (( MI->getOpcode() != RISCV::ADDI ))
145 return false;
146 }
147 if (!FirstMI)
148 return true;
149 {
150 [[maybe_unused]] const MachineInstr *MI = FirstMI;
151 if (( MI->getOpcode() != RISCV::AUIPC ))
152 return false;
153 }
154 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
155 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
156 return false;
157 }
158 {
159 Register FirstDest = FirstMI->getOperand(0).getReg();
160 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
161 return false;
162 }
163 if (!(FirstMI->getOperand(0).isReg() &&
164 SecondMI.getOperand(1).isReg() &&
165 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
166 return false;
167 if (SecondMI.getMF()->getProperties().hasNoVRegs())
168 ++NumTuneAUIPCADDIFusionPostRA;
169 else
170 ++NumTuneAUIPCADDIFusionPreRA;
171 return true;
172}
173STATISTIC(NumTuneAUIPCLoadFusionPreRA, "Times TuneAUIPCLoadFusion Triggered (pre-ra)");
174STATISTIC(NumTuneAUIPCLoadFusionPostRA, "Times TuneAUIPCLoadFusion Triggered (post-ra)");
175bool isTuneAUIPCLoadFusion(
176 const TargetInstrInfo &TII,
177 const TargetSubtargetInfo &STI,
178 const MachineInstr *FirstMI,
179 const MachineInstr &SecondMI, const SDep *Dep) {
180 if (isNonDataDep(Dep))
181 return false;
182 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
183 {
184 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
185 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
186 return false;
187 }
188 if (!FirstMI)
189 return true;
190 {
191 [[maybe_unused]] const MachineInstr *MI = FirstMI;
192 if (( MI->getOpcode() != RISCV::AUIPC ))
193 return false;
194 }
195 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
196 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
197 return false;
198 }
199 {
200 Register FirstDest = FirstMI->getOperand(0).getReg();
201 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
202 return false;
203 }
204 if (!(FirstMI->getOperand(0).isReg() &&
205 SecondMI.getOperand(1).isReg() &&
206 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
207 return false;
208 if (SecondMI.getMF()->getProperties().hasNoVRegs())
209 ++NumTuneAUIPCLoadFusionPostRA;
210 else
211 ++NumTuneAUIPCLoadFusionPreRA;
212 return true;
213}
214STATISTIC(NumTuneBFExtFusionPreRA, "Times TuneBFExtFusion Triggered (pre-ra)");
215STATISTIC(NumTuneBFExtFusionPostRA, "Times TuneBFExtFusion Triggered (post-ra)");
216bool isTuneBFExtFusion(
217 const TargetInstrInfo &TII,
218 const TargetSubtargetInfo &STI,
219 const MachineInstr *FirstMI,
220 const MachineInstr &SecondMI, const SDep *Dep) {
221 if (isNonDataDep(Dep))
222 return false;
223 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
224 {
225 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
226 if (( MI->getOpcode() != RISCV::SRLI ))
227 return false;
228 }
229 if (!FirstMI)
230 return true;
231 {
232 [[maybe_unused]] const MachineInstr *MI = FirstMI;
233 if (( MI->getOpcode() != RISCV::SLLI ))
234 return false;
235 }
236 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
237 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
238 return false;
239 }
240 {
241 Register FirstDest = FirstMI->getOperand(0).getReg();
242 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
243 return false;
244 }
245 if (!(FirstMI->getOperand(0).isReg() &&
246 SecondMI.getOperand(1).isReg() &&
247 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
248 return false;
249 if (SecondMI.getMF()->getProperties().hasNoVRegs())
250 ++NumTuneBFExtFusionPostRA;
251 else
252 ++NumTuneBFExtFusionPreRA;
253 return true;
254}
255STATISTIC(NumTuneFusionAddMemPreRA, "Times TuneFusionAddMem Triggered (pre-ra)");
256STATISTIC(NumTuneFusionAddMemPostRA, "Times TuneFusionAddMem Triggered (post-ra)");
257bool isTuneFusionAddMem(
258 const TargetInstrInfo &TII,
259 const TargetSubtargetInfo &STI,
260 const MachineInstr *FirstMI,
261 const MachineInstr &SecondMI, const SDep *Dep) {
262 if (isNonDataDep(Dep))
263 return false;
264 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
265 {
266 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
267 if (!(
268 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())
269 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
270 ))
271 return false;
272 }
273 if (!FirstMI)
274 return true;
275 {
276 [[maybe_unused]] const MachineInstr *MI = FirstMI;
277 if (!(
278 ( MI->getOpcode() == RISCV::ADD )
279 && !(MI->getOperand(0).isReg() && MI->getOperand(1).isReg() && MI->getOperand(0).getReg() == MI->getOperand(1).getReg())
280 && !(MI->getOperand(0).isReg() && MI->getOperand(2).isReg() && MI->getOperand(0).getReg() == MI->getOperand(2).getReg())
281 ))
282 return false;
283 }
284 if (!(FirstMI->getOperand(0).isReg() &&
285 SecondMI.getOperand(1).isReg() &&
286 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
287 return false;
288 if (SecondMI.getMF()->getProperties().hasNoVRegs())
289 ++NumTuneFusionAddMemPostRA;
290 else
291 ++NumTuneFusionAddMemPreRA;
292 return true;
293}
294STATISTIC(NumTuneFusionLogicImmRegPreRA, "Times TuneFusionLogicImmReg Triggered (pre-ra)");
295STATISTIC(NumTuneFusionLogicImmRegPostRA, "Times TuneFusionLogicImmReg Triggered (post-ra)");
296bool isTuneFusionLogicImmReg(
297 const TargetInstrInfo &TII,
298 const TargetSubtargetInfo &STI,
299 const MachineInstr *FirstMI,
300 const MachineInstr &SecondMI, const SDep *Dep) {
301 if (isNonDataDep(Dep))
302 return false;
303 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
304 {
305 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
306 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
307 return false;
308 }
309 if (!FirstMI)
310 return true;
311 {
312 [[maybe_unused]] const MachineInstr *MI = FirstMI;
313 if (!llvm::is_contained({RISCV::ANDI, RISCV::ORI, RISCV::XORI}, MI->getOpcode()))
314 return false;
315 }
316 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
317 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) {
318 if (!SecondMI.getDesc().isCommutable())
319 return false;
320 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
321 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
322 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
323 return false;
324 }
325 }
326 {
327 Register FirstDest = FirstMI->getOperand(0).getReg();
328 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
329 return false;
330 }
331 if (!(FirstMI->getOperand(0).isReg() &&
332 SecondMI.getOperand(1).isReg() &&
333 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
334 if (!SecondMI.getDesc().isCommutable())
335 return false;
336 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
337 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
338 if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
339 return false;
340 }
341 if (SecondMI.getMF()->getProperties().hasNoVRegs())
342 ++NumTuneFusionLogicImmRegPostRA;
343 else
344 ++NumTuneFusionLogicImmRegPreRA;
345 return true;
346}
347STATISTIC(NumTuneFusionLogicRegImmPreRA, "Times TuneFusionLogicRegImm Triggered (pre-ra)");
348STATISTIC(NumTuneFusionLogicRegImmPostRA, "Times TuneFusionLogicRegImm Triggered (post-ra)");
349bool isTuneFusionLogicRegImm(
350 const TargetInstrInfo &TII,
351 const TargetSubtargetInfo &STI,
352 const MachineInstr *FirstMI,
353 const MachineInstr &SecondMI, const SDep *Dep) {
354 if (isNonDataDep(Dep))
355 return false;
356 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
357 {
358 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
359 if (!llvm::is_contained({RISCV::ANDI, RISCV::ORI, RISCV::XORI}, MI->getOpcode()))
360 return false;
361 }
362 if (!FirstMI)
363 return true;
364 {
365 [[maybe_unused]] const MachineInstr *MI = FirstMI;
366 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
367 return false;
368 }
369 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
370 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
371 return false;
372 }
373 {
374 Register FirstDest = FirstMI->getOperand(0).getReg();
375 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
376 return false;
377 }
378 if (!(FirstMI->getOperand(0).isReg() &&
379 SecondMI.getOperand(1).isReg() &&
380 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
381 return false;
382 if (SecondMI.getMF()->getProperties().hasNoVRegs())
383 ++NumTuneFusionLogicRegImmPostRA;
384 else
385 ++NumTuneFusionLogicRegImmPreRA;
386 return true;
387}
388STATISTIC(NumTuneFusionLogicRegRegPreRA, "Times TuneFusionLogicRegReg Triggered (pre-ra)");
389STATISTIC(NumTuneFusionLogicRegRegPostRA, "Times TuneFusionLogicRegReg Triggered (post-ra)");
390bool isTuneFusionLogicRegReg(
391 const TargetInstrInfo &TII,
392 const TargetSubtargetInfo &STI,
393 const MachineInstr *FirstMI,
394 const MachineInstr &SecondMI, const SDep *Dep) {
395 if (isNonDataDep(Dep))
396 return false;
397 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
398 {
399 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
400 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
401 return false;
402 }
403 if (!FirstMI)
404 return true;
405 {
406 [[maybe_unused]] const MachineInstr *MI = FirstMI;
407 if (!llvm::is_contained({RISCV::AND, RISCV::OR, RISCV::XOR}, MI->getOpcode()))
408 return false;
409 }
410 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
411 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg()) {
412 if (!SecondMI.getDesc().isCommutable())
413 return false;
414 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
415 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
416 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
417 return false;
418 }
419 }
420 {
421 Register FirstDest = FirstMI->getOperand(0).getReg();
422 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
423 return false;
424 }
425 if (!(FirstMI->getOperand(0).isReg() &&
426 SecondMI.getOperand(1).isReg() &&
427 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg())) {
428 if (!SecondMI.getDesc().isCommutable())
429 return false;
430 unsigned SrcOpIdx1 = 1, SrcOpIdx2 = TargetInstrInfo::CommuteAnyOperandIndex;
431 if (TII.findCommutedOpIndices(SecondMI, SrcOpIdx1, SrcOpIdx2))
432 if (FirstMI->getOperand(0).getReg() != SecondMI.getOperand(SrcOpIdx2).getReg())
433 return false;
434 }
435 if (SecondMI.getMF()->getProperties().hasNoVRegs())
436 ++NumTuneFusionLogicRegRegPostRA;
437 else
438 ++NumTuneFusionLogicRegRegPreRA;
439 return true;
440}
441STATISTIC(NumTuneFusionMulAddPreRA, "Times TuneFusionMulAdd Triggered (pre-ra)");
442STATISTIC(NumTuneFusionMulAddPostRA, "Times TuneFusionMulAdd Triggered (post-ra)");
443bool isTuneFusionMulAdd(
444 const TargetInstrInfo &TII,
445 const TargetSubtargetInfo &STI,
446 const MachineInstr *FirstMI,
447 const MachineInstr &SecondMI, const SDep *Dep) {
448 if (isNonDataDep(Dep))
449 return false;
450 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
451 {
452 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
453 if (!llvm::is_contained({RISCV::ADD, RISCV::ADDW}, MI->getOpcode()))
454 return false;
455 }
456 if (!FirstMI)
457 return true;
458 {
459 [[maybe_unused]] const MachineInstr *MI = FirstMI;
460 if (!llvm::is_contained({RISCV::MUL, RISCV::MULW}, MI->getOpcode()))
461 return false;
462 }
463 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
464 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
465 return false;
466 }
467 {
468 Register FirstDest = FirstMI->getOperand(0).getReg();
469 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
470 return false;
471 }
472 if (!(FirstMI->getOperand(0).isReg() &&
473 SecondMI.getOperand(1).isReg() &&
474 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
475 return false;
476
477 if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
478 (SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
479 return false;
480 {
481 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
482 if ((MI->getOperand(0).isReg() && MI->getOperand(2).isReg() && MI->getOperand(0).getReg() == MI->getOperand(2).getReg()))
483 return false;
484 }
485 if (SecondMI.getMF()->getProperties().hasNoVRegs())
486 ++NumTuneFusionMulAddPostRA;
487 else
488 ++NumTuneFusionMulAddPreRA;
489 return true;
490}
491STATISTIC(NumTuneFusionShiftBitExtractPreRA, "Times TuneFusionShiftBitExtract Triggered (pre-ra)");
492STATISTIC(NumTuneFusionShiftBitExtractPostRA, "Times TuneFusionShiftBitExtract Triggered (post-ra)");
493bool isTuneFusionShiftBitExtract(
494 const TargetInstrInfo &TII,
495 const TargetSubtargetInfo &STI,
496 const MachineInstr *FirstMI,
497 const MachineInstr &SecondMI, const SDep *Dep) {
498 if (isNonDataDep(Dep))
499 return false;
500 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
501 {
502 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
503 if (!llvm::is_contained({RISCV::SRLI, RISCV::SRLIW, RISCV::SRAI, RISCV::SRAIW}, MI->getOpcode()))
504 return false;
505 }
506 if (!FirstMI)
507 return true;
508 {
509 [[maybe_unused]] const MachineInstr *MI = FirstMI;
510 if (!llvm::is_contained({RISCV::SLLI, RISCV::SLLIW}, MI->getOpcode()))
511 return false;
512 }
513 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
514 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
515 return false;
516 }
517 {
518 Register FirstDest = FirstMI->getOperand(0).getReg();
519 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
520 return false;
521 }
522 if (!(FirstMI->getOperand(0).isReg() &&
523 SecondMI.getOperand(1).isReg() &&
524 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
525 return false;
526
527 if ((FirstMI->getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask) !=
528 (SecondMI.getDesc().TSFlags & RISCVII::IsSignExtendingOpWMask))
529 return false;
530
531 if (!(FirstMI->getOperand(2).isImm() &&
532 SecondMI.getOperand(2).isImm() &&
533 FirstMI->getOperand(2).getImm() <=
534 SecondMI.getOperand(2).getImm()))
535 return false;
536 if (SecondMI.getMF()->getProperties().hasNoVRegs())
537 ++NumTuneFusionShiftBitExtractPostRA;
538 else
539 ++NumTuneFusionShiftBitExtractPreRA;
540 return true;
541}
542STATISTIC(NumTuneLDADDFusionPreRA, "Times TuneLDADDFusion Triggered (pre-ra)");
543STATISTIC(NumTuneLDADDFusionPostRA, "Times TuneLDADDFusion Triggered (post-ra)");
544bool isTuneLDADDFusion(
545 const TargetInstrInfo &TII,
546 const TargetSubtargetInfo &STI,
547 const MachineInstr *FirstMI,
548 const MachineInstr &SecondMI, const SDep *Dep) {
549 if (isNonDataDep(Dep))
550 return false;
551 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
552 {
553 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
554 if (!(
555 ( MI->getOpcode() == RISCV::LD )
556 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
557 ))
558 return false;
559 }
560 if (!FirstMI)
561 return true;
562 {
563 [[maybe_unused]] const MachineInstr *MI = FirstMI;
564 if (( MI->getOpcode() != RISCV::ADD ))
565 return false;
566 }
567 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
568 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
569 return false;
570 }
571 {
572 Register FirstDest = FirstMI->getOperand(0).getReg();
573 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
574 return false;
575 }
576 if (!(FirstMI->getOperand(0).isReg() &&
577 SecondMI.getOperand(1).isReg() &&
578 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
579 return false;
580 if (SecondMI.getMF()->getProperties().hasNoVRegs())
581 ++NumTuneLDADDFusionPostRA;
582 else
583 ++NumTuneLDADDFusionPreRA;
584 return true;
585}
586STATISTIC(NumTuneLUIADDIFusionPreRA, "Times TuneLUIADDIFusion Triggered (pre-ra)");
587STATISTIC(NumTuneLUIADDIFusionPostRA, "Times TuneLUIADDIFusion Triggered (post-ra)");
588bool isTuneLUIADDIFusion(
589 const TargetInstrInfo &TII,
590 const TargetSubtargetInfo &STI,
591 const MachineInstr *FirstMI,
592 const MachineInstr &SecondMI, const SDep *Dep) {
593 if (isNonDataDep(Dep))
594 return false;
595 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
596 {
597 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
598 if (!llvm::is_contained({RISCV::ADDI, RISCV::ADDIW}, MI->getOpcode()))
599 return false;
600 }
601 if (!FirstMI)
602 return true;
603 {
604 [[maybe_unused]] const MachineInstr *MI = FirstMI;
605 if (( MI->getOpcode() != RISCV::LUI ))
606 return false;
607 }
608 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
609 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
610 return false;
611 }
612 {
613 Register FirstDest = FirstMI->getOperand(0).getReg();
614 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
615 return false;
616 }
617 if (!(FirstMI->getOperand(0).isReg() &&
618 SecondMI.getOperand(1).isReg() &&
619 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
620 return false;
621 if (SecondMI.getMF()->getProperties().hasNoVRegs())
622 ++NumTuneLUIADDIFusionPostRA;
623 else
624 ++NumTuneLUIADDIFusionPreRA;
625 return true;
626}
627STATISTIC(NumTuneLUILoadFusionPreRA, "Times TuneLUILoadFusion Triggered (pre-ra)");
628STATISTIC(NumTuneLUILoadFusionPostRA, "Times TuneLUILoadFusion Triggered (post-ra)");
629bool isTuneLUILoadFusion(
630 const TargetInstrInfo &TII,
631 const TargetSubtargetInfo &STI,
632 const MachineInstr *FirstMI,
633 const MachineInstr &SecondMI, const SDep *Dep) {
634 if (isNonDataDep(Dep))
635 return false;
636 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
637 {
638 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
639 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
640 return false;
641 }
642 if (!FirstMI)
643 return true;
644 {
645 [[maybe_unused]] const MachineInstr *MI = FirstMI;
646 if (( MI->getOpcode() != RISCV::LUI ))
647 return false;
648 }
649 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
650 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
651 return false;
652 }
653 {
654 Register FirstDest = FirstMI->getOperand(0).getReg();
655 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
656 return false;
657 }
658 if (!(FirstMI->getOperand(0).isReg() &&
659 SecondMI.getOperand(1).isReg() &&
660 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
661 return false;
662 if (SecondMI.getMF()->getProperties().hasNoVRegs())
663 ++NumTuneLUILoadFusionPostRA;
664 else
665 ++NumTuneLUILoadFusionPreRA;
666 return true;
667}
668STATISTIC(NumTuneMOVIMMALUXqciFusionPreRA, "Times TuneMOVIMMALUXqciFusion Triggered (pre-ra)");
669STATISTIC(NumTuneMOVIMMALUXqciFusionPostRA, "Times TuneMOVIMMALUXqciFusion Triggered (post-ra)");
670bool isTuneMOVIMMALUXqciFusion(
671 const TargetInstrInfo &TII,
672 const TargetSubtargetInfo &STI,
673 const MachineInstr *FirstMI,
674 const MachineInstr &SecondMI, const SDep *Dep) {
675 if (isNonDataDep(Dep))
676 return false;
677 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
678 {
679 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
680 if (!llvm::is_contained({RISCV::ADD, RISCV::ADDI, RISCV::SUB, RISCV::MUL, RISCV::AND, RISCV::ANDI, RISCV::ANDN, RISCV::OR, RISCV::ORI, RISCV::ORN, RISCV::XOR, RISCV::XORI, RISCV::XNOR, RISCV::QC_E_ANDI, RISCV::QC_E_ORI, RISCV::QC_E_XORI, RISCV::SLLI, RISCV::SRLI, RISCV::SRAI, RISCV::QC_LI, RISCV::QC_E_LI, RISCV::MAX, RISCV::MAXU, RISCV::MIN, RISCV::MINU}, MI->getOpcode()))
681 return false;
682 }
683 if (!FirstMI)
684 return true;
685 {
686 [[maybe_unused]] const MachineInstr *MI = FirstMI;
687 if (!(
688 (
689 ( MI->getOpcode() == RISCV::ADDI )
690 && (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == RISCV::X0)
691 )
692 || llvm::is_contained({RISCV::LUI, RISCV::QC_E_LI, RISCV::QC_LI}, MI->getOpcode())
693 || ( MI->getOpcode() == RISCV::AUIPC )
694 ))
695 return false;
696 }
697 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
698 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
699 return false;
700 }
701 {
702 Register FirstDest = FirstMI->getOperand(0).getReg();
703 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
704 return false;
705 }
706 if (!(FirstMI->getOperand(0).isReg() &&
707 SecondMI.getOperand(1).isReg() &&
708 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
709 return false;
710 if (SecondMI.getMF()->getProperties().hasNoVRegs())
711 ++NumTuneMOVIMMALUXqciFusionPostRA;
712 else
713 ++NumTuneMOVIMMALUXqciFusionPreRA;
714 return true;
715}
716STATISTIC(NumTuneMOVIMMJumpXqciFusionPreRA, "Times TuneMOVIMMJumpXqciFusion Triggered (pre-ra)");
717STATISTIC(NumTuneMOVIMMJumpXqciFusionPostRA, "Times TuneMOVIMMJumpXqciFusion Triggered (post-ra)");
718bool isTuneMOVIMMJumpXqciFusion(
719 const TargetInstrInfo &TII,
720 const TargetSubtargetInfo &STI,
721 const MachineInstr *FirstMI,
722 const MachineInstr &SecondMI, const SDep *Dep) {
723 if (isNonDataDep(Dep))
724 return false;
725 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
726 {
727 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
728 if (( MI->getOpcode() != RISCV::JALR ))
729 return false;
730 }
731 if (!FirstMI)
732 return true;
733 {
734 [[maybe_unused]] const MachineInstr *MI = FirstMI;
735 if (!(
736 (
737 ( MI->getOpcode() == RISCV::ADDI )
738 && (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == RISCV::X0)
739 )
740 || llvm::is_contained({RISCV::LUI, RISCV::QC_E_LI, RISCV::QC_LI}, MI->getOpcode())
741 ))
742 return false;
743 }
744 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
745 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
746 return false;
747 }
748 {
749 Register FirstDest = FirstMI->getOperand(0).getReg();
750 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
751 return false;
752 }
753 if (!(FirstMI->getOperand(0).isReg() &&
754 SecondMI.getOperand(1).isReg() &&
755 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
756 return false;
757 if (SecondMI.getMF()->getProperties().hasNoVRegs())
758 ++NumTuneMOVIMMJumpXqciFusionPostRA;
759 else
760 ++NumTuneMOVIMMJumpXqciFusionPreRA;
761 return true;
762}
763STATISTIC(NumTuneMOVIMMLoadStoreXqciFusionPreRA, "Times TuneMOVIMMLoadStoreXqciFusion Triggered (pre-ra)");
764STATISTIC(NumTuneMOVIMMLoadStoreXqciFusionPostRA, "Times TuneMOVIMMLoadStoreXqciFusion Triggered (post-ra)");
765bool isTuneMOVIMMLoadStoreXqciFusion(
766 const TargetInstrInfo &TII,
767 const TargetSubtargetInfo &STI,
768 const MachineInstr *FirstMI,
769 const MachineInstr &SecondMI, const SDep *Dep) {
770 if (isNonDataDep(Dep))
771 return false;
772 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
773 {
774 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
775 if (!llvm::is_contained({RISCV::QC_E_LB, RISCV::QC_E_LBU, RISCV::QC_E_LH, RISCV::QC_E_LHU, RISCV::QC_E_LW, RISCV::QC_E_SB, RISCV::QC_E_SH, RISCV::QC_E_SW}, MI->getOpcode()))
776 return false;
777 }
778 if (!FirstMI)
779 return true;
780 {
781 [[maybe_unused]] const MachineInstr *MI = FirstMI;
782 if (!(
783 (
784 ( MI->getOpcode() == RISCV::ADDI )
785 && (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == RISCV::X0)
786 )
787 || llvm::is_contained({RISCV::LUI, RISCV::QC_E_LI, RISCV::QC_LI}, MI->getOpcode())
788 ))
789 return false;
790 }
791 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
792 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
793 return false;
794 }
795 {
796 Register FirstDest = FirstMI->getOperand(0).getReg();
797 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
798 return false;
799 }
800 if (!(FirstMI->getOperand(0).isReg() &&
801 SecondMI.getOperand(1).isReg() &&
802 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
803 return false;
804 if (SecondMI.getMF()->getProperties().hasNoVRegs())
805 ++NumTuneMOVIMMLoadStoreXqciFusionPostRA;
806 else
807 ++NumTuneMOVIMMLoadStoreXqciFusionPreRA;
808 return true;
809}
810STATISTIC(NumTuneMOVIMMLongAccumXciFusionPreRA, "Times TuneMOVIMMLongAccumXciFusion Triggered (pre-ra)");
811STATISTIC(NumTuneMOVIMMLongAccumXciFusionPostRA, "Times TuneMOVIMMLongAccumXciFusion Triggered (post-ra)");
812bool isTuneMOVIMMLongAccumXciFusion(
813 const TargetInstrInfo &TII,
814 const TargetSubtargetInfo &STI,
815 const MachineInstr *FirstMI,
816 const MachineInstr &SecondMI, const SDep *Dep) {
817 if (isNonDataDep(Dep))
818 return false;
819 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
820 {
821 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
822 if (!llvm::is_contained({RISCV::QC_E_XORAI, RISCV::QC_E_ORAI, RISCV::QC_E_ANDAI, RISCV::QC_E_ADDAI}, MI->getOpcode()))
823 return false;
824 }
825 if (!FirstMI)
826 return true;
827 {
828 [[maybe_unused]] const MachineInstr *MI = FirstMI;
829 if (!(
830 (
831 ( MI->getOpcode() == RISCV::ADDI )
832 && (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == RISCV::X0)
833 )
834 || llvm::is_contained({RISCV::LUI, RISCV::QC_E_LI, RISCV::QC_LI}, MI->getOpcode())
835 ))
836 return false;
837 }
838 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
839 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
840 return false;
841 }
842 {
843 Register FirstDest = FirstMI->getOperand(0).getReg();
844 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
845 return false;
846 }
847 if (!(FirstMI->getOperand(0).isReg() &&
848 SecondMI.getOperand(1).isReg() &&
849 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
850 return false;
851 if (!(FirstMI->getOperand(0).isReg() &&
852 SecondMI.getOperand(0).isReg() &&
853 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(0).getReg()))
854 return false;
855 if (SecondMI.getMF()->getProperties().hasNoVRegs())
856 ++NumTuneMOVIMMLongAccumXciFusionPostRA;
857 else
858 ++NumTuneMOVIMMLongAccumXciFusionPreRA;
859 return true;
860}
861STATISTIC(NumTuneMOVIMMMULXqciFusionPreRA, "Times TuneMOVIMMMULXqciFusion Triggered (pre-ra)");
862STATISTIC(NumTuneMOVIMMMULXqciFusionPostRA, "Times TuneMOVIMMMULXqciFusion Triggered (post-ra)");
863bool isTuneMOVIMMMULXqciFusion(
864 const TargetInstrInfo &TII,
865 const TargetSubtargetInfo &STI,
866 const MachineInstr *FirstMI,
867 const MachineInstr &SecondMI, const SDep *Dep) {
868 if (isNonDataDep(Dep))
869 return false;
870 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
871 {
872 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
873 if (( MI->getOpcode() != RISCV::MUL ))
874 return false;
875 }
876 if (!FirstMI)
877 return true;
878 {
879 [[maybe_unused]] const MachineInstr *MI = FirstMI;
880 if (!(
881 (
882 ( MI->getOpcode() == RISCV::ADDI )
883 && (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == RISCV::X0)
884 )
885 || llvm::is_contained({RISCV::LUI, RISCV::QC_E_LI, RISCV::QC_LI}, MI->getOpcode())
886 ))
887 return false;
888 }
889 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
890 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
891 return false;
892 }
893 {
894 Register FirstDest = FirstMI->getOperand(0).getReg();
895 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
896 return false;
897 }
898 if (!(FirstMI->getOperand(0).isReg() &&
899 SecondMI.getOperand(1).isReg() &&
900 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
901 return false;
902 if (SecondMI.getMF()->getProperties().hasNoVRegs())
903 ++NumTuneMOVIMMMULXqciFusionPostRA;
904 else
905 ++NumTuneMOVIMMMULXqciFusionPreRA;
906 return true;
907}
908STATISTIC(NumTuneMovALUXqciFusionPreRA, "Times TuneMovALUXqciFusion Triggered (pre-ra)");
909STATISTIC(NumTuneMovALUXqciFusionPostRA, "Times TuneMovALUXqciFusion Triggered (post-ra)");
910bool isTuneMovALUXqciFusion(
911 const TargetInstrInfo &TII,
912 const TargetSubtargetInfo &STI,
913 const MachineInstr *FirstMI,
914 const MachineInstr &SecondMI, const SDep *Dep) {
915 if (isNonDataDep(Dep))
916 return false;
917 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
918 {
919 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
920 if (!llvm::is_contained({RISCV::QC_E_XORAI, RISCV::QC_E_ORAI, RISCV::QC_E_ANDAI, RISCV::QC_E_ADDAI}, MI->getOpcode()))
921 return false;
922 }
923 if (!FirstMI)
924 return true;
925 {
926 [[maybe_unused]] const MachineInstr *MI = FirstMI;
927 if (!(
928 ( MI->getOpcode() == RISCV::ADDI )
929 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
930 ))
931 return false;
932 }
933 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
934 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
935 return false;
936 }
937 {
938 Register FirstDest = FirstMI->getOperand(0).getReg();
939 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
940 return false;
941 }
942 if (!(FirstMI->getOperand(0).isReg() &&
943 SecondMI.getOperand(1).isReg() &&
944 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
945 return false;
946 if (!(FirstMI->getOperand(0).isReg() &&
947 SecondMI.getOperand(0).isReg() &&
948 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(0).getReg()))
949 return false;
950 if (SecondMI.getMF()->getProperties().hasNoVRegs())
951 ++NumTuneMovALUXqciFusionPostRA;
952 else
953 ++NumTuneMovALUXqciFusionPreRA;
954 return true;
955}
956STATISTIC(NumTuneQCELILoadStoreFusionPreRA, "Times TuneQCELILoadStoreFusion Triggered (pre-ra)");
957STATISTIC(NumTuneQCELILoadStoreFusionPostRA, "Times TuneQCELILoadStoreFusion Triggered (post-ra)");
958bool isTuneQCELILoadStoreFusion(
959 const TargetInstrInfo &TII,
960 const TargetSubtargetInfo &STI,
961 const MachineInstr *FirstMI,
962 const MachineInstr &SecondMI, const SDep *Dep) {
963 if (isNonDataDep(Dep))
964 return false;
965 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
966 {
967 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
968 if (!llvm::is_contained({RISCV::LB, RISCV::LBU, RISCV::LH, RISCV::LHU, RISCV::LW, RISCV::SB, RISCV::SH, RISCV::SW}, MI->getOpcode()))
969 return false;
970 }
971 if (!FirstMI)
972 return true;
973 {
974 [[maybe_unused]] const MachineInstr *MI = FirstMI;
975 if (( MI->getOpcode() != RISCV::QC_E_LI ))
976 return false;
977 }
978 {
979 Register FirstDest = FirstMI->getOperand(0).getReg();
980 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
981 return false;
982 }
983 if (!(FirstMI->getOperand(0).isReg() &&
984 SecondMI.getOperand(1).isReg() &&
985 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
986 return false;
987 if (SecondMI.getMF()->getProperties().hasNoVRegs())
988 ++NumTuneQCELILoadStoreFusionPostRA;
989 else
990 ++NumTuneQCELILoadStoreFusionPreRA;
991 return true;
992}
993STATISTIC(NumTuneSHXADDLoadFusionPreRA, "Times TuneSHXADDLoadFusion Triggered (pre-ra)");
994STATISTIC(NumTuneSHXADDLoadFusionPostRA, "Times TuneSHXADDLoadFusion Triggered (post-ra)");
995bool isTuneSHXADDLoadFusion(
996 const TargetInstrInfo &TII,
997 const TargetSubtargetInfo &STI,
998 const MachineInstr *FirstMI,
999 const MachineInstr &SecondMI, const SDep *Dep) {
1000 if (isNonDataDep(Dep))
1001 return false;
1002 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
1003 {
1004 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
1005 if (!llvm::is_contained({RISCV::LB, RISCV::LH, RISCV::LW, RISCV::LD, RISCV::LBU, RISCV::LHU, RISCV::LWU}, MI->getOpcode()))
1006 return false;
1007 }
1008 if (!FirstMI)
1009 return true;
1010 {
1011 [[maybe_unused]] const MachineInstr *MI = FirstMI;
1012 if (!llvm::is_contained({RISCV::SH1ADD, RISCV::SH2ADD, RISCV::SH3ADD, RISCV::SH1ADD_UW, RISCV::SH2ADD_UW, RISCV::SH3ADD_UW}, MI->getOpcode()))
1013 return false;
1014 }
1015 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
1016 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
1017 return false;
1018 }
1019 {
1020 Register FirstDest = FirstMI->getOperand(0).getReg();
1021 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
1022 return false;
1023 }
1024 if (!(FirstMI->getOperand(0).isReg() &&
1025 SecondMI.getOperand(1).isReg() &&
1026 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
1027 return false;
1028 if (SecondMI.getMF()->getProperties().hasNoVRegs())
1029 ++NumTuneSHXADDLoadFusionPostRA;
1030 else
1031 ++NumTuneSHXADDLoadFusionPreRA;
1032 return true;
1033}
1034STATISTIC(NumTuneShiftedZExtWFusionPreRA, "Times TuneShiftedZExtWFusion Triggered (pre-ra)");
1035STATISTIC(NumTuneShiftedZExtWFusionPostRA, "Times TuneShiftedZExtWFusion Triggered (post-ra)");
1036bool isTuneShiftedZExtWFusion(
1037 const TargetInstrInfo &TII,
1038 const TargetSubtargetInfo &STI,
1039 const MachineInstr *FirstMI,
1040 const MachineInstr &SecondMI, const SDep *Dep) {
1041 if (isNonDataDep(Dep))
1042 return false;
1043 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
1044 {
1045 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
1046 if (!(
1047 ( MI->getOpcode() == RISCV::SRLI )
1048 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() >= 0 && MI->getOperand(2).getImm() <= 31)
1049 ))
1050 return false;
1051 }
1052 if (!FirstMI)
1053 return true;
1054 {
1055 [[maybe_unused]] const MachineInstr *MI = FirstMI;
1056 if (!(
1057 ( MI->getOpcode() == RISCV::SLLI )
1058 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 32)
1059 ))
1060 return false;
1061 }
1062 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
1063 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
1064 return false;
1065 }
1066 {
1067 Register FirstDest = FirstMI->getOperand(0).getReg();
1068 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
1069 return false;
1070 }
1071 if (!(FirstMI->getOperand(0).isReg() &&
1072 SecondMI.getOperand(1).isReg() &&
1073 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
1074 return false;
1075 if (SecondMI.getMF()->getProperties().hasNoVRegs())
1076 ++NumTuneShiftedZExtWFusionPostRA;
1077 else
1078 ++NumTuneShiftedZExtWFusionPreRA;
1079 return true;
1080}
1081STATISTIC(NumTuneZExtHFusionPreRA, "Times TuneZExtHFusion Triggered (pre-ra)");
1082STATISTIC(NumTuneZExtHFusionPostRA, "Times TuneZExtHFusion Triggered (post-ra)");
1083bool isTuneZExtHFusion(
1084 const TargetInstrInfo &TII,
1085 const TargetSubtargetInfo &STI,
1086 const MachineInstr *FirstMI,
1087 const MachineInstr &SecondMI, const SDep *Dep) {
1088 if (isNonDataDep(Dep))
1089 return false;
1090 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
1091 {
1092 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
1093 if (!(
1094 ( MI->getOpcode() == RISCV::SRLI )
1095 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 48)
1096 ))
1097 return false;
1098 }
1099 if (!FirstMI)
1100 return true;
1101 {
1102 [[maybe_unused]] const MachineInstr *MI = FirstMI;
1103 if (!(
1104 ( MI->getOpcode() == RISCV::SLLI )
1105 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 48)
1106 ))
1107 return false;
1108 }
1109 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
1110 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
1111 return false;
1112 }
1113 {
1114 Register FirstDest = FirstMI->getOperand(0).getReg();
1115 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
1116 return false;
1117 }
1118 if (!(FirstMI->getOperand(0).isReg() &&
1119 SecondMI.getOperand(1).isReg() &&
1120 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
1121 return false;
1122 if (SecondMI.getMF()->getProperties().hasNoVRegs())
1123 ++NumTuneZExtHFusionPostRA;
1124 else
1125 ++NumTuneZExtHFusionPreRA;
1126 return true;
1127}
1128STATISTIC(NumTuneZExtWFusionPreRA, "Times TuneZExtWFusion Triggered (pre-ra)");
1129STATISTIC(NumTuneZExtWFusionPostRA, "Times TuneZExtWFusion Triggered (post-ra)");
1130bool isTuneZExtWFusion(
1131 const TargetInstrInfo &TII,
1132 const TargetSubtargetInfo &STI,
1133 const MachineInstr *FirstMI,
1134 const MachineInstr &SecondMI, const SDep *Dep) {
1135 if (isNonDataDep(Dep))
1136 return false;
1137 [[maybe_unused]] auto &MRI = SecondMI.getMF()->getRegInfo();
1138 {
1139 [[maybe_unused]] const MachineInstr *MI = &SecondMI;
1140 if (!(
1141 ( MI->getOpcode() == RISCV::SRLI )
1142 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 32)
1143 ))
1144 return false;
1145 }
1146 if (!FirstMI)
1147 return true;
1148 {
1149 [[maybe_unused]] const MachineInstr *MI = FirstMI;
1150 if (!(
1151 ( MI->getOpcode() == RISCV::SLLI )
1152 && (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 32)
1153 ))
1154 return false;
1155 }
1156 if (!SecondMI.getOperand(0).getReg().isVirtual()) {
1157 if (SecondMI.getOperand(0).getReg() != SecondMI.getOperand(1).getReg())
1158 return false;
1159 }
1160 {
1161 Register FirstDest = FirstMI->getOperand(0).getReg();
1162 if (FirstDest.isVirtual() && !MRI.hasOneNonDBGUse(FirstDest))
1163 return false;
1164 }
1165 if (!(FirstMI->getOperand(0).isReg() &&
1166 SecondMI.getOperand(1).isReg() &&
1167 FirstMI->getOperand(0).getReg() == SecondMI.getOperand(1).getReg()))
1168 return false;
1169 if (SecondMI.getMF()->getProperties().hasNoVRegs())
1170 ++NumTuneZExtWFusionPostRA;
1171 else
1172 ++NumTuneZExtWFusionPreRA;
1173 return true;
1174}
1175
1176} // namespace llvm
1177
1178#endif // GET_RISCV_MACRO_FUSION_PRED_IMPL
1179
1180