LLVM 22.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"
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 const TargetInstrInfo *TII;
37
38public:
39 static char ID;
40
41 RISCVVLOptimizer() : MachineFunctionPass(ID) {}
42
43 bool runOnMachineFunction(MachineFunction &MF) override;
44
45 void getAnalysisUsage(AnalysisUsage &AU) const override {
46 AU.setPreservesCFG();
49 }
50
51 StringRef getPassName() const override { return PASS_NAME; }
52
53private:
54 std::optional<MachineOperand>
55 getMinimumVLForUser(const MachineOperand &UserOp) const;
56 /// Returns the largest common VL MachineOperand that may be used to optimize
57 /// MI. Returns std::nullopt if it failed to find a suitable VL.
58 std::optional<MachineOperand> checkUsers(const MachineInstr &MI) const;
59 bool tryReduceVL(MachineInstr &MI) const;
60 bool isCandidate(const MachineInstr &MI) const;
61
62 /// For a given instruction, records what elements of it are demanded by
63 /// downstream users.
65};
66
67/// Represents the EMUL and EEW of a MachineOperand.
68struct OperandInfo {
69 // Represent as 1,2,4,8, ... and fractional indicator. This is because
70 // EMUL can take on values that don't map to RISCVVType::VLMUL values exactly.
71 // For example, a mask operand can have an EMUL less than MF8.
72 // If nullopt, then EMUL isn't used (i.e. only a single scalar is read).
73 std::optional<std::pair<unsigned, bool>> EMUL;
74
75 unsigned Log2EEW;
76
77 OperandInfo(RISCVVType::VLMUL EMUL, unsigned Log2EEW)
78 : EMUL(RISCVVType::decodeVLMUL(EMUL)), Log2EEW(Log2EEW) {}
79
80 OperandInfo(std::pair<unsigned, bool> EMUL, unsigned Log2EEW)
81 : EMUL(EMUL), Log2EEW(Log2EEW) {}
82
83 OperandInfo(unsigned Log2EEW) : Log2EEW(Log2EEW) {}
84
85 OperandInfo() = delete;
86
87 /// Return true if the EMUL and EEW produced by \p Def is compatible with the
88 /// EMUL and EEW used by \p User.
89 static bool areCompatible(const OperandInfo &Def, const OperandInfo &User) {
90 if (Def.Log2EEW != User.Log2EEW)
91 return false;
92 if (User.EMUL && Def.EMUL != User.EMUL)
93 return false;
94 return true;
95 }
96
97 void print(raw_ostream &OS) const {
98 if (EMUL) {
99 OS << "EMUL: m";
100 if (EMUL->second)
101 OS << "f";
102 OS << EMUL->first;
103 } else
104 OS << "EMUL: none\n";
105 OS << ", EEW: " << (1 << Log2EEW);
106 }
107};
108
109} // end anonymous namespace
110
111char RISCVVLOptimizer::ID = 0;
112INITIALIZE_PASS_BEGIN(RISCVVLOptimizer, DEBUG_TYPE, PASS_NAME, false, false)
115
117 return new RISCVVLOptimizer();
118}
119
121static raw_ostream &operator<<(raw_ostream &OS, const OperandInfo &OI) {
122 OI.print(OS);
123 return OS;
124}
125
128 const std::optional<OperandInfo> &OI) {
129 if (OI)
130 OI->print(OS);
131 else
132 OS << "nullopt";
133 return OS;
134}
135
136/// Return EMUL = (EEW / SEW) * LMUL where EEW comes from Log2EEW and LMUL and
137/// SEW are from the TSFlags of MI.
138static std::pair<unsigned, bool>
140 RISCVVType::VLMUL MIVLMUL = RISCVII::getLMul(MI.getDesc().TSFlags);
141 auto [MILMUL, MILMULIsFractional] = RISCVVType::decodeVLMUL(MIVLMUL);
142 unsigned MILog2SEW =
143 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
144
145 // Mask instructions will have 0 as the SEW operand. But the LMUL of these
146 // instructions is calculated is as if the SEW operand was 3 (e8).
147 if (MILog2SEW == 0)
148 MILog2SEW = 3;
149
150 unsigned MISEW = 1 << MILog2SEW;
151
152 unsigned EEW = 1 << Log2EEW;
153 // Calculate (EEW/SEW)*LMUL preserving fractions less than 1. Use GCD
154 // to put fraction in simplest form.
155 unsigned Num = EEW, Denom = MISEW;
156 int GCD = MILMULIsFractional ? std::gcd(Num, Denom * MILMUL)
157 : std::gcd(Num * MILMUL, Denom);
158 Num = MILMULIsFractional ? Num / GCD : Num * MILMUL / GCD;
159 Denom = MILMULIsFractional ? Denom * MILMUL / GCD : Denom / GCD;
160 return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
161}
162
163/// Dest has EEW=SEW. Source EEW=SEW/Factor (i.e. F2 => EEW/2).
164/// SEW comes from TSFlags of MI.
165static unsigned getIntegerExtensionOperandEEW(unsigned Factor,
166 const MachineInstr &MI,
167 const MachineOperand &MO) {
168 unsigned MILog2SEW =
169 MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
170
171 if (MO.getOperandNo() == 0)
172 return MILog2SEW;
173
174 unsigned MISEW = 1 << MILog2SEW;
175 unsigned EEW = MISEW / Factor;
176 unsigned Log2EEW = Log2_32(EEW);
177
178 return Log2EEW;
179}
180
181#define VSEG_CASES(Prefix, EEW) \
182 RISCV::Prefix##SEG2E##EEW##_V: \
183 case RISCV::Prefix##SEG3E##EEW##_V: \
184 case RISCV::Prefix##SEG4E##EEW##_V: \
185 case RISCV::Prefix##SEG5E##EEW##_V: \
186 case RISCV::Prefix##SEG6E##EEW##_V: \
187 case RISCV::Prefix##SEG7E##EEW##_V: \
188 case RISCV::Prefix##SEG8E##EEW##_V
189#define VSSEG_CASES(EEW) VSEG_CASES(VS, EEW)
190#define VSSSEG_CASES(EEW) VSEG_CASES(VSS, EEW)
191#define VSUXSEG_CASES(EEW) VSEG_CASES(VSUX, I##EEW)
192#define VSOXSEG_CASES(EEW) VSEG_CASES(VSOX, I##EEW)
193
194static std::optional<unsigned> getOperandLog2EEW(const MachineOperand &MO) {
195 const MachineInstr &MI = *MO.getParent();
196 const MCInstrDesc &Desc = MI.getDesc();
198 RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
199 assert(RVV && "Could not find MI in PseudoTable");
200
201 // MI has a SEW associated with it. The RVV specification defines
202 // the EEW of each operand and definition in relation to MI.SEW.
203 unsigned MILog2SEW = MI.getOperand(RISCVII::getSEWOpNum(Desc)).getImm();
204
205 const bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(Desc);
206 const bool IsTied = RISCVII::isTiedPseudo(Desc.TSFlags);
207
208 bool IsMODef = MO.getOperandNo() == 0 ||
209 (HasPassthru && MO.getOperandNo() == MI.getNumExplicitDefs());
210
211 // All mask operands have EEW=1
212 const MCOperandInfo &Info = Desc.operands()[MO.getOperandNo()];
213 if (Info.OperandType == MCOI::OPERAND_REGISTER &&
214 Info.RegClass == RISCV::VMV0RegClassID)
215 return 0;
216
217 // switch against BaseInstr to reduce number of cases that need to be
218 // considered.
219 switch (RVV->BaseInstr) {
220
221 // 6. Configuration-Setting Instructions
222 // Configuration setting instructions do not read or write vector registers
223 case RISCV::VSETIVLI:
224 case RISCV::VSETVL:
225 case RISCV::VSETVLI:
226 llvm_unreachable("Configuration setting instructions do not read or write "
227 "vector registers");
228
229 // Vector Loads and Stores
230 // Vector Unit-Stride Instructions
231 // Vector Strided Instructions
232 /// Dest EEW encoded in the instruction
233 case RISCV::VLM_V:
234 case RISCV::VSM_V:
235 return 0;
236 case RISCV::VLE8_V:
237 case RISCV::VSE8_V:
238 case RISCV::VLSE8_V:
239 case RISCV::VSSE8_V:
240 case VSSEG_CASES(8):
241 case VSSSEG_CASES(8):
242 return 3;
243 case RISCV::VLE16_V:
244 case RISCV::VSE16_V:
245 case RISCV::VLSE16_V:
246 case RISCV::VSSE16_V:
247 case VSSEG_CASES(16):
248 case VSSSEG_CASES(16):
249 return 4;
250 case RISCV::VLE32_V:
251 case RISCV::VSE32_V:
252 case RISCV::VLSE32_V:
253 case RISCV::VSSE32_V:
254 case VSSEG_CASES(32):
255 case VSSSEG_CASES(32):
256 return 5;
257 case RISCV::VLE64_V:
258 case RISCV::VSE64_V:
259 case RISCV::VLSE64_V:
260 case RISCV::VSSE64_V:
261 case VSSEG_CASES(64):
262 case VSSSEG_CASES(64):
263 return 6;
264
265 // Vector Indexed Instructions
266 // vs(o|u)xei<eew>.v
267 // Dest/Data (operand 0) EEW=SEW. Source EEW=<eew>.
268 case RISCV::VLUXEI8_V:
269 case RISCV::VLOXEI8_V:
270 case RISCV::VSUXEI8_V:
271 case RISCV::VSOXEI8_V:
272 case VSUXSEG_CASES(8):
273 case VSOXSEG_CASES(8): {
274 if (MO.getOperandNo() == 0)
275 return MILog2SEW;
276 return 3;
277 }
278 case RISCV::VLUXEI16_V:
279 case RISCV::VLOXEI16_V:
280 case RISCV::VSUXEI16_V:
281 case RISCV::VSOXEI16_V:
282 case VSUXSEG_CASES(16):
283 case VSOXSEG_CASES(16): {
284 if (MO.getOperandNo() == 0)
285 return MILog2SEW;
286 return 4;
287 }
288 case RISCV::VLUXEI32_V:
289 case RISCV::VLOXEI32_V:
290 case RISCV::VSUXEI32_V:
291 case RISCV::VSOXEI32_V:
292 case VSUXSEG_CASES(32):
293 case VSOXSEG_CASES(32): {
294 if (MO.getOperandNo() == 0)
295 return MILog2SEW;
296 return 5;
297 }
298 case RISCV::VLUXEI64_V:
299 case RISCV::VLOXEI64_V:
300 case RISCV::VSUXEI64_V:
301 case RISCV::VSOXEI64_V:
302 case VSUXSEG_CASES(64):
303 case VSOXSEG_CASES(64): {
304 if (MO.getOperandNo() == 0)
305 return MILog2SEW;
306 return 6;
307 }
308
309 // Vector Integer Arithmetic Instructions
310 // Vector Single-Width Integer Add and Subtract
311 case RISCV::VADD_VI:
312 case RISCV::VADD_VV:
313 case RISCV::VADD_VX:
314 case RISCV::VSUB_VV:
315 case RISCV::VSUB_VX:
316 case RISCV::VRSUB_VI:
317 case RISCV::VRSUB_VX:
318 // Vector Bitwise Logical Instructions
319 // Vector Single-Width Shift Instructions
320 // EEW=SEW.
321 case RISCV::VAND_VI:
322 case RISCV::VAND_VV:
323 case RISCV::VAND_VX:
324 case RISCV::VOR_VI:
325 case RISCV::VOR_VV:
326 case RISCV::VOR_VX:
327 case RISCV::VXOR_VI:
328 case RISCV::VXOR_VV:
329 case RISCV::VXOR_VX:
330 case RISCV::VSLL_VI:
331 case RISCV::VSLL_VV:
332 case RISCV::VSLL_VX:
333 case RISCV::VSRL_VI:
334 case RISCV::VSRL_VV:
335 case RISCV::VSRL_VX:
336 case RISCV::VSRA_VI:
337 case RISCV::VSRA_VV:
338 case RISCV::VSRA_VX:
339 // Vector Integer Min/Max Instructions
340 // EEW=SEW.
341 case RISCV::VMINU_VV:
342 case RISCV::VMINU_VX:
343 case RISCV::VMIN_VV:
344 case RISCV::VMIN_VX:
345 case RISCV::VMAXU_VV:
346 case RISCV::VMAXU_VX:
347 case RISCV::VMAX_VV:
348 case RISCV::VMAX_VX:
349 // Vector Single-Width Integer Multiply Instructions
350 // Source and Dest EEW=SEW.
351 case RISCV::VMUL_VV:
352 case RISCV::VMUL_VX:
353 case RISCV::VMULH_VV:
354 case RISCV::VMULH_VX:
355 case RISCV::VMULHU_VV:
356 case RISCV::VMULHU_VX:
357 case RISCV::VMULHSU_VV:
358 case RISCV::VMULHSU_VX:
359 // Vector Integer Divide Instructions
360 // EEW=SEW.
361 case RISCV::VDIVU_VV:
362 case RISCV::VDIVU_VX:
363 case RISCV::VDIV_VV:
364 case RISCV::VDIV_VX:
365 case RISCV::VREMU_VV:
366 case RISCV::VREMU_VX:
367 case RISCV::VREM_VV:
368 case RISCV::VREM_VX:
369 // Vector Single-Width Integer Multiply-Add Instructions
370 // EEW=SEW.
371 case RISCV::VMACC_VV:
372 case RISCV::VMACC_VX:
373 case RISCV::VNMSAC_VV:
374 case RISCV::VNMSAC_VX:
375 case RISCV::VMADD_VV:
376 case RISCV::VMADD_VX:
377 case RISCV::VNMSUB_VV:
378 case RISCV::VNMSUB_VX:
379 // Vector Integer Merge Instructions
380 // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
381 // EEW=SEW, except the mask operand has EEW=1. Mask operand is handled
382 // before this switch.
383 case RISCV::VMERGE_VIM:
384 case RISCV::VMERGE_VVM:
385 case RISCV::VMERGE_VXM:
386 case RISCV::VADC_VIM:
387 case RISCV::VADC_VVM:
388 case RISCV::VADC_VXM:
389 case RISCV::VSBC_VVM:
390 case RISCV::VSBC_VXM:
391 // Vector Integer Move Instructions
392 // Vector Fixed-Point Arithmetic Instructions
393 // Vector Single-Width Saturating Add and Subtract
394 // Vector Single-Width Averaging Add and Subtract
395 // EEW=SEW.
396 case RISCV::VMV_V_I:
397 case RISCV::VMV_V_V:
398 case RISCV::VMV_V_X:
399 case RISCV::VSADDU_VI:
400 case RISCV::VSADDU_VV:
401 case RISCV::VSADDU_VX:
402 case RISCV::VSADD_VI:
403 case RISCV::VSADD_VV:
404 case RISCV::VSADD_VX:
405 case RISCV::VSSUBU_VV:
406 case RISCV::VSSUBU_VX:
407 case RISCV::VSSUB_VV:
408 case RISCV::VSSUB_VX:
409 case RISCV::VAADDU_VV:
410 case RISCV::VAADDU_VX:
411 case RISCV::VAADD_VV:
412 case RISCV::VAADD_VX:
413 case RISCV::VASUBU_VV:
414 case RISCV::VASUBU_VX:
415 case RISCV::VASUB_VV:
416 case RISCV::VASUB_VX:
417 // Vector Single-Width Fractional Multiply with Rounding and Saturation
418 // EEW=SEW. The instruction produces 2*SEW product internally but
419 // saturates to fit into SEW bits.
420 case RISCV::VSMUL_VV:
421 case RISCV::VSMUL_VX:
422 // Vector Single-Width Scaling Shift Instructions
423 // EEW=SEW.
424 case RISCV::VSSRL_VI:
425 case RISCV::VSSRL_VV:
426 case RISCV::VSSRL_VX:
427 case RISCV::VSSRA_VI:
428 case RISCV::VSSRA_VV:
429 case RISCV::VSSRA_VX:
430 // Vector Permutation Instructions
431 // Integer Scalar Move Instructions
432 // Floating-Point Scalar Move Instructions
433 // EEW=SEW.
434 case RISCV::VMV_X_S:
435 case RISCV::VMV_S_X:
436 case RISCV::VFMV_F_S:
437 case RISCV::VFMV_S_F:
438 // Vector Slide Instructions
439 // EEW=SEW.
440 case RISCV::VSLIDEUP_VI:
441 case RISCV::VSLIDEUP_VX:
442 case RISCV::VSLIDEDOWN_VI:
443 case RISCV::VSLIDEDOWN_VX:
444 case RISCV::VSLIDE1UP_VX:
445 case RISCV::VFSLIDE1UP_VF:
446 case RISCV::VSLIDE1DOWN_VX:
447 case RISCV::VFSLIDE1DOWN_VF:
448 // Vector Register Gather Instructions
449 // EEW=SEW. For mask operand, EEW=1.
450 case RISCV::VRGATHER_VI:
451 case RISCV::VRGATHER_VV:
452 case RISCV::VRGATHER_VX:
453 // Vector Element Index Instruction
454 case RISCV::VID_V:
455 // Vector Single-Width Floating-Point Add/Subtract Instructions
456 case RISCV::VFADD_VF:
457 case RISCV::VFADD_VV:
458 case RISCV::VFSUB_VF:
459 case RISCV::VFSUB_VV:
460 case RISCV::VFRSUB_VF:
461 // Vector Single-Width Floating-Point Multiply/Divide Instructions
462 case RISCV::VFMUL_VF:
463 case RISCV::VFMUL_VV:
464 case RISCV::VFDIV_VF:
465 case RISCV::VFDIV_VV:
466 case RISCV::VFRDIV_VF:
467 // Vector Single-Width Floating-Point Fused Multiply-Add Instructions
468 case RISCV::VFMACC_VV:
469 case RISCV::VFMACC_VF:
470 case RISCV::VFNMACC_VV:
471 case RISCV::VFNMACC_VF:
472 case RISCV::VFMSAC_VV:
473 case RISCV::VFMSAC_VF:
474 case RISCV::VFNMSAC_VV:
475 case RISCV::VFNMSAC_VF:
476 case RISCV::VFMADD_VV:
477 case RISCV::VFMADD_VF:
478 case RISCV::VFNMADD_VV:
479 case RISCV::VFNMADD_VF:
480 case RISCV::VFMSUB_VV:
481 case RISCV::VFMSUB_VF:
482 case RISCV::VFNMSUB_VV:
483 case RISCV::VFNMSUB_VF:
484 // Vector Floating-Point Square-Root Instruction
485 case RISCV::VFSQRT_V:
486 // Vector Floating-Point Reciprocal Square-Root Estimate Instruction
487 case RISCV::VFRSQRT7_V:
488 // Vector Floating-Point Reciprocal Estimate Instruction
489 case RISCV::VFREC7_V:
490 // Vector Floating-Point MIN/MAX Instructions
491 case RISCV::VFMIN_VF:
492 case RISCV::VFMIN_VV:
493 case RISCV::VFMAX_VF:
494 case RISCV::VFMAX_VV:
495 // Vector Floating-Point Sign-Injection Instructions
496 case RISCV::VFSGNJ_VF:
497 case RISCV::VFSGNJ_VV:
498 case RISCV::VFSGNJN_VV:
499 case RISCV::VFSGNJN_VF:
500 case RISCV::VFSGNJX_VF:
501 case RISCV::VFSGNJX_VV:
502 // Vector Floating-Point Classify Instruction
503 case RISCV::VFCLASS_V:
504 // Vector Floating-Point Move Instruction
505 case RISCV::VFMV_V_F:
506 // Single-Width Floating-Point/Integer Type-Convert Instructions
507 case RISCV::VFCVT_XU_F_V:
508 case RISCV::VFCVT_X_F_V:
509 case RISCV::VFCVT_RTZ_XU_F_V:
510 case RISCV::VFCVT_RTZ_X_F_V:
511 case RISCV::VFCVT_F_XU_V:
512 case RISCV::VFCVT_F_X_V:
513 // Vector Floating-Point Merge Instruction
514 case RISCV::VFMERGE_VFM:
515 // Vector count population in mask vcpop.m
516 // vfirst find-first-set mask bit
517 case RISCV::VCPOP_M:
518 case RISCV::VFIRST_M:
519 // Vector Bit-manipulation Instructions (Zvbb)
520 // Vector And-Not
521 case RISCV::VANDN_VV:
522 case RISCV::VANDN_VX:
523 // Vector Reverse Bits in Elements
524 case RISCV::VBREV_V:
525 // Vector Reverse Bits in Bytes
526 case RISCV::VBREV8_V:
527 // Vector Reverse Bytes
528 case RISCV::VREV8_V:
529 // Vector Count Leading Zeros
530 case RISCV::VCLZ_V:
531 // Vector Count Trailing Zeros
532 case RISCV::VCTZ_V:
533 // Vector Population Count
534 case RISCV::VCPOP_V:
535 // Vector Rotate Left
536 case RISCV::VROL_VV:
537 case RISCV::VROL_VX:
538 // Vector Rotate Right
539 case RISCV::VROR_VI:
540 case RISCV::VROR_VV:
541 case RISCV::VROR_VX:
542 // Vector Carry-less Multiplication Instructions (Zvbc)
543 // Vector Carry-less Multiply
544 case RISCV::VCLMUL_VV:
545 case RISCV::VCLMUL_VX:
546 // Vector Carry-less Multiply Return High Half
547 case RISCV::VCLMULH_VV:
548 case RISCV::VCLMULH_VX:
549 return MILog2SEW;
550
551 // Vector Widening Shift Left Logical (Zvbb)
552 case RISCV::VWSLL_VI:
553 case RISCV::VWSLL_VX:
554 case RISCV::VWSLL_VV:
555 // Vector Widening Integer Add/Subtract
556 // Def uses EEW=2*SEW . Operands use EEW=SEW.
557 case RISCV::VWADDU_VV:
558 case RISCV::VWADDU_VX:
559 case RISCV::VWSUBU_VV:
560 case RISCV::VWSUBU_VX:
561 case RISCV::VWADD_VV:
562 case RISCV::VWADD_VX:
563 case RISCV::VWSUB_VV:
564 case RISCV::VWSUB_VX:
565 // Vector Widening Integer Multiply Instructions
566 // Destination EEW=2*SEW. Source EEW=SEW.
567 case RISCV::VWMUL_VV:
568 case RISCV::VWMUL_VX:
569 case RISCV::VWMULSU_VV:
570 case RISCV::VWMULSU_VX:
571 case RISCV::VWMULU_VV:
572 case RISCV::VWMULU_VX:
573 // Vector Widening Integer Multiply-Add Instructions
574 // Destination EEW=2*SEW. Source EEW=SEW.
575 // A SEW-bit*SEW-bit multiply of the sources forms a 2*SEW-bit value, which
576 // is then added to the 2*SEW-bit Dest. These instructions never have a
577 // passthru operand.
578 case RISCV::VWMACCU_VV:
579 case RISCV::VWMACCU_VX:
580 case RISCV::VWMACC_VV:
581 case RISCV::VWMACC_VX:
582 case RISCV::VWMACCSU_VV:
583 case RISCV::VWMACCSU_VX:
584 case RISCV::VWMACCUS_VX:
585 // Vector Widening Floating-Point Fused Multiply-Add Instructions
586 case RISCV::VFWMACC_VF:
587 case RISCV::VFWMACC_VV:
588 case RISCV::VFWNMACC_VF:
589 case RISCV::VFWNMACC_VV:
590 case RISCV::VFWMSAC_VF:
591 case RISCV::VFWMSAC_VV:
592 case RISCV::VFWNMSAC_VF:
593 case RISCV::VFWNMSAC_VV:
594 case RISCV::VFWMACCBF16_VV:
595 case RISCV::VFWMACCBF16_VF:
596 // Vector Widening Floating-Point Add/Subtract Instructions
597 // Dest EEW=2*SEW. Source EEW=SEW.
598 case RISCV::VFWADD_VV:
599 case RISCV::VFWADD_VF:
600 case RISCV::VFWSUB_VV:
601 case RISCV::VFWSUB_VF:
602 // Vector Widening Floating-Point Multiply
603 case RISCV::VFWMUL_VF:
604 case RISCV::VFWMUL_VV:
605 // Widening Floating-Point/Integer Type-Convert Instructions
606 case RISCV::VFWCVT_XU_F_V:
607 case RISCV::VFWCVT_X_F_V:
608 case RISCV::VFWCVT_RTZ_XU_F_V:
609 case RISCV::VFWCVT_RTZ_X_F_V:
610 case RISCV::VFWCVT_F_XU_V:
611 case RISCV::VFWCVT_F_X_V:
612 case RISCV::VFWCVT_F_F_V:
613 case RISCV::VFWCVTBF16_F_F_V:
614 return IsMODef ? MILog2SEW + 1 : MILog2SEW;
615
616 // Def and Op1 uses EEW=2*SEW. Op2 uses EEW=SEW.
617 case RISCV::VWADDU_WV:
618 case RISCV::VWADDU_WX:
619 case RISCV::VWSUBU_WV:
620 case RISCV::VWSUBU_WX:
621 case RISCV::VWADD_WV:
622 case RISCV::VWADD_WX:
623 case RISCV::VWSUB_WV:
624 case RISCV::VWSUB_WX:
625 // Vector Widening Floating-Point Add/Subtract Instructions
626 case RISCV::VFWADD_WF:
627 case RISCV::VFWADD_WV:
628 case RISCV::VFWSUB_WF:
629 case RISCV::VFWSUB_WV: {
630 bool IsOp1 = (HasPassthru && !IsTied) ? MO.getOperandNo() == 2
631 : MO.getOperandNo() == 1;
632 bool TwoTimes = IsMODef || IsOp1;
633 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
634 }
635
636 // Vector Integer Extension
637 case RISCV::VZEXT_VF2:
638 case RISCV::VSEXT_VF2:
639 return getIntegerExtensionOperandEEW(2, MI, MO);
640 case RISCV::VZEXT_VF4:
641 case RISCV::VSEXT_VF4:
642 return getIntegerExtensionOperandEEW(4, MI, MO);
643 case RISCV::VZEXT_VF8:
644 case RISCV::VSEXT_VF8:
645 return getIntegerExtensionOperandEEW(8, MI, MO);
646
647 // Vector Narrowing Integer Right Shift Instructions
648 // Destination EEW=SEW, Op 1 has EEW=2*SEW. Op2 has EEW=SEW
649 case RISCV::VNSRL_WX:
650 case RISCV::VNSRL_WI:
651 case RISCV::VNSRL_WV:
652 case RISCV::VNSRA_WI:
653 case RISCV::VNSRA_WV:
654 case RISCV::VNSRA_WX:
655 // Vector Narrowing Fixed-Point Clip Instructions
656 // Destination and Op1 EEW=SEW. Op2 EEW=2*SEW.
657 case RISCV::VNCLIPU_WI:
658 case RISCV::VNCLIPU_WV:
659 case RISCV::VNCLIPU_WX:
660 case RISCV::VNCLIP_WI:
661 case RISCV::VNCLIP_WV:
662 case RISCV::VNCLIP_WX:
663 // Narrowing Floating-Point/Integer Type-Convert Instructions
664 case RISCV::VFNCVT_XU_F_W:
665 case RISCV::VFNCVT_X_F_W:
666 case RISCV::VFNCVT_RTZ_XU_F_W:
667 case RISCV::VFNCVT_RTZ_X_F_W:
668 case RISCV::VFNCVT_F_XU_W:
669 case RISCV::VFNCVT_F_X_W:
670 case RISCV::VFNCVT_F_F_W:
671 case RISCV::VFNCVT_ROD_F_F_W:
672 case RISCV::VFNCVTBF16_F_F_W: {
673 assert(!IsTied);
674 bool IsOp1 = HasPassthru ? MO.getOperandNo() == 2 : MO.getOperandNo() == 1;
675 bool TwoTimes = IsOp1;
676 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
677 }
678
679 // Vector Mask Instructions
680 // Vector Mask-Register Logical Instructions
681 // vmsbf.m set-before-first mask bit
682 // vmsif.m set-including-first mask bit
683 // vmsof.m set-only-first mask bit
684 // EEW=1
685 // We handle the cases when operand is a v0 mask operand above the switch,
686 // but these instructions may use non-v0 mask operands and need to be handled
687 // specifically.
688 case RISCV::VMAND_MM:
689 case RISCV::VMNAND_MM:
690 case RISCV::VMANDN_MM:
691 case RISCV::VMXOR_MM:
692 case RISCV::VMOR_MM:
693 case RISCV::VMNOR_MM:
694 case RISCV::VMORN_MM:
695 case RISCV::VMXNOR_MM:
696 case RISCV::VMSBF_M:
697 case RISCV::VMSIF_M:
698 case RISCV::VMSOF_M: {
699 return MILog2SEW;
700 }
701
702 // Vector Compress Instruction
703 // EEW=SEW, except the mask operand has EEW=1. Mask operand is not handled
704 // before this switch.
705 case RISCV::VCOMPRESS_VM:
706 return MO.getOperandNo() == 3 ? 0 : MILog2SEW;
707
708 // Vector Iota Instruction
709 // EEW=SEW, except the mask operand has EEW=1. Mask operand is not handled
710 // before this switch.
711 case RISCV::VIOTA_M: {
712 if (IsMODef || MO.getOperandNo() == 1)
713 return MILog2SEW;
714 return 0;
715 }
716
717 // Vector Integer Compare Instructions
718 // Dest EEW=1. Source EEW=SEW.
719 case RISCV::VMSEQ_VI:
720 case RISCV::VMSEQ_VV:
721 case RISCV::VMSEQ_VX:
722 case RISCV::VMSNE_VI:
723 case RISCV::VMSNE_VV:
724 case RISCV::VMSNE_VX:
725 case RISCV::VMSLTU_VV:
726 case RISCV::VMSLTU_VX:
727 case RISCV::VMSLT_VV:
728 case RISCV::VMSLT_VX:
729 case RISCV::VMSLEU_VV:
730 case RISCV::VMSLEU_VI:
731 case RISCV::VMSLEU_VX:
732 case RISCV::VMSLE_VV:
733 case RISCV::VMSLE_VI:
734 case RISCV::VMSLE_VX:
735 case RISCV::VMSGTU_VI:
736 case RISCV::VMSGTU_VX:
737 case RISCV::VMSGT_VI:
738 case RISCV::VMSGT_VX:
739 // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
740 // Dest EEW=1. Source EEW=SEW. Mask source operand handled above this switch.
741 case RISCV::VMADC_VIM:
742 case RISCV::VMADC_VVM:
743 case RISCV::VMADC_VXM:
744 case RISCV::VMSBC_VVM:
745 case RISCV::VMSBC_VXM:
746 // Dest EEW=1. Source EEW=SEW.
747 case RISCV::VMADC_VV:
748 case RISCV::VMADC_VI:
749 case RISCV::VMADC_VX:
750 case RISCV::VMSBC_VV:
751 case RISCV::VMSBC_VX:
752 // 13.13. Vector Floating-Point Compare Instructions
753 // Dest EEW=1. Source EEW=SEW
754 case RISCV::VMFEQ_VF:
755 case RISCV::VMFEQ_VV:
756 case RISCV::VMFNE_VF:
757 case RISCV::VMFNE_VV:
758 case RISCV::VMFLT_VF:
759 case RISCV::VMFLT_VV:
760 case RISCV::VMFLE_VF:
761 case RISCV::VMFLE_VV:
762 case RISCV::VMFGT_VF:
763 case RISCV::VMFGE_VF: {
764 if (IsMODef)
765 return 0;
766 return MILog2SEW;
767 }
768
769 // Vector Reduction Operations
770 // Vector Single-Width Integer Reduction Instructions
771 case RISCV::VREDAND_VS:
772 case RISCV::VREDMAX_VS:
773 case RISCV::VREDMAXU_VS:
774 case RISCV::VREDMIN_VS:
775 case RISCV::VREDMINU_VS:
776 case RISCV::VREDOR_VS:
777 case RISCV::VREDSUM_VS:
778 case RISCV::VREDXOR_VS:
779 // Vector Single-Width Floating-Point Reduction Instructions
780 case RISCV::VFREDMAX_VS:
781 case RISCV::VFREDMIN_VS:
782 case RISCV::VFREDOSUM_VS:
783 case RISCV::VFREDUSUM_VS: {
784 return MILog2SEW;
785 }
786
787 // Vector Widening Integer Reduction Instructions
788 // The Dest and VS1 read only element 0 for the vector register. Return
789 // 2*EEW for these. VS2 has EEW=SEW and EMUL=LMUL.
790 case RISCV::VWREDSUM_VS:
791 case RISCV::VWREDSUMU_VS:
792 // Vector Widening Floating-Point Reduction Instructions
793 case RISCV::VFWREDOSUM_VS:
794 case RISCV::VFWREDUSUM_VS: {
795 bool TwoTimes = IsMODef || MO.getOperandNo() == 3;
796 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
797 }
798
799 // Vector Register Gather with 16-bit Index Elements Instruction
800 // Dest and source data EEW=SEW. Index vector EEW=16.
801 case RISCV::VRGATHEREI16_VV: {
802 if (MO.getOperandNo() == 2)
803 return 4;
804 return MILog2SEW;
805 }
806
807 default:
808 return std::nullopt;
809 }
810}
811
812static std::optional<OperandInfo> getOperandInfo(const MachineOperand &MO) {
813 const MachineInstr &MI = *MO.getParent();
815 RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
816 assert(RVV && "Could not find MI in PseudoTable");
817
818 std::optional<unsigned> Log2EEW = getOperandLog2EEW(MO);
819 if (!Log2EEW)
820 return std::nullopt;
821
822 switch (RVV->BaseInstr) {
823 // Vector Reduction Operations
824 // Vector Single-Width Integer Reduction Instructions
825 // Vector Widening Integer Reduction Instructions
826 // Vector Widening Floating-Point Reduction Instructions
827 // The Dest and VS1 only read element 0 of the vector register. Return just
828 // the EEW for these.
829 case RISCV::VREDAND_VS:
830 case RISCV::VREDMAX_VS:
831 case RISCV::VREDMAXU_VS:
832 case RISCV::VREDMIN_VS:
833 case RISCV::VREDMINU_VS:
834 case RISCV::VREDOR_VS:
835 case RISCV::VREDSUM_VS:
836 case RISCV::VREDXOR_VS:
837 case RISCV::VWREDSUM_VS:
838 case RISCV::VWREDSUMU_VS:
839 case RISCV::VFWREDOSUM_VS:
840 case RISCV::VFWREDUSUM_VS:
841 if (MO.getOperandNo() != 2)
842 return OperandInfo(*Log2EEW);
843 break;
844 };
845
846 // All others have EMUL=EEW/SEW*LMUL
847 return OperandInfo(getEMULEqualsEEWDivSEWTimesLMUL(*Log2EEW, MI), *Log2EEW);
848}
849
850/// Return true if this optimization should consider MI for VL reduction. This
851/// white-list approach simplifies this optimization for instructions that may
852/// have more complex semantics with relation to how it uses VL.
853static bool isSupportedInstr(const MachineInstr &MI) {
855 RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
856
857 if (!RVV)
858 return false;
859
860 switch (RVV->BaseInstr) {
861 // Vector Unit-Stride Instructions
862 // Vector Strided Instructions
863 case RISCV::VLM_V:
864 case RISCV::VLE8_V:
865 case RISCV::VLSE8_V:
866 case RISCV::VLE16_V:
867 case RISCV::VLSE16_V:
868 case RISCV::VLE32_V:
869 case RISCV::VLSE32_V:
870 case RISCV::VLE64_V:
871 case RISCV::VLSE64_V:
872 // Vector Indexed Instructions
873 case RISCV::VLUXEI8_V:
874 case RISCV::VLOXEI8_V:
875 case RISCV::VLUXEI16_V:
876 case RISCV::VLOXEI16_V:
877 case RISCV::VLUXEI32_V:
878 case RISCV::VLOXEI32_V:
879 case RISCV::VLUXEI64_V:
880 case RISCV::VLOXEI64_V:
881 // Vector Single-Width Integer Add and Subtract
882 case RISCV::VADD_VI:
883 case RISCV::VADD_VV:
884 case RISCV::VADD_VX:
885 case RISCV::VSUB_VV:
886 case RISCV::VSUB_VX:
887 case RISCV::VRSUB_VI:
888 case RISCV::VRSUB_VX:
889 // Vector Bitwise Logical Instructions
890 // Vector Single-Width Shift Instructions
891 case RISCV::VAND_VI:
892 case RISCV::VAND_VV:
893 case RISCV::VAND_VX:
894 case RISCV::VOR_VI:
895 case RISCV::VOR_VV:
896 case RISCV::VOR_VX:
897 case RISCV::VXOR_VI:
898 case RISCV::VXOR_VV:
899 case RISCV::VXOR_VX:
900 case RISCV::VSLL_VI:
901 case RISCV::VSLL_VV:
902 case RISCV::VSLL_VX:
903 case RISCV::VSRL_VI:
904 case RISCV::VSRL_VV:
905 case RISCV::VSRL_VX:
906 case RISCV::VSRA_VI:
907 case RISCV::VSRA_VV:
908 case RISCV::VSRA_VX:
909 // Vector Widening Integer Add/Subtract
910 case RISCV::VWADDU_VV:
911 case RISCV::VWADDU_VX:
912 case RISCV::VWSUBU_VV:
913 case RISCV::VWSUBU_VX:
914 case RISCV::VWADD_VV:
915 case RISCV::VWADD_VX:
916 case RISCV::VWSUB_VV:
917 case RISCV::VWSUB_VX:
918 case RISCV::VWADDU_WV:
919 case RISCV::VWADDU_WX:
920 case RISCV::VWSUBU_WV:
921 case RISCV::VWSUBU_WX:
922 case RISCV::VWADD_WV:
923 case RISCV::VWADD_WX:
924 case RISCV::VWSUB_WV:
925 case RISCV::VWSUB_WX:
926 // Vector Integer Extension
927 case RISCV::VZEXT_VF2:
928 case RISCV::VSEXT_VF2:
929 case RISCV::VZEXT_VF4:
930 case RISCV::VSEXT_VF4:
931 case RISCV::VZEXT_VF8:
932 case RISCV::VSEXT_VF8:
933 // Vector Narrowing Integer Right Shift Instructions
934 case RISCV::VNSRL_WX:
935 case RISCV::VNSRL_WI:
936 case RISCV::VNSRL_WV:
937 case RISCV::VNSRA_WI:
938 case RISCV::VNSRA_WV:
939 case RISCV::VNSRA_WX:
940 // Vector Integer Compare Instructions
941 case RISCV::VMSEQ_VI:
942 case RISCV::VMSEQ_VV:
943 case RISCV::VMSEQ_VX:
944 case RISCV::VMSNE_VI:
945 case RISCV::VMSNE_VV:
946 case RISCV::VMSNE_VX:
947 case RISCV::VMSLTU_VV:
948 case RISCV::VMSLTU_VX:
949 case RISCV::VMSLT_VV:
950 case RISCV::VMSLT_VX:
951 case RISCV::VMSLEU_VV:
952 case RISCV::VMSLEU_VI:
953 case RISCV::VMSLEU_VX:
954 case RISCV::VMSLE_VV:
955 case RISCV::VMSLE_VI:
956 case RISCV::VMSLE_VX:
957 case RISCV::VMSGTU_VI:
958 case RISCV::VMSGTU_VX:
959 case RISCV::VMSGT_VI:
960 case RISCV::VMSGT_VX:
961 // Vector Integer Min/Max Instructions
962 case RISCV::VMINU_VV:
963 case RISCV::VMINU_VX:
964 case RISCV::VMIN_VV:
965 case RISCV::VMIN_VX:
966 case RISCV::VMAXU_VV:
967 case RISCV::VMAXU_VX:
968 case RISCV::VMAX_VV:
969 case RISCV::VMAX_VX:
970 // Vector Single-Width Integer Multiply Instructions
971 case RISCV::VMUL_VV:
972 case RISCV::VMUL_VX:
973 case RISCV::VMULH_VV:
974 case RISCV::VMULH_VX:
975 case RISCV::VMULHU_VV:
976 case RISCV::VMULHU_VX:
977 case RISCV::VMULHSU_VV:
978 case RISCV::VMULHSU_VX:
979 // Vector Integer Divide Instructions
980 case RISCV::VDIVU_VV:
981 case RISCV::VDIVU_VX:
982 case RISCV::VDIV_VV:
983 case RISCV::VDIV_VX:
984 case RISCV::VREMU_VV:
985 case RISCV::VREMU_VX:
986 case RISCV::VREM_VV:
987 case RISCV::VREM_VX:
988 // Vector Widening Integer Multiply Instructions
989 case RISCV::VWMUL_VV:
990 case RISCV::VWMUL_VX:
991 case RISCV::VWMULSU_VV:
992 case RISCV::VWMULSU_VX:
993 case RISCV::VWMULU_VV:
994 case RISCV::VWMULU_VX:
995 // Vector Single-Width Integer Multiply-Add Instructions
996 case RISCV::VMACC_VV:
997 case RISCV::VMACC_VX:
998 case RISCV::VNMSAC_VV:
999 case RISCV::VNMSAC_VX:
1000 case RISCV::VMADD_VV:
1001 case RISCV::VMADD_VX:
1002 case RISCV::VNMSUB_VV:
1003 case RISCV::VNMSUB_VX:
1004 // Vector Integer Merge Instructions
1005 case RISCV::VMERGE_VIM:
1006 case RISCV::VMERGE_VVM:
1007 case RISCV::VMERGE_VXM:
1008 // Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
1009 case RISCV::VADC_VIM:
1010 case RISCV::VADC_VVM:
1011 case RISCV::VADC_VXM:
1012 case RISCV::VMADC_VIM:
1013 case RISCV::VMADC_VVM:
1014 case RISCV::VMADC_VXM:
1015 case RISCV::VSBC_VVM:
1016 case RISCV::VSBC_VXM:
1017 case RISCV::VMSBC_VVM:
1018 case RISCV::VMSBC_VXM:
1019 case RISCV::VMADC_VV:
1020 case RISCV::VMADC_VI:
1021 case RISCV::VMADC_VX:
1022 case RISCV::VMSBC_VV:
1023 case RISCV::VMSBC_VX:
1024 // Vector Widening Integer Multiply-Add Instructions
1025 case RISCV::VWMACCU_VV:
1026 case RISCV::VWMACCU_VX:
1027 case RISCV::VWMACC_VV:
1028 case RISCV::VWMACC_VX:
1029 case RISCV::VWMACCSU_VV:
1030 case RISCV::VWMACCSU_VX:
1031 case RISCV::VWMACCUS_VX:
1032 // Vector Integer Move Instructions
1033 case RISCV::VMV_V_I:
1034 case RISCV::VMV_V_X:
1035 case RISCV::VMV_V_V:
1036 // Vector Single-Width Saturating Add and Subtract
1037 case RISCV::VSADDU_VV:
1038 case RISCV::VSADDU_VX:
1039 case RISCV::VSADDU_VI:
1040 case RISCV::VSADD_VV:
1041 case RISCV::VSADD_VX:
1042 case RISCV::VSADD_VI:
1043 case RISCV::VSSUBU_VV:
1044 case RISCV::VSSUBU_VX:
1045 case RISCV::VSSUB_VV:
1046 case RISCV::VSSUB_VX:
1047 // Vector Single-Width Averaging Add and Subtract
1048 case RISCV::VAADDU_VV:
1049 case RISCV::VAADDU_VX:
1050 case RISCV::VAADD_VV:
1051 case RISCV::VAADD_VX:
1052 case RISCV::VASUBU_VV:
1053 case RISCV::VASUBU_VX:
1054 case RISCV::VASUB_VV:
1055 case RISCV::VASUB_VX:
1056 // Vector Single-Width Fractional Multiply with Rounding and Saturation
1057 case RISCV::VSMUL_VV:
1058 case RISCV::VSMUL_VX:
1059 // Vector Single-Width Scaling Shift Instructions
1060 case RISCV::VSSRL_VV:
1061 case RISCV::VSSRL_VX:
1062 case RISCV::VSSRL_VI:
1063 case RISCV::VSSRA_VV:
1064 case RISCV::VSSRA_VX:
1065 case RISCV::VSSRA_VI:
1066 // Vector Narrowing Fixed-Point Clip Instructions
1067 case RISCV::VNCLIPU_WV:
1068 case RISCV::VNCLIPU_WX:
1069 case RISCV::VNCLIPU_WI:
1070 case RISCV::VNCLIP_WV:
1071 case RISCV::VNCLIP_WX:
1072 case RISCV::VNCLIP_WI:
1073 // Vector Bit-manipulation Instructions (Zvbb)
1074 // Vector And-Not
1075 case RISCV::VANDN_VV:
1076 case RISCV::VANDN_VX:
1077 // Vector Reverse Bits in Elements
1078 case RISCV::VBREV_V:
1079 // Vector Reverse Bits in Bytes
1080 case RISCV::VBREV8_V:
1081 // Vector Reverse Bytes
1082 case RISCV::VREV8_V:
1083 // Vector Count Leading Zeros
1084 case RISCV::VCLZ_V:
1085 // Vector Count Trailing Zeros
1086 case RISCV::VCTZ_V:
1087 // Vector Population Count
1088 case RISCV::VCPOP_V:
1089 // Vector Rotate Left
1090 case RISCV::VROL_VV:
1091 case RISCV::VROL_VX:
1092 // Vector Rotate Right
1093 case RISCV::VROR_VI:
1094 case RISCV::VROR_VV:
1095 case RISCV::VROR_VX:
1096 // Vector Widening Shift Left Logical
1097 case RISCV::VWSLL_VI:
1098 case RISCV::VWSLL_VX:
1099 case RISCV::VWSLL_VV:
1100 // Vector Carry-less Multiplication Instructions (Zvbc)
1101 // Vector Carry-less Multiply
1102 case RISCV::VCLMUL_VV:
1103 case RISCV::VCLMUL_VX:
1104 // Vector Carry-less Multiply Return High Half
1105 case RISCV::VCLMULH_VV:
1106 case RISCV::VCLMULH_VX:
1107 // Vector Mask Instructions
1108 // Vector Mask-Register Logical Instructions
1109 // vmsbf.m set-before-first mask bit
1110 // vmsif.m set-including-first mask bit
1111 // vmsof.m set-only-first mask bit
1112 // Vector Iota Instruction
1113 // Vector Element Index Instruction
1114 case RISCV::VMAND_MM:
1115 case RISCV::VMNAND_MM:
1116 case RISCV::VMANDN_MM:
1117 case RISCV::VMXOR_MM:
1118 case RISCV::VMOR_MM:
1119 case RISCV::VMNOR_MM:
1120 case RISCV::VMORN_MM:
1121 case RISCV::VMXNOR_MM:
1122 case RISCV::VMSBF_M:
1123 case RISCV::VMSIF_M:
1124 case RISCV::VMSOF_M:
1125 case RISCV::VIOTA_M:
1126 case RISCV::VID_V:
1127 // Vector Slide Instructions
1128 case RISCV::VSLIDEUP_VX:
1129 case RISCV::VSLIDEUP_VI:
1130 case RISCV::VSLIDEDOWN_VX:
1131 case RISCV::VSLIDEDOWN_VI:
1132 case RISCV::VSLIDE1UP_VX:
1133 case RISCV::VFSLIDE1UP_VF:
1134 // Vector Register Gather Instructions
1135 case RISCV::VRGATHER_VI:
1136 case RISCV::VRGATHER_VV:
1137 case RISCV::VRGATHER_VX:
1138 case RISCV::VRGATHEREI16_VV:
1139 // Vector Single-Width Floating-Point Add/Subtract Instructions
1140 case RISCV::VFADD_VF:
1141 case RISCV::VFADD_VV:
1142 case RISCV::VFSUB_VF:
1143 case RISCV::VFSUB_VV:
1144 case RISCV::VFRSUB_VF:
1145 // Vector Widening Floating-Point Add/Subtract Instructions
1146 case RISCV::VFWADD_VV:
1147 case RISCV::VFWADD_VF:
1148 case RISCV::VFWSUB_VV:
1149 case RISCV::VFWSUB_VF:
1150 case RISCV::VFWADD_WF:
1151 case RISCV::VFWADD_WV:
1152 case RISCV::VFWSUB_WF:
1153 case RISCV::VFWSUB_WV:
1154 // Vector Single-Width Floating-Point Multiply/Divide Instructions
1155 case RISCV::VFMUL_VF:
1156 case RISCV::VFMUL_VV:
1157 case RISCV::VFDIV_VF:
1158 case RISCV::VFDIV_VV:
1159 case RISCV::VFRDIV_VF:
1160 // Vector Widening Floating-Point Multiply
1161 case RISCV::VFWMUL_VF:
1162 case RISCV::VFWMUL_VV:
1163 // Vector Single-Width Floating-Point Fused Multiply-Add Instructions
1164 case RISCV::VFMACC_VV:
1165 case RISCV::VFMACC_VF:
1166 case RISCV::VFNMACC_VV:
1167 case RISCV::VFNMACC_VF:
1168 case RISCV::VFMSAC_VV:
1169 case RISCV::VFMSAC_VF:
1170 case RISCV::VFNMSAC_VV:
1171 case RISCV::VFNMSAC_VF:
1172 case RISCV::VFMADD_VV:
1173 case RISCV::VFMADD_VF:
1174 case RISCV::VFNMADD_VV:
1175 case RISCV::VFNMADD_VF:
1176 case RISCV::VFMSUB_VV:
1177 case RISCV::VFMSUB_VF:
1178 case RISCV::VFNMSUB_VV:
1179 case RISCV::VFNMSUB_VF:
1180 // Vector Widening Floating-Point Fused Multiply-Add Instructions
1181 case RISCV::VFWMACC_VV:
1182 case RISCV::VFWMACC_VF:
1183 case RISCV::VFWNMACC_VV:
1184 case RISCV::VFWNMACC_VF:
1185 case RISCV::VFWMSAC_VV:
1186 case RISCV::VFWMSAC_VF:
1187 case RISCV::VFWNMSAC_VV:
1188 case RISCV::VFWNMSAC_VF:
1189 case RISCV::VFWMACCBF16_VV:
1190 case RISCV::VFWMACCBF16_VF:
1191 // Vector Floating-Point Square-Root Instruction
1192 case RISCV::VFSQRT_V:
1193 // Vector Floating-Point Reciprocal Square-Root Estimate Instruction
1194 case RISCV::VFRSQRT7_V:
1195 // Vector Floating-Point Reciprocal Estimate Instruction
1196 case RISCV::VFREC7_V:
1197 // Vector Floating-Point MIN/MAX Instructions
1198 case RISCV::VFMIN_VF:
1199 case RISCV::VFMIN_VV:
1200 case RISCV::VFMAX_VF:
1201 case RISCV::VFMAX_VV:
1202 // Vector Floating-Point Sign-Injection Instructions
1203 case RISCV::VFSGNJ_VF:
1204 case RISCV::VFSGNJ_VV:
1205 case RISCV::VFSGNJN_VV:
1206 case RISCV::VFSGNJN_VF:
1207 case RISCV::VFSGNJX_VF:
1208 case RISCV::VFSGNJX_VV:
1209 // Vector Floating-Point Compare Instructions
1210 case RISCV::VMFEQ_VF:
1211 case RISCV::VMFEQ_VV:
1212 case RISCV::VMFNE_VF:
1213 case RISCV::VMFNE_VV:
1214 case RISCV::VMFLT_VF:
1215 case RISCV::VMFLT_VV:
1216 case RISCV::VMFLE_VF:
1217 case RISCV::VMFLE_VV:
1218 case RISCV::VMFGT_VF:
1219 case RISCV::VMFGE_VF:
1220 // Vector Floating-Point Classify Instruction
1221 case RISCV::VFCLASS_V:
1222 // Vector Floating-Point Merge Instruction
1223 case RISCV::VFMERGE_VFM:
1224 // Vector Floating-Point Move Instruction
1225 case RISCV::VFMV_V_F:
1226 // Single-Width Floating-Point/Integer Type-Convert Instructions
1227 case RISCV::VFCVT_XU_F_V:
1228 case RISCV::VFCVT_X_F_V:
1229 case RISCV::VFCVT_RTZ_XU_F_V:
1230 case RISCV::VFCVT_RTZ_X_F_V:
1231 case RISCV::VFCVT_F_XU_V:
1232 case RISCV::VFCVT_F_X_V:
1233 // Widening Floating-Point/Integer Type-Convert Instructions
1234 case RISCV::VFWCVT_XU_F_V:
1235 case RISCV::VFWCVT_X_F_V:
1236 case RISCV::VFWCVT_RTZ_XU_F_V:
1237 case RISCV::VFWCVT_RTZ_X_F_V:
1238 case RISCV::VFWCVT_F_XU_V:
1239 case RISCV::VFWCVT_F_X_V:
1240 case RISCV::VFWCVT_F_F_V:
1241 case RISCV::VFWCVTBF16_F_F_V:
1242 // Narrowing Floating-Point/Integer Type-Convert Instructions
1243 case RISCV::VFNCVT_XU_F_W:
1244 case RISCV::VFNCVT_X_F_W:
1245 case RISCV::VFNCVT_RTZ_XU_F_W:
1246 case RISCV::VFNCVT_RTZ_X_F_W:
1247 case RISCV::VFNCVT_F_XU_W:
1248 case RISCV::VFNCVT_F_X_W:
1249 case RISCV::VFNCVT_F_F_W:
1250 case RISCV::VFNCVT_ROD_F_F_W:
1251 case RISCV::VFNCVTBF16_F_F_W:
1252 return true;
1253 }
1254
1255 return false;
1256}
1257
1258/// Return true if MO is a vector operand but is used as a scalar operand.
1260 const MachineInstr *MI = MO.getParent();
1262 RISCVVPseudosTable::getPseudoInfo(MI->getOpcode());
1263
1264 if (!RVV)
1265 return false;
1266
1267 switch (RVV->BaseInstr) {
1268 // Reductions only use vs1[0] of vs1
1269 case RISCV::VREDAND_VS:
1270 case RISCV::VREDMAX_VS:
1271 case RISCV::VREDMAXU_VS:
1272 case RISCV::VREDMIN_VS:
1273 case RISCV::VREDMINU_VS:
1274 case RISCV::VREDOR_VS:
1275 case RISCV::VREDSUM_VS:
1276 case RISCV::VREDXOR_VS:
1277 case RISCV::VWREDSUM_VS:
1278 case RISCV::VWREDSUMU_VS:
1279 case RISCV::VFREDMAX_VS:
1280 case RISCV::VFREDMIN_VS:
1281 case RISCV::VFREDOSUM_VS:
1282 case RISCV::VFREDUSUM_VS:
1283 case RISCV::VFWREDOSUM_VS:
1284 case RISCV::VFWREDUSUM_VS:
1285 return MO.getOperandNo() == 3;
1286 case RISCV::VMV_X_S:
1287 case RISCV::VFMV_F_S:
1288 return MO.getOperandNo() == 1;
1289 default:
1290 return false;
1291 }
1292}
1293
1294bool RISCVVLOptimizer::isCandidate(const MachineInstr &MI) const {
1295 const MCInstrDesc &Desc = MI.getDesc();
1296 if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags))
1297 return false;
1298
1299 if (MI.getNumExplicitDefs() != 1)
1300 return false;
1301
1302 // Some instructions have implicit defs e.g. $vxsat. If they might be read
1303 // later then we can't reduce VL.
1304 if (!MI.allImplicitDefsAreDead()) {
1305 LLVM_DEBUG(dbgs() << "Not a candidate because has non-dead implicit def\n");
1306 return false;
1307 }
1308
1309 if (MI.mayRaiseFPException()) {
1310 LLVM_DEBUG(dbgs() << "Not a candidate because may raise FP exception\n");
1311 return false;
1312 }
1313
1314 for (const MachineMemOperand *MMO : MI.memoperands()) {
1315 if (MMO->isVolatile()) {
1316 LLVM_DEBUG(dbgs() << "Not a candidate because contains volatile MMO\n");
1317 return false;
1318 }
1319 }
1320
1321 // Some instructions that produce vectors have semantics that make it more
1322 // difficult to determine whether the VL can be reduced. For example, some
1323 // instructions, such as reductions, may write lanes past VL to a scalar
1324 // register. Other instructions, such as some loads or stores, may write
1325 // lower lanes using data from higher lanes. There may be other complex
1326 // semantics not mentioned here that make it hard to determine whether
1327 // the VL can be optimized. As a result, a white-list of supported
1328 // instructions is used. Over time, more instructions can be supported
1329 // upon careful examination of their semantics under the logic in this
1330 // optimization.
1331 // TODO: Use a better approach than a white-list, such as adding
1332 // properties to instructions using something like TSFlags.
1333 if (!isSupportedInstr(MI)) {
1334 LLVM_DEBUG(dbgs() << "Not a candidate due to unsupported instruction: "
1335 << MI);
1336 return false;
1337 }
1338
1340 TII->get(RISCV::getRVVMCOpcode(MI.getOpcode())).TSFlags) &&
1341 "Instruction shouldn't be supported if elements depend on VL");
1342
1344 MRI->getRegClass(MI.getOperand(0).getReg())->TSFlags) &&
1345 "All supported instructions produce a vector register result");
1346
1347 LLVM_DEBUG(dbgs() << "Found a candidate for VL reduction: " << MI << "\n");
1348 return true;
1349}
1350
1351std::optional<MachineOperand>
1352RISCVVLOptimizer::getMinimumVLForUser(const MachineOperand &UserOp) const {
1353 const MachineInstr &UserMI = *UserOp.getParent();
1354 const MCInstrDesc &Desc = UserMI.getDesc();
1355
1356 if (!RISCVII::hasVLOp(Desc.TSFlags) || !RISCVII::hasSEWOp(Desc.TSFlags)) {
1357 LLVM_DEBUG(dbgs() << " Abort due to lack of VL, assume that"
1358 " use VLMAX\n");
1359 return std::nullopt;
1360 }
1361
1363 TII->get(RISCV::getRVVMCOpcode(UserMI.getOpcode())).TSFlags)) {
1364 LLVM_DEBUG(dbgs() << " Abort because used by unsafe instruction\n");
1365 return std::nullopt;
1366 }
1367
1368 unsigned VLOpNum = RISCVII::getVLOpNum(Desc);
1369 const MachineOperand &VLOp = UserMI.getOperand(VLOpNum);
1370 // Looking for an immediate or a register VL that isn't X0.
1371 assert((!VLOp.isReg() || VLOp.getReg() != RISCV::X0) &&
1372 "Did not expect X0 VL");
1373
1374 // If the user is a passthru it will read the elements past VL, so
1375 // abort if any of the elements past VL are demanded.
1376 if (UserOp.isTied()) {
1377 assert(UserOp.getOperandNo() == UserMI.getNumExplicitDefs() &&
1379 auto DemandedVL = DemandedVLs.lookup(&UserMI);
1380 if (!DemandedVL || !RISCV::isVLKnownLE(*DemandedVL, VLOp)) {
1381 LLVM_DEBUG(dbgs() << " Abort because user is passthru in "
1382 "instruction with demanded tail\n");
1383 return std::nullopt;
1384 }
1385 }
1386
1387 // Instructions like reductions may use a vector register as a scalar
1388 // register. In this case, we should treat it as only reading the first lane.
1389 if (isVectorOpUsedAsScalarOp(UserOp)) {
1390 LLVM_DEBUG(dbgs() << " Used this operand as a scalar operand\n");
1391 return MachineOperand::CreateImm(1);
1392 }
1393
1394 // If we know the demanded VL of UserMI, then we can reduce the VL it
1395 // requires.
1396 if (auto DemandedVL = DemandedVLs.lookup(&UserMI)) {
1397 assert(isCandidate(UserMI));
1398 if (RISCV::isVLKnownLE(*DemandedVL, VLOp))
1399 return DemandedVL;
1400 }
1401
1402 return VLOp;
1403}
1404
1405/// Return true if MI is an instruction used for assembling registers
1406/// for segmented store instructions, namely, RISCVISD::TUPLE_INSERT.
1407/// Currently it's lowered to INSERT_SUBREG.
1409 if (!MI.isInsertSubreg())
1410 return false;
1411
1412 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
1413 const TargetRegisterClass *DstRC = MRI.getRegClass(MI.getOperand(0).getReg());
1414 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
1415 if (!RISCVRI::isVRegClass(DstRC->TSFlags))
1416 return false;
1417 unsigned NF = RISCVRI::getNF(DstRC->TSFlags);
1418 if (NF < 2)
1419 return false;
1420
1421 // Check whether INSERT_SUBREG has the correct subreg index for tuple inserts.
1422 auto VLMul = RISCVRI::getLMul(DstRC->TSFlags);
1423 unsigned SubRegIdx = MI.getOperand(3).getImm();
1424 [[maybe_unused]] auto [LMul, IsFractional] = RISCVVType::decodeVLMUL(VLMul);
1425 assert(!IsFractional && "unexpected LMUL for tuple register classes");
1426 return TRI->getSubRegIdxSize(SubRegIdx) == RISCV::RVVBitsPerBlock * LMul;
1427}
1428
1430 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
1431 case VSSEG_CASES(8):
1432 case VSSSEG_CASES(8):
1433 case VSUXSEG_CASES(8):
1434 case VSOXSEG_CASES(8):
1435 case VSSEG_CASES(16):
1436 case VSSSEG_CASES(16):
1437 case VSUXSEG_CASES(16):
1438 case VSOXSEG_CASES(16):
1439 case VSSEG_CASES(32):
1440 case VSSSEG_CASES(32):
1441 case VSUXSEG_CASES(32):
1442 case VSOXSEG_CASES(32):
1443 case VSSEG_CASES(64):
1444 case VSSSEG_CASES(64):
1445 case VSUXSEG_CASES(64):
1446 case VSOXSEG_CASES(64):
1447 return true;
1448 default:
1449 return false;
1450 }
1451}
1452
1453std::optional<MachineOperand>
1454RISCVVLOptimizer::checkUsers(const MachineInstr &MI) const {
1455 std::optional<MachineOperand> CommonVL;
1456 SmallSetVector<MachineOperand *, 8> Worklist;
1457 SmallPtrSet<const MachineInstr *, 4> PHISeen;
1458 for (auto &UserOp : MRI->use_operands(MI.getOperand(0).getReg()))
1459 Worklist.insert(&UserOp);
1460
1461 while (!Worklist.empty()) {
1462 MachineOperand &UserOp = *Worklist.pop_back_val();
1463 const MachineInstr &UserMI = *UserOp.getParent();
1464 LLVM_DEBUG(dbgs() << " Checking user: " << UserMI << "\n");
1465
1466 if (UserMI.isFullCopy() && UserMI.getOperand(0).getReg().isVirtual()) {
1467 LLVM_DEBUG(dbgs() << " Peeking through uses of COPY\n");
1469 MRI->use_operands(UserMI.getOperand(0).getReg())));
1470 continue;
1471 }
1472
1473 if (isTupleInsertInstr(UserMI)) {
1474 LLVM_DEBUG(dbgs().indent(4) << "Peeking through uses of INSERT_SUBREG\n");
1475 for (MachineOperand &UseOp :
1476 MRI->use_operands(UserMI.getOperand(0).getReg())) {
1477 const MachineInstr &CandidateMI = *UseOp.getParent();
1478 // We should not propagate the VL if the user is not a segmented store
1479 // or another INSERT_SUBREG, since VL just works differently
1480 // between segmented operations (per-field) v.s. other RVV ops (on the
1481 // whole register group).
1482 if (!isTupleInsertInstr(CandidateMI) &&
1483 !isSegmentedStoreInstr(CandidateMI))
1484 return std::nullopt;
1485 Worklist.insert(&UseOp);
1486 }
1487 continue;
1488 }
1489
1490 if (UserMI.isPHI()) {
1491 // Don't follow PHI cycles
1492 if (!PHISeen.insert(&UserMI).second)
1493 continue;
1494 LLVM_DEBUG(dbgs() << " Peeking through uses of PHI\n");
1496 MRI->use_operands(UserMI.getOperand(0).getReg())));
1497 continue;
1498 }
1499
1500 auto VLOp = getMinimumVLForUser(UserOp);
1501 if (!VLOp)
1502 return std::nullopt;
1503
1504 // Use the largest VL among all the users. If we cannot determine this
1505 // statically, then we cannot optimize the VL.
1506 if (!CommonVL || RISCV::isVLKnownLE(*CommonVL, *VLOp)) {
1507 CommonVL = *VLOp;
1508 LLVM_DEBUG(dbgs() << " User VL is: " << VLOp << "\n");
1509 } else if (!RISCV::isVLKnownLE(*VLOp, *CommonVL)) {
1510 LLVM_DEBUG(dbgs() << " Abort because cannot determine a common VL\n");
1511 return std::nullopt;
1512 }
1513
1514 if (!RISCVII::hasSEWOp(UserMI.getDesc().TSFlags)) {
1515 LLVM_DEBUG(dbgs() << " Abort due to lack of SEW operand\n");
1516 return std::nullopt;
1517 }
1518
1519 std::optional<OperandInfo> ConsumerInfo = getOperandInfo(UserOp);
1520 std::optional<OperandInfo> ProducerInfo = getOperandInfo(MI.getOperand(0));
1521 if (!ConsumerInfo || !ProducerInfo) {
1522 LLVM_DEBUG(dbgs() << " Abort due to unknown operand information.\n");
1523 LLVM_DEBUG(dbgs() << " ConsumerInfo is: " << ConsumerInfo << "\n");
1524 LLVM_DEBUG(dbgs() << " ProducerInfo is: " << ProducerInfo << "\n");
1525 return std::nullopt;
1526 }
1527
1528 if (!OperandInfo::areCompatible(*ProducerInfo, *ConsumerInfo)) {
1529 LLVM_DEBUG(
1530 dbgs()
1531 << " Abort due to incompatible information for EMUL or EEW.\n");
1532 LLVM_DEBUG(dbgs() << " ConsumerInfo is: " << ConsumerInfo << "\n");
1533 LLVM_DEBUG(dbgs() << " ProducerInfo is: " << ProducerInfo << "\n");
1534 return std::nullopt;
1535 }
1536 }
1537
1538 return CommonVL;
1539}
1540
1541bool RISCVVLOptimizer::tryReduceVL(MachineInstr &MI) const {
1542 LLVM_DEBUG(dbgs() << "Trying to reduce VL for " << MI);
1543
1544 unsigned VLOpNum = RISCVII::getVLOpNum(MI.getDesc());
1545 MachineOperand &VLOp = MI.getOperand(VLOpNum);
1546
1547 // If the VL is 1, then there is no need to reduce it. This is an
1548 // optimization, not needed to preserve correctness.
1549 if (VLOp.isImm() && VLOp.getImm() == 1) {
1550 LLVM_DEBUG(dbgs() << " Abort due to VL == 1, no point in reducing.\n");
1551 return false;
1552 }
1553
1554 auto CommonVL = DemandedVLs.lookup(&MI);
1555 if (!CommonVL)
1556 return false;
1557
1558 assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
1559 "Expected VL to be an Imm or virtual Reg");
1560
1561 // If the VL is defined by a vleff that doesn't dominate MI, try using the
1562 // vleff's AVL. It will be greater than or equal to the output VL.
1563 if (CommonVL->isReg()) {
1564 const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
1565 if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) &&
1566 !MDT->dominates(VLMI, &MI))
1567 CommonVL = VLMI->getOperand(RISCVII::getVLOpNum(VLMI->getDesc()));
1568 }
1569
1570 if (!RISCV::isVLKnownLE(*CommonVL, VLOp)) {
1571 LLVM_DEBUG(dbgs() << " Abort due to CommonVL not <= VLOp.\n");
1572 return false;
1573 }
1574
1575 if (CommonVL->isIdenticalTo(VLOp)) {
1576 LLVM_DEBUG(
1577 dbgs() << " Abort due to CommonVL == VLOp, no point in reducing.\n");
1578 return false;
1579 }
1580
1581 if (CommonVL->isImm()) {
1582 LLVM_DEBUG(dbgs() << " Reduce VL from " << VLOp << " to "
1583 << CommonVL->getImm() << " for " << MI << "\n");
1584 VLOp.ChangeToImmediate(CommonVL->getImm());
1585 return true;
1586 }
1587 const MachineInstr *VLMI = MRI->getVRegDef(CommonVL->getReg());
1588 if (!MDT->dominates(VLMI, &MI)) {
1589 LLVM_DEBUG(dbgs() << " Abort due to VL not dominating.\n");
1590 return false;
1591 }
1592 LLVM_DEBUG(
1593 dbgs() << " Reduce VL from " << VLOp << " to "
1594 << printReg(CommonVL->getReg(), MRI->getTargetRegisterInfo())
1595 << " for " << MI << "\n");
1596
1597 // All our checks passed. We can reduce VL.
1598 VLOp.ChangeToRegister(CommonVL->getReg(), false);
1599 return true;
1600}
1601
1602bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
1603 if (skipFunction(MF.getFunction()))
1604 return false;
1605
1606 MRI = &MF.getRegInfo();
1607 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1608
1609 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
1610 if (!ST.hasVInstructions())
1611 return false;
1612
1613 TII = ST.getInstrInfo();
1614
1615 assert(DemandedVLs.empty());
1616
1617 // For each instruction that defines a vector, compute what VL its
1618 // downstream users demand.
1619 for (MachineBasicBlock *MBB : post_order(&MF)) {
1621 for (MachineInstr &MI : reverse(*MBB)) {
1622 if (!isCandidate(MI))
1623 continue;
1624 DemandedVLs.insert({&MI, checkUsers(MI)});
1625 }
1626 }
1627
1628 // Then go through and see if we can reduce the VL of any instructions to
1629 // only what's demanded.
1630 bool MadeChange = false;
1631 for (MachineBasicBlock &MBB : MF) {
1632 // Avoid unreachable blocks as they have degenerate dominance
1633 if (!MDT->isReachableFromEntry(&MBB))
1634 continue;
1635
1636 for (auto &MI : reverse(MBB)) {
1637 if (!isCandidate(MI))
1638 continue;
1639 if (!tryReduceVL(MI))
1640 continue;
1641 MadeChange = true;
1642 }
1643 }
1644
1645 DemandedVLs.clear();
1646 return MadeChange;
1647}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
Analysis containing CSE Info
Definition CSEInfo.cpp:27
#define LLVM_ATTRIBUTE_UNUSED
Definition Compiler.h:298
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static unsigned getIntegerExtensionOperandEEW(unsigned Factor, const MachineInstr &MI, const MachineOperand &MO)
Dest has EEW=SEW.
static std::optional< OperandInfo > getOperandInfo(const MachineOperand &MO)
#define VSOXSEG_CASES(EEW)
static bool isSegmentedStoreInstr(const MachineInstr &MI)
static bool isVectorOpUsedAsScalarOp(const MachineOperand &MO)
Return true if MO is a vector operand but is used as a scalar operand.
static std::optional< unsigned > getOperandLog2EEW(const MachineOperand &MO)
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...
#define VSUXSEG_CASES(EEW)
static bool isSupportedInstr(const MachineInstr &MI)
Return true if this optimization should consider MI for VL reduction.
#define VSSSEG_CASES(EEW)
#define VSSEG_CASES(EEW)
static bool isTupleInsertInstr(const MachineInstr &MI)
Return true if MI is an instruction used for assembling registers for segmented store instructions,...
#define LLVM_DEBUG(...)
Definition Debug.h:119
#define PASS_NAME
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:270
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
Describe properties that are true of each instruction in the target description file.
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition MCInstrDesc.h:86
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
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.
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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isFullCopy() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI 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.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
LLVM_ABI 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.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:74
void insert_range(Range &&R)
Definition SetVector.h:193
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:99
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:168
value_type pop_back_val()
Definition SetVector.h:296
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
TargetInstrInfo - Interface to description of machine instruction set.
const uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#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 bool readsPastVL(uint64_t TSFlags)
static bool isTiedPseudo(uint64_t TSFlags)
static RISCVVType::VLMUL getLMul(uint64_t TSFlags)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool elementsDependOnVL(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
static unsigned getNF(uint8_t TSFlags)
static bool isVRegClass(uint8_t TSFlags)
static RISCVVType::VLMUL getLMul(uint8_t TSFlags)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
static constexpr unsigned RVVBitsPerBlock
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
FunctionPass * createRISCVVLOptimizerPass()
iterator_range< po_iterator< T > > post_order(const T &G)
Op::Description Desc
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:336
auto reverse(ContainerTy &&C)
Definition STLExtras.h:420
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:363
LLVM_ABI 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.