LLVM 20.0.0git
RISCVVLOptimizer.cpp
Go to the documentation of this file.
1//===-------------- RISCVVLOptimizer.cpp - VL Optimizer -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===---------------------------------------------------------------------===//
8//
9// This pass reduces the VL where possible at the MI level, before VSETVLI
10// instructions are inserted.
11//
12// The purpose of this optimization is to make the VL argument, for instructions
13// that have a VL argument, as small as possible. This is implemented by
14// visiting each instruction in reverse order and checking that if it has a VL
15// argument, whether the VL can be reduced.
16//
17//===---------------------------------------------------------------------===//
18
19#include "RISCV.h"
20#include "RISCVSubtarget.h"
21#include "llvm/ADT/SetVector.h"
25
26using namespace llvm;
27
28#define DEBUG_TYPE "riscv-vl-optimizer"
29#define PASS_NAME "RISC-V VL Optimizer"
30
31namespace {
32
33class RISCVVLOptimizer : public MachineFunctionPass {
35 const MachineDominatorTree *MDT;
36
37public:
38 static char ID;
39
40 RISCVVLOptimizer() : MachineFunctionPass(ID) {}
41
42 bool runOnMachineFunction(MachineFunction &MF) override;
43
44 void getAnalysisUsage(AnalysisUsage &AU) const override {
45 AU.setPreservesCFG();
48 }
49
50 StringRef getPassName() const override { return PASS_NAME; }
51
52private:
53 bool checkUsers(const MachineOperand *&CommonVL, MachineInstr &MI);
54 bool tryReduceVL(MachineInstr &MI);
55 bool isCandidate(const MachineInstr &MI) const;
56};
57
58} // end anonymous namespace
59
60char RISCVVLOptimizer::ID = 0;
61INITIALIZE_PASS_BEGIN(RISCVVLOptimizer, DEBUG_TYPE, PASS_NAME, false, false)
64
66 return new RISCVVLOptimizer();
67}
68
69/// Return true if R is a physical or virtual vector register, false otherwise.
71 if (R.isPhysical())
72 return RISCV::VRRegClass.contains(R);
73 const TargetRegisterClass *RC = MRI->getRegClass(R);
74 return RISCVRI::isVRegClass(RC->TSFlags);
75}
76
77/// Represents the EMUL and EEW of a MachineOperand.
79 enum class State {
80 Unknown,
81 Known,
82 } S;
83
84 // Represent as 1,2,4,8, ... and fractional indicator. This is because
85 // EMUL can take on values that don't map to RISCVII::VLMUL values exactly.
86 // For example, a mask operand can have an EMUL less than MF8.
87 std::optional<std::pair<unsigned, bool>> EMUL;
88
89 unsigned Log2EEW;
90
92 : S(State::Known), EMUL(RISCVVType::decodeVLMUL(EMUL)), Log2EEW(Log2EEW) {
93 }
94
95 OperandInfo(std::pair<unsigned, bool> EMUL, unsigned Log2EEW)
97
99
100 bool isUnknown() const { return S == State::Unknown; }
101 bool isKnown() const { return S == State::Known; }
102
103 static bool EMULAndEEWAreEqual(const OperandInfo &A, const OperandInfo &B) {
104 assert(A.isKnown() && B.isKnown() && "Both operands must be known");
105
106 return A.Log2EEW == B.Log2EEW && A.EMUL->first == B.EMUL->first &&
107 A.EMUL->second == B.EMUL->second;
108 }
109
110 void print(raw_ostream &OS) const {
111 if (isUnknown()) {
112 OS << "Unknown";
113 return;
114 }
115 assert(EMUL && "Expected EMUL to have value");
116 OS << "EMUL: m";
117 if (EMUL->second)
118 OS << "f";
119 OS << EMUL->first;
120 OS << ", EEW: " << (1 << Log2EEW);
121 }
122};
123
126 OI.print(OS);
127 return OS;
128}
129
130namespace llvm {
131namespace RISCVVType {
132/// Return the RISCVII::VLMUL that is two times VLMul.
133/// Precondition: VLMul is not LMUL_RESERVED or LMUL_8.
135 switch (VLMul) {
149 default:
150 llvm_unreachable("Could not multiply VLMul by 2");
151 }
152}
153
154/// Return EMUL = (EEW / SEW) * LMUL where EEW comes from Log2EEW and LMUL and
155/// SEW are from the TSFlags of MI.
156static std::pair<unsigned, bool>
158 RISCVII::VLMUL MIVLMUL = RISCVII::getLMul(MI.getDesc().TSFlags);
159 auto [MILMUL, MILMULIsFractional] = RISCVVType::decodeVLMUL(MIVLMUL);
160 unsigned MILog2SEW =
161 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
162
163 // Mask instructions will have 0 as the SEW operand. But the LMUL of these
164 // instructions is calculated is as if the SEW operand was 3 (e8).
165 if (MILog2SEW == 0)
166 MILog2SEW = 3;
167
168 unsigned MISEW = 1 << MILog2SEW;
169
170 unsigned EEW = 1 << Log2EEW;
171 // Calculate (EEW/SEW)*LMUL preserving fractions less than 1. Use GCD
172 // to put fraction in simplest form.
173 unsigned Num = EEW, Denom = MISEW;
174 int GCD = MILMULIsFractional ? std::gcd(Num, Denom * MILMUL)
175 : std::gcd(Num * MILMUL, Denom);
176 Num = MILMULIsFractional ? Num / GCD : Num * MILMUL / GCD;
177 Denom = MILMULIsFractional ? Denom * MILMUL / GCD : Denom / GCD;
178 return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
179}
180} // end namespace RISCVVType
181} // end namespace llvm
182
183/// Dest has EEW=SEW and EMUL=LMUL. Source EEW=SEW/Factor (i.e. F2 => EEW/2).
184/// Source has EMUL=(EEW/SEW)*LMUL. LMUL and SEW comes from TSFlags of MI.
186 const MachineInstr &MI,
187 const MachineOperand &MO) {
188 RISCVII::VLMUL MIVLMul = RISCVII::getLMul(MI.getDesc().TSFlags);
189 unsigned MILog2SEW =
190 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
191
192 if (MO.getOperandNo() == 0)
193 return OperandInfo(MIVLMul, MILog2SEW);
194
195 unsigned MISEW = 1 << MILog2SEW;
196 unsigned EEW = MISEW / Factor;
197 unsigned Log2EEW = Log2_32(EEW);
198
200 Log2EEW);
201}
202
203/// Check whether MO is a mask operand of MI.
204static bool isMaskOperand(const MachineInstr &MI, const MachineOperand &MO,
205 const MachineRegisterInfo *MRI) {
206
207 if (!MO.isReg() || !isVectorRegClass(MO.getReg(), MRI))
208 return false;
209
210 const MCInstrDesc &Desc = MI.getDesc();
211 return Desc.operands()[MO.getOperandNo()].RegClass == RISCV::VMV0RegClassID;
212}
213
214/// Return the OperandInfo for MO.
216 const MachineRegisterInfo *MRI) {
217 const MachineInstr &MI = *MO.getParent();
219 RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
220 assert(RVV && "Could not find MI in PseudoTable");
221
222 // MI has a VLMUL and SEW associated with it. The RVV specification defines
223 // the LMUL and SEW of each operand and definition in relation to MI.VLMUL and
224 // MI.SEW.
225 RISCVII::VLMUL MIVLMul = RISCVII::getLMul(MI.getDesc().TSFlags);
226 unsigned MILog2SEW =
227 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
228
229 const bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(MI.getDesc());
230
231 // We bail out early for instructions that have passthru with non NoRegister,
232 // which means they are using TU policy. We are not interested in these
233 // since they must preserve the entire register content.
234 if (HasPassthru && MO.getOperandNo() == MI.getNumExplicitDefs() &&
235 (MO.getReg() != RISCV::NoRegister))
236 return {};
237
238 bool IsMODef = MO.getOperandNo() == 0;
239
240 // All mask operands have EEW=1, EMUL=(EEW/SEW)*LMUL
241 if (isMaskOperand(MI, MO, MRI))
243
244 // switch against BaseInstr to reduce number of cases that need to be
245 // considered.
246 switch (RVV->BaseInstr) {
247
248 // 6. Configuration-Setting Instructions
249 // Configuration setting instructions do not read or write vector registers
250 case RISCV::VSETIVLI:
251 case RISCV::VSETVL:
252 case RISCV::VSETVLI:
253 llvm_unreachable("Configuration setting instructions do not read or write "
254 "vector registers");
255
256 // Vector Loads and Stores
257 // Vector Unit-Stride Instructions
258 // Vector Strided Instructions
259 /// Dest EEW encoded in the instruction and EMUL=(EEW/SEW)*LMUL
260 case RISCV::VSE8_V:
261 case RISCV::VSSE8_V:
263 case RISCV::VSE16_V:
264 case RISCV::VSSE16_V:
266 case RISCV::VSE32_V:
267 case RISCV::VSSE32_V:
269 case RISCV::VSE64_V:
270 case RISCV::VSSE64_V:
272
273 // Vector Indexed Instructions
274 // vs(o|u)xei<eew>.v
275 // Dest/Data (operand 0) EEW=SEW, EMUL=LMUL. Source EEW=<eew> and
276 // EMUL=(EEW/SEW)*LMUL.
277 case RISCV::VLUXEI8_V:
278 case RISCV::VLOXEI8_V:
279 case RISCV::VSUXEI8_V:
280 case RISCV::VSOXEI8_V: {
281 if (MO.getOperandNo() == 0)
282 return OperandInfo(MIVLMul, MILog2SEW);
284 }
285 case RISCV::VLUXEI16_V:
286 case RISCV::VLOXEI16_V:
287 case RISCV::VSUXEI16_V:
288 case RISCV::VSOXEI16_V: {
289 if (MO.getOperandNo() == 0)
290 return OperandInfo(MIVLMul, MILog2SEW);
292 }
293 case RISCV::VLUXEI32_V:
294 case RISCV::VLOXEI32_V:
295 case RISCV::VSUXEI32_V:
296 case RISCV::VSOXEI32_V: {
297 if (MO.getOperandNo() == 0)
298 return OperandInfo(MIVLMul, MILog2SEW);
300 }
301 case RISCV::VLUXEI64_V:
302 case RISCV::VLOXEI64_V:
303 case RISCV::VSUXEI64_V:
304 case RISCV::VSOXEI64_V: {
305 if (MO.getOperandNo() == 0)
306 return OperandInfo(MIVLMul, MILog2SEW);
308 }
309
310 // Vector Integer Arithmetic Instructions
311 // Vector Single-Width Integer Add and Subtract
312 case RISCV::VADD_VI:
313 case RISCV::VADD_VV:
314 case RISCV::VADD_VX:
315 case RISCV::VSUB_VV:
316 case RISCV::VSUB_VX:
317 case RISCV::VRSUB_VI:
318 case RISCV::VRSUB_VX:
319 // Vector Bitwise Logical Instructions
320 // Vector Single-Width Shift Instructions
321 // EEW=SEW. EMUL=LMUL.
322 case RISCV::VAND_VI:
323 case RISCV::VAND_VV:
324 case RISCV::VAND_VX:
325 case RISCV::VOR_VI:
326 case RISCV::VOR_VV:
327 case RISCV::VOR_VX:
328 case RISCV::VXOR_VI:
329 case RISCV::VXOR_VV:
330 case RISCV::VXOR_VX:
331 case RISCV::VSLL_VI:
332 case RISCV::VSLL_VV:
333 case RISCV::VSLL_VX:
334 case RISCV::VSRL_VI:
335 case RISCV::VSRL_VV:
336 case RISCV::VSRL_VX:
337 case RISCV::VSRA_VI:
338 case RISCV::VSRA_VV:
339 case RISCV::VSRA_VX:
340 // Vector Integer Min/Max Instructions
341 // EEW=SEW. EMUL=LMUL.
342 case RISCV::VMINU_VV:
343 case RISCV::VMINU_VX:
344 case RISCV::VMIN_VV:
345 case RISCV::VMIN_VX:
346 case RISCV::VMAXU_VV:
347 case RISCV::VMAXU_VX:
348 case RISCV::VMAX_VV:
349 case RISCV::VMAX_VX:
350 // Vector Single-Width Integer Multiply Instructions
351 // Source and Dest EEW=SEW and EMUL=LMUL.
352 case RISCV::VMUL_VV:
353 case RISCV::VMUL_VX:
354 case RISCV::VMULH_VV:
355 case RISCV::VMULH_VX:
356 case RISCV::VMULHU_VV:
357 case RISCV::VMULHU_VX:
358 case RISCV::VMULHSU_VV:
359 case RISCV::VMULHSU_VX:
360 // Vector Integer Divide Instructions
361 // EEW=SEW. EMUL=LMUL.
362 case RISCV::VDIVU_VV:
363 case RISCV::VDIVU_VX:
364 case RISCV::VDIV_VV:
365 case RISCV::VDIV_VX:
366 case RISCV::VREMU_VV:
367 case RISCV::VREMU_VX:
368 case RISCV::VREM_VV:
369 case RISCV::VREM_VX:
370 // Vector Single-Width Integer Multiply-Add Instructions
371 // EEW=SEW. EMUL=LMUL.
372 case RISCV::VMACC_VV:
373 case RISCV::VMACC_VX:
374 case RISCV::VNMSAC_VV:
375 case RISCV::VNMSAC_VX:
376 case RISCV::VMADD_VV:
377 case RISCV::VMADD_VX:
378 case RISCV::VNMSUB_VV:
379 case RISCV::VNMSUB_VX:
380 // Vector Integer Merge Instructions
381 // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
382 // EEW=SEW and EMUL=LMUL, except the mask operand has EEW=1 and EMUL=
383 // (EEW/SEW)*LMUL. Mask operand is handled before this switch.
384 case RISCV::VMERGE_VIM:
385 case RISCV::VMERGE_VVM:
386 case RISCV::VMERGE_VXM:
387 case RISCV::VADC_VIM:
388 case RISCV::VADC_VVM:
389 case RISCV::VADC_VXM:
390 case RISCV::VSBC_VVM:
391 case RISCV::VSBC_VXM:
392 // Vector Integer Move Instructions
393 // Vector Fixed-Point Arithmetic Instructions
394 // Vector Single-Width Saturating Add and Subtract
395 // Vector Single-Width Averaging Add and Subtract
396 // EEW=SEW. EMUL=LMUL.
397 case RISCV::VMV_V_I:
398 case RISCV::VMV_V_V:
399 case RISCV::VMV_V_X:
400 case RISCV::VSADDU_VI:
401 case RISCV::VSADDU_VV:
402 case RISCV::VSADDU_VX:
403 case RISCV::VSADD_VI:
404 case RISCV::VSADD_VV:
405 case RISCV::VSADD_VX:
406 case RISCV::VSSUBU_VV:
407 case RISCV::VSSUBU_VX:
408 case RISCV::VSSUB_VV:
409 case RISCV::VSSUB_VX:
410 case RISCV::VAADDU_VV:
411 case RISCV::VAADDU_VX:
412 case RISCV::VAADD_VV:
413 case RISCV::VAADD_VX:
414 case RISCV::VASUBU_VV:
415 case RISCV::VASUBU_VX:
416 case RISCV::VASUB_VV:
417 case RISCV::VASUB_VX:
418 // Vector Single-Width Fractional Multiply with Rounding and Saturation
419 // EEW=SEW. EMUL=LMUL. The instruction produces 2*SEW product internally but
420 // saturates to fit into SEW bits.
421 case RISCV::VSMUL_VV:
422 case RISCV::VSMUL_VX:
423 // Vector Single-Width Scaling Shift Instructions
424 // EEW=SEW. EMUL=LMUL.
425 case RISCV::VSSRL_VI:
426 case RISCV::VSSRL_VV:
427 case RISCV::VSSRL_VX:
428 case RISCV::VSSRA_VI:
429 case RISCV::VSSRA_VV:
430 case RISCV::VSSRA_VX:
431 // Vector Permutation Instructions
432 // Integer Scalar Move Instructions
433 // Floating-Point Scalar Move Instructions
434 // EMUL=LMUL. EEW=SEW.
435 case RISCV::VMV_X_S:
436 case RISCV::VMV_S_X:
437 case RISCV::VFMV_F_S:
438 case RISCV::VFMV_S_F:
439 // Vector Slide Instructions
440 // EMUL=LMUL. EEW=SEW.
441 case RISCV::VSLIDEUP_VI:
442 case RISCV::VSLIDEUP_VX:
443 case RISCV::VSLIDEDOWN_VI:
444 case RISCV::VSLIDEDOWN_VX:
445 case RISCV::VSLIDE1UP_VX:
446 case RISCV::VFSLIDE1UP_VF:
447 case RISCV::VSLIDE1DOWN_VX:
448 case RISCV::VFSLIDE1DOWN_VF:
449 // Vector Register Gather Instructions
450 // EMUL=LMUL. EEW=SEW. For mask operand, EMUL=1 and EEW=1.
451 case RISCV::VRGATHER_VI:
452 case RISCV::VRGATHER_VV:
453 case RISCV::VRGATHER_VX:
454 // Vector Compress Instruction
455 // EMUL=LMUL. EEW=SEW.
456 case RISCV::VCOMPRESS_VM:
457 // Vector Element Index Instruction
458 case RISCV::VID_V:
459 // Vector Single-Width Floating-Point Add/Subtract Instructions
460 case RISCV::VFADD_VF:
461 case RISCV::VFADD_VV:
462 case RISCV::VFSUB_VF:
463 case RISCV::VFSUB_VV:
464 case RISCV::VFRSUB_VF:
465 // Vector Single-Width Floating-Point Multiply/Divide Instructions
466 case RISCV::VFMUL_VF:
467 case RISCV::VFMUL_VV:
468 case RISCV::VFDIV_VF:
469 case RISCV::VFDIV_VV:
470 case RISCV::VFRDIV_VF:
471 // Vector Floating-Point Square-Root Instruction
472 case RISCV::VFSQRT_V:
473 // Vector Floating-Point Reciprocal Square-Root Estimate Instruction
474 case RISCV::VFRSQRT7_V:
475 // Vector Floating-Point Reciprocal Estimate Instruction
476 case RISCV::VFREC7_V:
477 // Vector Floating-Point MIN/MAX Instructions
478 case RISCV::VFMIN_VF:
479 case RISCV::VFMIN_VV:
480 case RISCV::VFMAX_VF:
481 case RISCV::VFMAX_VV:
482 // Vector Floating-Point Sign-Injection Instructions
483 case RISCV::VFSGNJ_VF:
484 case RISCV::VFSGNJ_VV:
485 case RISCV::VFSGNJN_VV:
486 case RISCV::VFSGNJN_VF:
487 case RISCV::VFSGNJX_VF:
488 case RISCV::VFSGNJX_VV:
489 // Vector Floating-Point Classify Instruction
490 case RISCV::VFCLASS_V:
491 // Vector Floating-Point Move Instruction
492 case RISCV::VFMV_V_F:
493 // Single-Width Floating-Point/Integer Type-Convert Instructions
494 case RISCV::VFCVT_XU_F_V:
495 case RISCV::VFCVT_X_F_V:
496 case RISCV::VFCVT_RTZ_XU_F_V:
497 case RISCV::VFCVT_RTZ_X_F_V:
498 case RISCV::VFCVT_F_XU_V:
499 case RISCV::VFCVT_F_X_V:
500 // Vector Floating-Point Merge Instruction
501 case RISCV::VFMERGE_VFM:
502 return OperandInfo(MIVLMul, MILog2SEW);
503
504 // Vector Widening Integer Add/Subtract
505 // Def uses EEW=2*SEW and EMUL=2*LMUL. Operands use EEW=SEW and EMUL=LMUL.
506 case RISCV::VWADDU_VV:
507 case RISCV::VWADDU_VX:
508 case RISCV::VWSUBU_VV:
509 case RISCV::VWSUBU_VX:
510 case RISCV::VWADD_VV:
511 case RISCV::VWADD_VX:
512 case RISCV::VWSUB_VV:
513 case RISCV::VWSUB_VX:
514 case RISCV::VWSLL_VI:
515 // Vector Widening Integer Multiply Instructions
516 // Source and Destination EMUL=LMUL. Destination EEW=2*SEW. Source EEW=SEW.
517 case RISCV::VWMUL_VV:
518 case RISCV::VWMUL_VX:
519 case RISCV::VWMULSU_VV:
520 case RISCV::VWMULSU_VX:
521 case RISCV::VWMULU_VV:
522 case RISCV::VWMULU_VX:
523 // Vector Widening Integer Multiply-Add Instructions
524 // Destination EEW=2*SEW and EMUL=2*LMUL. Source EEW=SEW and EMUL=LMUL.
525 // A SEW-bit*SEW-bit multiply of the sources forms a 2*SEW-bit value, which
526 // is then added to the 2*SEW-bit Dest. These instructions never have a
527 // passthru operand.
528 case RISCV::VWMACCU_VV:
529 case RISCV::VWMACCU_VX:
530 case RISCV::VWMACC_VV:
531 case RISCV::VWMACC_VX:
532 case RISCV::VWMACCSU_VV:
533 case RISCV::VWMACCSU_VX:
534 case RISCV::VWMACCUS_VX:
535 // Vector Widening Floating-Point Fused Multiply-Add Instructions
536 case RISCV::VFWMACC_VF:
537 case RISCV::VFWMACC_VV:
538 case RISCV::VFWNMACC_VF:
539 case RISCV::VFWNMACC_VV:
540 case RISCV::VFWMSAC_VF:
541 case RISCV::VFWMSAC_VV:
542 case RISCV::VFWNMSAC_VF:
543 case RISCV::VFWNMSAC_VV:
544 // Vector Widening Floating-Point Add/Subtract Instructions
545 // Dest EEW=2*SEW and EMUL=2*LMUL. Source EEW=SEW and EMUL=LMUL.
546 case RISCV::VFWADD_VV:
547 case RISCV::VFWADD_VF:
548 case RISCV::VFWSUB_VV:
549 case RISCV::VFWSUB_VF:
550 // Vector Widening Floating-Point Multiply
551 case RISCV::VFWMUL_VF:
552 case RISCV::VFWMUL_VV:
553 // Widening Floating-Point/Integer Type-Convert Instructions
554 case RISCV::VFWCVT_XU_F_V:
555 case RISCV::VFWCVT_X_F_V:
556 case RISCV::VFWCVT_RTZ_XU_F_V:
557 case RISCV::VFWCVT_RTZ_X_F_V:
558 case RISCV::VFWCVT_F_XU_V:
559 case RISCV::VFWCVT_F_X_V:
560 case RISCV::VFWCVT_F_F_V: {
561 unsigned Log2EEW = IsMODef ? MILog2SEW + 1 : MILog2SEW;
562 RISCVII::VLMUL EMUL =
563 IsMODef ? RISCVVType::twoTimesVLMUL(MIVLMul) : MIVLMul;
564 return OperandInfo(EMUL, Log2EEW);
565 }
566
567 // Def and Op1 uses EEW=2*SEW and EMUL=2*LMUL. Op2 uses EEW=SEW and EMUL=LMUL
568 case RISCV::VWADDU_WV:
569 case RISCV::VWADDU_WX:
570 case RISCV::VWSUBU_WV:
571 case RISCV::VWSUBU_WX:
572 case RISCV::VWADD_WV:
573 case RISCV::VWADD_WX:
574 case RISCV::VWSUB_WV:
575 case RISCV::VWSUB_WX:
576 // Vector Widening Floating-Point Add/Subtract Instructions
577 case RISCV::VFWADD_WF:
578 case RISCV::VFWADD_WV:
579 case RISCV::VFWSUB_WF:
580 case RISCV::VFWSUB_WV: {
581 bool IsOp1 = HasPassthru ? MO.getOperandNo() == 2 : MO.getOperandNo() == 1;
582 bool TwoTimes = IsMODef || IsOp1;
583 unsigned Log2EEW = TwoTimes ? MILog2SEW + 1 : MILog2SEW;
584 RISCVII::VLMUL EMUL =
585 TwoTimes ? RISCVVType::twoTimesVLMUL(MIVLMul) : MIVLMul;
586 return OperandInfo(EMUL, Log2EEW);
587 }
588
589 // Vector Integer Extension
590 case RISCV::VZEXT_VF2:
591 case RISCV::VSEXT_VF2:
592 return getIntegerExtensionOperandInfo(2, MI, MO);
593 case RISCV::VZEXT_VF4:
594 case RISCV::VSEXT_VF4:
595 return getIntegerExtensionOperandInfo(4, MI, MO);
596 case RISCV::VZEXT_VF8:
597 case RISCV::VSEXT_VF8:
598 return getIntegerExtensionOperandInfo(8, MI, MO);
599
600 // Vector Narrowing Integer Right Shift Instructions
601 // Destination EEW=SEW and EMUL=LMUL, Op 1 has EEW=2*SEW EMUL=2*LMUL. Op2 has
602 // EEW=SEW EMUL=LMUL.
603 case RISCV::VNSRL_WX:
604 case RISCV::VNSRL_WI:
605 case RISCV::VNSRL_WV:
606 case RISCV::VNSRA_WI:
607 case RISCV::VNSRA_WV:
608 case RISCV::VNSRA_WX:
609 // Vector Narrowing Fixed-Point Clip Instructions
610 // Destination and Op1 EEW=SEW and EMUL=LMUL. Op2 EEW=2*SEW and EMUL=2*LMUL
611 case RISCV::VNCLIPU_WI:
612 case RISCV::VNCLIPU_WV:
613 case RISCV::VNCLIPU_WX:
614 case RISCV::VNCLIP_WI:
615 case RISCV::VNCLIP_WV:
616 case RISCV::VNCLIP_WX:
617 // Narrowing Floating-Point/Integer Type-Convert Instructions
618 case RISCV::VFNCVT_XU_F_W:
619 case RISCV::VFNCVT_X_F_W:
620 case RISCV::VFNCVT_RTZ_XU_F_W:
621 case RISCV::VFNCVT_RTZ_X_F_W:
622 case RISCV::VFNCVT_F_XU_W:
623 case RISCV::VFNCVT_F_X_W:
624 case RISCV::VFNCVT_F_F_W:
625 case RISCV::VFNCVT_ROD_F_F_W: {
626 bool IsOp1 = HasPassthru ? MO.getOperandNo() == 2 : MO.getOperandNo() == 1;
627 bool TwoTimes = IsOp1;
628 unsigned Log2EEW = TwoTimes ? MILog2SEW + 1 : MILog2SEW;
629 RISCVII::VLMUL EMUL =
630 TwoTimes ? RISCVVType::twoTimesVLMUL(MIVLMul) : MIVLMul;
631 return OperandInfo(EMUL, Log2EEW);
632 }
633
634 // Vector Mask Instructions
635 // Vector Mask-Register Logical Instructions
636 // vmsbf.m set-before-first mask bit
637 // vmsif.m set-including-first mask bit
638 // vmsof.m set-only-first mask bit
639 // EEW=1 and EMUL=(EEW/SEW)*LMUL
640 // We handle the cases when operand is a v0 mask operand above the switch,
641 // but these instructions may use non-v0 mask operands and need to be handled
642 // specifically.
643 case RISCV::VMAND_MM:
644 case RISCV::VMNAND_MM:
645 case RISCV::VMANDN_MM:
646 case RISCV::VMXOR_MM:
647 case RISCV::VMOR_MM:
648 case RISCV::VMNOR_MM:
649 case RISCV::VMORN_MM:
650 case RISCV::VMXNOR_MM:
651 case RISCV::VMSBF_M:
652 case RISCV::VMSIF_M:
653 case RISCV::VMSOF_M: {
655 }
656
657 // Vector Iota Instruction
658 // EEW=SEW and EMUL=LMUL, except the mask operand has EEW=1 and EMUL=
659 // (EEW/SEW)*LMUL. Mask operand is not handled before this switch.
660 case RISCV::VIOTA_M: {
661 if (IsMODef || MO.getOperandNo() == 1)
662 return OperandInfo(MIVLMul, MILog2SEW);
664 }
665
666 // Vector Integer Compare Instructions
667 // Dest EEW=1 and EMUL=(EEW/SEW)*LMUL. Source EEW=SEW and EMUL=LMUL.
668 case RISCV::VMSEQ_VI:
669 case RISCV::VMSEQ_VV:
670 case RISCV::VMSEQ_VX:
671 case RISCV::VMSNE_VI:
672 case RISCV::VMSNE_VV:
673 case RISCV::VMSNE_VX:
674 case RISCV::VMSLTU_VV:
675 case RISCV::VMSLTU_VX:
676 case RISCV::VMSLT_VV:
677 case RISCV::VMSLT_VX:
678 case RISCV::VMSLEU_VV:
679 case RISCV::VMSLEU_VI:
680 case RISCV::VMSLEU_VX:
681 case RISCV::VMSLE_VV:
682 case RISCV::VMSLE_VI:
683 case RISCV::VMSLE_VX:
684 case RISCV::VMSGTU_VI:
685 case RISCV::VMSGTU_VX:
686 case RISCV::VMSGT_VI:
687 case RISCV::VMSGT_VX:
688 // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
689 // Dest EEW=1 and EMUL=(EEW/SEW)*LMUL. Source EEW=SEW and EMUL=LMUL. Mask
690 // source operand handled above this switch.
691 case RISCV::VMADC_VIM:
692 case RISCV::VMADC_VVM:
693 case RISCV::VMADC_VXM:
694 case RISCV::VMSBC_VVM:
695 case RISCV::VMSBC_VXM:
696 // Dest EEW=1 and EMUL=(EEW/SEW)*LMUL. Source EEW=SEW and EMUL=LMUL.
697 case RISCV::VMADC_VV:
698 case RISCV::VMADC_VI:
699 case RISCV::VMADC_VX:
700 case RISCV::VMSBC_VV:
701 case RISCV::VMSBC_VX:
702 // 13.13. Vector Floating-Point Compare Instructions
703 // Dest EEW=1 and EMUL=(EEW/SEW)*LMUL. Source EEW=SEW EMUL=LMUL.
704 case RISCV::VMFEQ_VF:
705 case RISCV::VMFEQ_VV:
706 case RISCV::VMFNE_VF:
707 case RISCV::VMFNE_VV:
708 case RISCV::VMFLT_VF:
709 case RISCV::VMFLT_VV:
710 case RISCV::VMFLE_VF:
711 case RISCV::VMFLE_VV:
712 case RISCV::VMFGT_VF:
713 case RISCV::VMFGE_VF: {
714 if (IsMODef)
716 return OperandInfo(MIVLMul, MILog2SEW);
717 }
718
719 default:
720 return {};
721 }
722}
723
724/// Return true if this optimization should consider MI for VL reduction. This
725/// white-list approach simplifies this optimization for instructions that may
726/// have more complex semantics with relation to how it uses VL.
727static bool isSupportedInstr(const MachineInstr &MI) {
729 RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
730
731 if (!RVV)
732 return false;
733
734 switch (RVV->BaseInstr) {
735 // Vector Single-Width Integer Add and Subtract
736 case RISCV::VADD_VI:
737 case RISCV::VADD_VV:
738 case RISCV::VADD_VX:
739 case RISCV::VSUB_VV:
740 case RISCV::VSUB_VX:
741 case RISCV::VRSUB_VI:
742 case RISCV::VRSUB_VX:
743 // Vector Bitwise Logical Instructions
744 // Vector Single-Width Shift Instructions
745 case RISCV::VAND_VI:
746 case RISCV::VAND_VV:
747 case RISCV::VAND_VX:
748 case RISCV::VOR_VI:
749 case RISCV::VOR_VV:
750 case RISCV::VOR_VX:
751 case RISCV::VXOR_VI:
752 case RISCV::VXOR_VV:
753 case RISCV::VXOR_VX:
754 case RISCV::VSLL_VI:
755 case RISCV::VSLL_VV:
756 case RISCV::VSLL_VX:
757 case RISCV::VSRL_VI:
758 case RISCV::VSRL_VV:
759 case RISCV::VSRL_VX:
760 case RISCV::VSRA_VI:
761 case RISCV::VSRA_VV:
762 case RISCV::VSRA_VX:
763 // Vector Widening Integer Add/Subtract
764 case RISCV::VWADDU_VV:
765 case RISCV::VWADDU_VX:
766 case RISCV::VWSUBU_VV:
767 case RISCV::VWSUBU_VX:
768 case RISCV::VWADD_VV:
769 case RISCV::VWADD_VX:
770 case RISCV::VWSUB_VV:
771 case RISCV::VWSUB_VX:
772 case RISCV::VWADDU_WV:
773 case RISCV::VWADDU_WX:
774 case RISCV::VWSUBU_WV:
775 case RISCV::VWSUBU_WX:
776 case RISCV::VWADD_WV:
777 case RISCV::VWADD_WX:
778 case RISCV::VWSUB_WV:
779 case RISCV::VWSUB_WX:
780 // Vector Integer Extension
781 case RISCV::VZEXT_VF2:
782 case RISCV::VSEXT_VF2:
783 case RISCV::VZEXT_VF4:
784 case RISCV::VSEXT_VF4:
785 case RISCV::VZEXT_VF8:
786 case RISCV::VSEXT_VF8:
787 // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
788 // FIXME: Add support
789 case RISCV::VMADC_VV:
790 case RISCV::VMADC_VI:
791 case RISCV::VMADC_VX:
792 case RISCV::VMSBC_VV:
793 case RISCV::VMSBC_VX:
794 // Vector Narrowing Integer Right Shift Instructions
795 case RISCV::VNSRL_WX:
796 case RISCV::VNSRL_WI:
797 case RISCV::VNSRL_WV:
798 case RISCV::VNSRA_WI:
799 case RISCV::VNSRA_WV:
800 case RISCV::VNSRA_WX:
801 // Vector Integer Compare Instructions
802 case RISCV::VMSEQ_VI:
803 case RISCV::VMSEQ_VV:
804 case RISCV::VMSEQ_VX:
805 case RISCV::VMSNE_VI:
806 case RISCV::VMSNE_VV:
807 case RISCV::VMSNE_VX:
808 case RISCV::VMSLTU_VV:
809 case RISCV::VMSLTU_VX:
810 case RISCV::VMSLT_VV:
811 case RISCV::VMSLT_VX:
812 case RISCV::VMSLEU_VV:
813 case RISCV::VMSLEU_VI:
814 case RISCV::VMSLEU_VX:
815 case RISCV::VMSLE_VV:
816 case RISCV::VMSLE_VI:
817 case RISCV::VMSLE_VX:
818 case RISCV::VMSGTU_VI:
819 case RISCV::VMSGTU_VX:
820 case RISCV::VMSGT_VI:
821 case RISCV::VMSGT_VX:
822 // Vector Integer Min/Max Instructions
823 case RISCV::VMINU_VV:
824 case RISCV::VMINU_VX:
825 case RISCV::VMIN_VV:
826 case RISCV::VMIN_VX:
827 case RISCV::VMAXU_VV:
828 case RISCV::VMAXU_VX:
829 case RISCV::VMAX_VV:
830 case RISCV::VMAX_VX:
831 // Vector Single-Width Integer Multiply Instructions
832 case RISCV::VMUL_VV:
833 case RISCV::VMUL_VX:
834 case RISCV::VMULH_VV:
835 case RISCV::VMULH_VX:
836 case RISCV::VMULHU_VV:
837 case RISCV::VMULHU_VX:
838 case RISCV::VMULHSU_VV:
839 case RISCV::VMULHSU_VX:
840 // Vector Integer Divide Instructions
841 case RISCV::VDIVU_VV:
842 case RISCV::VDIVU_VX:
843 case RISCV::VDIV_VV:
844 case RISCV::VDIV_VX:
845 case RISCV::VREMU_VV:
846 case RISCV::VREMU_VX:
847 case RISCV::VREM_VV:
848 case RISCV::VREM_VX:
849 // Vector Widening Integer Multiply Instructions
850 case RISCV::VWMUL_VV:
851 case RISCV::VWMUL_VX:
852 case RISCV::VWMULSU_VV:
853 case RISCV::VWMULSU_VX:
854 case RISCV::VWMULU_VV:
855 case RISCV::VWMULU_VX:
856 // Vector Single-Width Integer Multiply-Add Instructions
857 case RISCV::VMACC_VV:
858 case RISCV::VMACC_VX:
859 case RISCV::VNMSAC_VV:
860 case RISCV::VNMSAC_VX:
861 case RISCV::VMADD_VV:
862 case RISCV::VMADD_VX:
863 case RISCV::VNMSUB_VV:
864 case RISCV::VNMSUB_VX:
865 // Vector Widening Integer Multiply-Add Instructions
866 case RISCV::VWMACCU_VV:
867 case RISCV::VWMACCU_VX:
868 case RISCV::VWMACC_VV:
869 case RISCV::VWMACC_VX:
870 case RISCV::VWMACCSU_VV:
871 case RISCV::VWMACCSU_VX:
872 case RISCV::VWMACCUS_VX:
873 // Vector Integer Merge Instructions
874 // FIXME: Add support
875 // Vector Integer Move Instructions
876 // FIXME: Add support
877 case RISCV::VMV_V_I:
878 case RISCV::VMV_V_X:
879 case RISCV::VMV_V_V:
880
881 // Vector Crypto
882 case RISCV::VWSLL_VI:
883
884 // Vector Mask Instructions
885 // Vector Mask-Register Logical Instructions
886 // vmsbf.m set-before-first mask bit
887 // vmsif.m set-including-first mask bit
888 // vmsof.m set-only-first mask bit
889 // Vector Iota Instruction
890 // Vector Element Index Instruction
891 case RISCV::VMAND_MM:
892 case RISCV::VMNAND_MM:
893 case RISCV::VMANDN_MM:
894 case RISCV::VMXOR_MM:
895 case RISCV::VMOR_MM:
896 case RISCV::VMNOR_MM:
897 case RISCV::VMORN_MM:
898 case RISCV::VMXNOR_MM:
899 case RISCV::VMSBF_M:
900 case RISCV::VMSIF_M:
901 case RISCV::VMSOF_M:
902 case RISCV::VIOTA_M:
903 case RISCV::VID_V:
904 return true;
905 }
906
907 return false;
908}
909
910/// Return true if MO is a vector operand but is used as a scalar operand.
912 MachineInstr *MI = MO.getParent();
914 RISCVVPseudosTable::getPseudoInfo(MI->getOpcode());
915
916 if (!RVV)
917 return false;
918
919 switch (RVV->BaseInstr) {
920 // Reductions only use vs1[0] of vs1
921 case RISCV::VREDAND_VS:
922 case RISCV::VREDMAX_VS:
923 case RISCV::VREDMAXU_VS:
924 case RISCV::VREDMIN_VS:
925 case RISCV::VREDMINU_VS:
926 case RISCV::VREDOR_VS:
927 case RISCV::VREDSUM_VS:
928 case RISCV::VREDXOR_VS:
929 case RISCV::VWREDSUM_VS:
930 case RISCV::VWREDSUMU_VS:
931 case RISCV::VFREDMAX_VS:
932 case RISCV::VFREDMIN_VS:
933 case RISCV::VFREDOSUM_VS:
934 case RISCV::VFREDUSUM_VS:
935 case RISCV::VFWREDOSUM_VS:
936 case RISCV::VFWREDUSUM_VS:
937 return MO.getOperandNo() == 3;
938 case RISCV::VMV_X_S:
939 case RISCV::VFMV_F_S:
940 return MO.getOperandNo() == 1;
941 default:
942 return false;
943 }
944}
945
946/// Return true if MI may read elements past VL.
947static bool mayReadPastVL(const MachineInstr &MI) {
949 RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
950 if (!RVV)
951 return true;
952
953 switch (RVV->BaseInstr) {
954 // vslidedown instructions may read elements past VL. They are handled
955 // according to current tail policy.
956 case RISCV::VSLIDEDOWN_VI:
957 case RISCV::VSLIDEDOWN_VX:
958 case RISCV::VSLIDE1DOWN_VX:
959 case RISCV::VFSLIDE1DOWN_VF:
960
961 // vrgather instructions may read the source vector at any index < VLMAX,
962 // regardless of VL.
963 case RISCV::VRGATHER_VI:
964 case RISCV::VRGATHER_VV:
965 case RISCV::VRGATHER_VX:
966 case RISCV::VRGATHEREI16_VV:
967 return true;
968
969 default:
970 return false;
971 }
972}
973
974bool RISCVVLOptimizer::isCandidate(const MachineInstr &MI) const {
975 const MCInstrDesc &Desc = MI.getDesc();
976 if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags))
977 return false;
978 if (MI.getNumDefs() != 1)
979 return false;
980
981 // If we're not using VLMAX, then we need to be careful whether we are using
982 // TA/TU when there is a non-undef Passthru. But when we are using VLMAX, it
983 // does not matter whether we are using TA/TU with a non-undef Passthru, since
984 // there are no tail elements to be preserved.
985 unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
986 const MachineOperand &VLOp = MI.getOperand(VLOpNum);
987 if (VLOp.isReg() || VLOp.getImm() != RISCV::VLMaxSentinel) {
988 // If MI has a non-undef passthru, we will not try to optimize it since
989 // that requires us to preserve tail elements according to TA/TU.
990 // Otherwise, The MI has an undef Passthru, so it doesn't matter whether we
991 // are using TA/TU.
992 bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(Desc);
993 unsigned PassthruOpIdx = MI.getNumExplicitDefs();
994 if (HasPassthru &&
995 MI.getOperand(PassthruOpIdx).getReg() != RISCV::NoRegister) {
997 dbgs() << " Not a candidate because it uses non-undef passthru"
998 " with non-VLMAX VL\n");
999 return false;
1000 }
1001 }
1002
1003 // If the VL is 1, then there is no need to reduce it. This is an
1004 // optimization, not needed to preserve correctness.
1005 if (VLOp.isImm() && VLOp.getImm() == 1) {
1006 LLVM_DEBUG(dbgs() << " Not a candidate because VL is already 1\n");
1007 return false;
1008 }
1009
1010 // Some instructions that produce vectors have semantics that make it more
1011 // difficult to determine whether the VL can be reduced. For example, some
1012 // instructions, such as reductions, may write lanes past VL to a scalar
1013 // register. Other instructions, such as some loads or stores, may write
1014 // lower lanes using data from higher lanes. There may be other complex
1015 // semantics not mentioned here that make it hard to determine whether
1016 // the VL can be optimized. As a result, a white-list of supported
1017 // instructions is used. Over time, more instructions can be supported
1018 // upon careful examination of their semantics under the logic in this
1019 // optimization.
1020 // TODO: Use a better approach than a white-list, such as adding
1021 // properties to instructions using something like TSFlags.
1022 if (!isSupportedInstr(MI)) {
1023 LLVM_DEBUG(dbgs() << "Not a candidate due to unsupported instruction\n");
1024 return false;
1025 }
1026
1027 LLVM_DEBUG(dbgs() << "Found a candidate for VL reduction: " << MI << "\n");
1028 return true;
1029}
1030
1031bool RISCVVLOptimizer::checkUsers(const MachineOperand *&CommonVL,
1032 MachineInstr &MI) {
1033 // FIXME: Avoid visiting each user for each time we visit something on the
1034 // worklist, combined with an extra visit from the outer loop. Restructure
1035 // along lines of an instcombine style worklist which integrates the outer
1036 // pass.
1037 bool CanReduceVL = true;
1038 for (auto &UserOp : MRI->use_operands(MI.getOperand(0).getReg())) {
1039 const MachineInstr &UserMI = *UserOp.getParent();
1040 LLVM_DEBUG(dbgs() << " Checking user: " << UserMI << "\n");
1041
1042 // Instructions like reductions may use a vector register as a scalar
1043 // register. In this case, we should treat it like a scalar register which
1044 // does not impact the decision on whether to optimize VL.
1045 // TODO: Treat it like a scalar register instead of bailing out.
1046 if (isVectorOpUsedAsScalarOp(UserOp)) {
1047 CanReduceVL = false;
1048 break;
1049 }
1050
1051 if (mayReadPastVL(UserMI)) {
1052 LLVM_DEBUG(dbgs() << " Abort because used by unsafe instruction\n");
1053 CanReduceVL = false;
1054 break;
1055 }
1056
1057 // Tied operands might pass through.
1058 if (UserOp.isTied()) {
1059 LLVM_DEBUG(dbgs() << " Abort because user used as tied operand\n");
1060 CanReduceVL = false;
1061 break;
1062 }
1063
1064 const MCInstrDesc &Desc = UserMI.getDesc();
1065 if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags)) {
1066 LLVM_DEBUG(dbgs() << " Abort due to lack of VL or SEW, assume that"
1067 " use VLMAX\n");
1068 CanReduceVL = false;
1069 break;
1070 }
1071
1072 unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
1073 const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
1074
1075 // Looking for an immediate or a register VL that isn't X0.
1076 assert((!VLOp.isReg() || VLOp.getReg() != RISCV::X0) &&
1077 "Did not expect X0 VL");
1078
1079 // Use the largest VL among all the users. If we cannot determine this
1080 // statically, then we cannot optimize the VL.
1081 if (!CommonVL || RISCV::isVLKnownLE(*CommonVL, VLOp)) {
1082 CommonVL = &VLOp;
1083 LLVM_DEBUG(dbgs() << " User VL is: " << VLOp << "\n");
1084 } else if (!RISCV::isVLKnownLE(VLOp, *CommonVL)) {
1085 LLVM_DEBUG(dbgs() << " Abort because cannot determine a common VL\n");
1086 CanReduceVL = false;
1087 break;
1088 }
1089
1090 // The SEW and LMUL of destination and source registers need to match.
1091 OperandInfo ConsumerInfo = getOperandInfo(UserOp, MRI);
1092 OperandInfo ProducerInfo = getOperandInfo(MI.getOperand(0), MRI);
1093 if (ConsumerInfo.isUnknown() || ProducerInfo.isUnknown() ||
1094 !OperandInfo::EMULAndEEWAreEqual(ConsumerInfo, ProducerInfo)) {
1095 LLVM_DEBUG(dbgs() << " Abort due to incompatible or unknown "
1096 "information for EMUL or EEW.\n");
1097 LLVM_DEBUG(dbgs() << " ConsumerInfo is: " << ConsumerInfo << "\n");
1098 LLVM_DEBUG(dbgs() << " ProducerInfo is: " << ProducerInfo << "\n");
1099 CanReduceVL = false;
1100 break;
1101 }
1102 }
1103 return CanReduceVL;
1104}
1105
1106bool RISCVVLOptimizer::tryReduceVL(MachineInstr &OrigMI) {
1108 Worklist.insert(&OrigMI);
1109
1110 bool MadeChange = false;
1111 while (!Worklist.empty()) {
1112 MachineInstr &MI = *Worklist.pop_back_val();
1113 LLVM_DEBUG(dbgs() << "Trying to reduce VL for " << MI << "\n");
1114
1115 const MachineOperand *CommonVL = nullptr;
1116 bool CanReduceVL = true;
1117 if (isVectorRegClass(MI.getOperand(0).getReg(), MRI))
1118 CanReduceVL = checkUsers(CommonVL, MI);
1119
1120 if (!CanReduceVL || !CommonVL)
1121 continue;
1122
1123 assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
1124 "Expected VL to be an Imm or virtual Reg");
1125
1126 unsigned VLOpNum = RISCVII::getVLOpNum(MI.getDesc());
1127 MachineOperand &VLOp = MI.getOperand(VLOpNum);
1128
1129 if (!RISCV::isVLKnownLE(*CommonVL, VLOp)) {
1130 LLVM_DEBUG(dbgs() << " Abort due to CommonVL not <= VLOp.\n");
1131 continue;
1132 }
1133
1134 if (CommonVL->isImm()) {
1135 LLVM_DEBUG(dbgs() << " Reduce VL from " << VLOp << " to "
1136 << CommonVL->getImm() << " for " << MI << "\n");
1137 VLOp.ChangeToImmediate(CommonVL->getImm());
1138 } else {
1139 const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
1140 if (!MDT->dominates(VLMI, &MI))
1141 continue;
1142 LLVM_DEBUG(
1143 dbgs() << " Reduce VL from " << VLOp << " to "
1144 << printReg(CommonVL->getReg(), MRI->getTargetRegisterInfo())
1145 << " for " << MI << "\n");
1146
1147 // All our checks passed. We can reduce VL.
1148 VLOp.ChangeToRegister(CommonVL->getReg(), false);
1149 }
1150
1151 MadeChange = true;
1152
1153 // Now add all inputs to this instruction to the worklist.
1154 for (auto &Op : MI.operands()) {
1155 if (!Op.isReg() || !Op.isUse() || !Op.getReg().isVirtual())
1156 continue;
1157
1158 if (!isVectorRegClass(Op.getReg(), MRI))
1159 continue;
1160
1161 MachineInstr *DefMI = MRI->getVRegDef(Op.getReg());
1162
1163 if (!isCandidate(*DefMI))
1164 continue;
1165
1166 Worklist.insert(DefMI);
1167 }
1168 }
1169
1170 return MadeChange;
1171}
1172
1173bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
1174 if (skipFunction(MF.getFunction()))
1175 return false;
1176
1177 MRI = &MF.getRegInfo();
1178 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1179
1181 if (!ST.hasVInstructions())
1182 return false;
1183
1184 bool MadeChange = false;
1185 for (MachineBasicBlock &MBB : MF) {
1186 // Visit instructions in reverse order.
1187 for (auto &MI : make_range(MBB.rbegin(), MBB.rend())) {
1188 if (!isCandidate(MI))
1189 continue;
1190
1191 MadeChange |= tryReduceVL(MI);
1192 }
1193 }
1194
1195 return MadeChange;
1196}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:282
#define LLVM_DEBUG(...)
Definition: Debug.h:106
IRTranslator LLVM IR MI
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
static bool mayReadPastVL(const MachineInstr &MI)
Return true if MI may read elements past VL.
static OperandInfo getOperandInfo(const MachineOperand &MO, const MachineRegisterInfo *MRI)
Return the OperandInfo for MO.
static LLVM_ATTRIBUTE_UNUSED raw_ostream & operator<<(raw_ostream &OS, const OperandInfo &OI)
static bool isVectorOpUsedAsScalarOp(MachineOperand &MO)
Return true if MO is a vector operand but is used as a scalar operand.
static bool isVectorRegClass(Register R, const MachineRegisterInfo *MRI)
Return true if R is a physical or virtual vector register, false otherwise.
static bool isSupportedInstr(const MachineInstr &MI)
Return true if this optimization should consider MI for VL reduction.
#define PASS_NAME
#define DEBUG_TYPE
static OperandInfo getIntegerExtensionOperandInfo(unsigned Factor, const MachineInstr &MI, const MachineOperand &MO)
Dest has EEW=SEW and EMUL=LMUL.
static bool isMaskOperand(const MachineInstr &MI, const MachineOperand &MO, const MachineRegisterInfo *MRI)
Check whether MO is a mask operand of MI.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
#define PASS_NAME
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:256
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
reverse_iterator rend()
reverse_iterator rbegin()
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
Definition: MachineInstr.h:69
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:347
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:572
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
MachineOperand class - Representation of each machine instruction operand.
unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
void ChangeToRegister(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
A vector that has set insertion semantics.
Definition: SetVector.h:57
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:93
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
value_type pop_back_val()
Definition: SetVector.h:285
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
const uint8_t TSFlags
Configurable target specific flags.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static VLMUL getLMul(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
static bool isVRegClass(uint64_t TSFlags)
static std::pair< unsigned, bool > getEMULEqualsEEWDivSEWTimesLMUL(unsigned Log2EEW, const MachineInstr &MI)
Return EMUL = (EEW / SEW) * LMUL where EEW comes from Log2EEW and LMUL and SEW are from the TSFlags o...
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
static RISCVII::VLMUL twoTimesVLMUL(RISCVII::VLMUL VLMul)
Return the RISCVII::VLMUL that is two times VLMul.
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
static constexpr int64_t VLMaxSentinel
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
FunctionPass * createRISCVVLOptimizerPass()
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:340
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Represents the EMUL and EEW of a MachineOperand.
OperandInfo(std::pair< unsigned, bool > EMUL, unsigned Log2EEW)
bool isKnown() const
void print(raw_ostream &OS) const
static bool EMULAndEEWAreEqual(const OperandInfo &A, const OperandInfo &B)
OperandInfo(RISCVII::VLMUL EMUL, unsigned Log2EEW)
bool isUnknown() const
std::optional< std::pair< unsigned, bool > > EMUL
enum OperandInfo::State S
Description of the encoding of one expression Op.