LLVM 20.0.0git
RISCVVectorPeephole.cpp
Go to the documentation of this file.
1//===- RISCVVectorPeephole.cpp - MI Vector Pseudo Peepholes ---------------===//
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 performs various vector pseudo peephole optimisations after
10// instruction selection.
11//
12// Currently it converts vmerge.vvm to vmv.v.v
13// PseudoVMERGE_VVM %false, %false, %true, %allonesmask, %vl, %sew
14// ->
15// PseudoVMV_V_V %false, %true, %vl, %sew
16//
17// And masked pseudos to unmasked pseudos
18// PseudoVADD_V_V_MASK %passthru, %a, %b, %allonesmask, %vl, sew, policy
19// ->
20// PseudoVADD_V_V %passthru %a, %b, %vl, sew, policy
21//
22// It also converts AVLs to VLMAX where possible
23// %vl = VLENB * something
24// PseudoVADD_V_V %passthru, %a, %b, %vl, sew, policy
25// ->
26// PseudoVADD_V_V %passthru, %a, %b, -1, sew, policy
27//
28//===----------------------------------------------------------------------===//
29
30#include "RISCV.h"
31#include "RISCVISelDAGToDAG.h"
32#include "RISCVSubtarget.h"
37
38using namespace llvm;
39
40#define DEBUG_TYPE "riscv-vector-peephole"
41
42namespace {
43
44class RISCVVectorPeephole : public MachineFunctionPass {
45public:
46 static char ID;
47 const TargetInstrInfo *TII;
50 const RISCVSubtarget *ST;
51 RISCVVectorPeephole() : MachineFunctionPass(ID) {}
52
53 bool runOnMachineFunction(MachineFunction &MF) override;
56 MachineFunctionProperties::Property::IsSSA);
57 }
58
59 StringRef getPassName() const override {
60 return "RISC-V Vector Peephole Optimization";
61 }
62
63private:
64 bool tryToReduceVL(MachineInstr &MI) const;
65 bool convertToVLMAX(MachineInstr &MI) const;
66 bool convertToWholeRegister(MachineInstr &MI) const;
67 bool convertToUnmasked(MachineInstr &MI) const;
68 bool convertVMergeToVMv(MachineInstr &MI) const;
69 bool foldVMV_V_V(MachineInstr &MI);
70
71 bool isAllOnesMask(const MachineInstr *MaskDef) const;
72 std::optional<unsigned> getConstant(const MachineOperand &VL) const;
73
74 /// Maps uses of V0 to the corresponding def of V0.
76};
77
78} // namespace
79
80char RISCVVectorPeephole::ID = 0;
81
82INITIALIZE_PASS(RISCVVectorPeephole, DEBUG_TYPE, "RISC-V Fold Masks", false,
83 false)
84
85/// Given two VL operands, do we know that LHS <= RHS?
86static bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS) {
87 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
88 LHS.getReg() == RHS.getReg())
89 return true;
91 return true;
92 if (LHS.isImm() && LHS.getImm() == RISCV::VLMaxSentinel)
93 return false;
94 if (!LHS.isImm() || !RHS.isImm())
95 return false;
96 return LHS.getImm() <= RHS.getImm();
97}
98
99static unsigned getSEWLMULRatio(const MachineInstr &MI) {
100 RISCVII::VLMUL LMUL = RISCVII::getLMul(MI.getDesc().TSFlags);
101 unsigned Log2SEW = MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
102 return RISCVVType::getSEWLMULRatio(1 << Log2SEW, LMUL);
103}
104
105// Attempt to reduce the VL of an instruction whose sole use is feeding a
106// instruction with a narrower VL. This currently works backwards from the
107// user instruction (which might have a smaller VL).
108bool RISCVVectorPeephole::tryToReduceVL(MachineInstr &MI) const {
109 // Note that the goal here is a bit multifaceted.
110 // 1) For store's reducing the VL of the value being stored may help to
111 // reduce VL toggles. This is somewhat of an artifact of the fact we
112 // promote arithmetic instructions but VL predicate stores.
113 // 2) For vmv.v.v reducing VL eagerly on the source instruction allows us
114 // to share code with the foldVMV_V_V transform below.
115 //
116 // Note that to the best of our knowledge, reducing VL is generally not
117 // a significant win on real hardware unless we can also reduce LMUL which
118 // this code doesn't try to do.
119 //
120 // TODO: We can handle a bunch more instructions here, and probably
121 // recurse backwards through operands too.
122 unsigned SrcIdx = 0;
123 switch (RISCV::getRVVMCOpcode(MI.getOpcode())) {
124 default:
125 return false;
126 case RISCV::VSE8_V:
127 case RISCV::VSE16_V:
128 case RISCV::VSE32_V:
129 case RISCV::VSE64_V:
130 break;
131 case RISCV::VMV_V_V:
132 SrcIdx = 2;
133 break;
134 }
135
136 MachineOperand &VL = MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
137 if (VL.isImm() && VL.getImm() == RISCV::VLMaxSentinel)
138 return false;
139
140 Register SrcReg = MI.getOperand(SrcIdx).getReg();
141 // Note: one *use*, not one *user*.
142 if (!MRI->hasOneUse(SrcReg))
143 return false;
144
145 MachineInstr *Src = MRI->getVRegDef(SrcReg);
146 if (!Src || Src->hasUnmodeledSideEffects() ||
147 Src->getParent() != MI.getParent() || Src->getNumDefs() != 1 ||
148 !RISCVII::hasVLOp(Src->getDesc().TSFlags) ||
149 !RISCVII::hasSEWOp(Src->getDesc().TSFlags))
150 return false;
151
152 // Src needs to have the same VLMAX as MI
153 if (getSEWLMULRatio(MI) != getSEWLMULRatio(*Src))
154 return false;
155
156 bool ActiveElementsAffectResult = RISCVII::activeElementsAffectResult(
157 TII->get(RISCV::getRVVMCOpcode(Src->getOpcode())).TSFlags);
158 if (ActiveElementsAffectResult || Src->mayRaiseFPException())
159 return false;
160
161 MachineOperand &SrcVL = Src->getOperand(RISCVII::getVLOpNum(Src->getDesc()));
162 if (VL.isIdenticalTo(SrcVL) || !isVLKnownLE(VL, SrcVL))
163 return false;
164
165 if (VL.isImm())
166 SrcVL.ChangeToImmediate(VL.getImm());
167 else if (VL.isReg())
168 SrcVL.ChangeToRegister(VL.getReg(), false);
169
170 // TODO: For instructions with a passthru, we could clear the passthru
171 // and tail policy since we've just proven the tail is not demanded.
172 return true;
173}
174
175/// Check if an operand is an immediate or a materialized ADDI $x0, imm.
176std::optional<unsigned>
177RISCVVectorPeephole::getConstant(const MachineOperand &VL) const {
178 if (VL.isImm())
179 return VL.getImm();
180
181 MachineInstr *Def = MRI->getVRegDef(VL.getReg());
182 if (!Def || Def->getOpcode() != RISCV::ADDI ||
183 Def->getOperand(1).getReg() != RISCV::X0)
184 return std::nullopt;
185 return Def->getOperand(2).getImm();
186}
187
188/// Convert AVLs that are known to be VLMAX to the VLMAX sentinel.
189bool RISCVVectorPeephole::convertToVLMAX(MachineInstr &MI) const {
190 if (!RISCVII::hasVLOp(MI.getDesc().TSFlags) ||
191 !RISCVII::hasSEWOp(MI.getDesc().TSFlags))
192 return false;
193
194 auto LMUL = RISCVVType::decodeVLMUL(RISCVII::getLMul(MI.getDesc().TSFlags));
195 // Fixed-point value, denominator=8
196 unsigned LMULFixed = LMUL.second ? (8 / LMUL.first) : 8 * LMUL.first;
197 unsigned Log2SEW = MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
198 // A Log2SEW of 0 is an operation on mask registers only
199 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
200 assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
201 assert(8 * LMULFixed / SEW > 0);
202
203 // If the exact VLEN is known then we know VLMAX, check if the AVL == VLMAX.
204 MachineOperand &VL = MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
205 if (auto VLen = ST->getRealVLen(), AVL = getConstant(VL);
206 VLen && AVL && (*VLen * LMULFixed) / SEW == *AVL * 8) {
208 return true;
209 }
210
211 // If an AVL is a VLENB that's possibly scaled to be equal to VLMAX, convert
212 // it to the VLMAX sentinel value.
213 if (!VL.isReg())
214 return false;
215 MachineInstr *Def = MRI->getVRegDef(VL.getReg());
216 if (!Def)
217 return false;
218
219 // Fixed-point value, denominator=8
220 uint64_t ScaleFixed = 8;
221 // Check if the VLENB was potentially scaled with slli/srli
222 if (Def->getOpcode() == RISCV::SLLI) {
223 assert(Def->getOperand(2).getImm() < 64);
224 ScaleFixed <<= Def->getOperand(2).getImm();
225 Def = MRI->getVRegDef(Def->getOperand(1).getReg());
226 } else if (Def->getOpcode() == RISCV::SRLI) {
227 assert(Def->getOperand(2).getImm() < 64);
228 ScaleFixed >>= Def->getOperand(2).getImm();
229 Def = MRI->getVRegDef(Def->getOperand(1).getReg());
230 }
231
232 if (!Def || Def->getOpcode() != RISCV::PseudoReadVLENB)
233 return false;
234
235 // AVL = (VLENB * Scale)
236 //
237 // VLMAX = (VLENB * 8 * LMUL) / SEW
238 //
239 // AVL == VLMAX
240 // -> VLENB * Scale == (VLENB * 8 * LMUL) / SEW
241 // -> Scale == (8 * LMUL) / SEW
242 if (ScaleFixed != 8 * LMULFixed / SEW)
243 return false;
244
246
247 return true;
248}
249
250bool RISCVVectorPeephole::isAllOnesMask(const MachineInstr *MaskDef) const {
251 assert(MaskDef && MaskDef->isCopy() &&
252 MaskDef->getOperand(0).getReg() == RISCV::V0);
253 Register SrcReg = TRI->lookThruCopyLike(MaskDef->getOperand(1).getReg(), MRI);
254 if (!SrcReg.isVirtual())
255 return false;
256 MaskDef = MRI->getVRegDef(SrcReg);
257 if (!MaskDef)
258 return false;
259
260 // TODO: Check that the VMSET is the expected bitwidth? The pseudo has
261 // undefined behaviour if it's the wrong bitwidth, so we could choose to
262 // assume that it's all-ones? Same applies to its VL.
263 switch (MaskDef->getOpcode()) {
264 case RISCV::PseudoVMSET_M_B1:
265 case RISCV::PseudoVMSET_M_B2:
266 case RISCV::PseudoVMSET_M_B4:
267 case RISCV::PseudoVMSET_M_B8:
268 case RISCV::PseudoVMSET_M_B16:
269 case RISCV::PseudoVMSET_M_B32:
270 case RISCV::PseudoVMSET_M_B64:
271 return true;
272 default:
273 return false;
274 }
275}
276
277/// Convert unit strided unmasked loads and stores to whole-register equivalents
278/// to avoid the dependency on $vl and $vtype.
279///
280/// %x = PseudoVLE8_V_M1 %passthru, %ptr, %vlmax, policy
281/// PseudoVSE8_V_M1 %v, %ptr, %vlmax
282///
283/// ->
284///
285/// %x = VL1RE8_V %ptr
286/// VS1R_V %v, %ptr
287bool RISCVVectorPeephole::convertToWholeRegister(MachineInstr &MI) const {
288#define CASE_WHOLE_REGISTER_LMUL_SEW(lmul, sew) \
289 case RISCV::PseudoVLE##sew##_V_M##lmul: \
290 NewOpc = RISCV::VL##lmul##RE##sew##_V; \
291 break; \
292 case RISCV::PseudoVSE##sew##_V_M##lmul: \
293 NewOpc = RISCV::VS##lmul##R_V; \
294 break;
295#define CASE_WHOLE_REGISTER_LMUL(lmul) \
296 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 8) \
297 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 16) \
298 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 32) \
299 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 64)
300
301 unsigned NewOpc;
302 switch (MI.getOpcode()) {
307 default:
308 return false;
309 }
310
311 MachineOperand &VLOp = MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
312 if (!VLOp.isImm() || VLOp.getImm() != RISCV::VLMaxSentinel)
313 return false;
314
315 // Whole register instructions aren't pseudos so they don't have
316 // policy/SEW/AVL ops, and they don't have passthrus.
317 if (RISCVII::hasVecPolicyOp(MI.getDesc().TSFlags))
318 MI.removeOperand(RISCVII::getVecPolicyOpNum(MI.getDesc()));
319 MI.removeOperand(RISCVII::getSEWOpNum(MI.getDesc()));
320 MI.removeOperand(RISCVII::getVLOpNum(MI.getDesc()));
321 if (RISCVII::isFirstDefTiedToFirstUse(MI.getDesc()))
322 MI.removeOperand(1);
323
324 MI.setDesc(TII->get(NewOpc));
325
326 return true;
327}
328
329// Transform (VMERGE_VVM_<LMUL> false, false, true, allones, vl, sew) to
330// (VMV_V_V_<LMUL> false, true, vl, sew). It may decrease uses of VMSET.
331bool RISCVVectorPeephole::convertVMergeToVMv(MachineInstr &MI) const {
332#define CASE_VMERGE_TO_VMV(lmul) \
333 case RISCV::PseudoVMERGE_VVM_##lmul: \
334 NewOpc = RISCV::PseudoVMV_V_V_##lmul; \
335 break;
336 unsigned NewOpc;
337 switch (MI.getOpcode()) {
338 default:
339 return false;
347 }
348
349 Register PassthruReg = MI.getOperand(1).getReg();
350 Register FalseReg = MI.getOperand(2).getReg();
351 // Check passthru == false (or passthru == undef)
352 if (PassthruReg != RISCV::NoRegister &&
353 TRI->lookThruCopyLike(PassthruReg, MRI) !=
354 TRI->lookThruCopyLike(FalseReg, MRI))
355 return false;
356
357 assert(MI.getOperand(4).isReg() && MI.getOperand(4).getReg() == RISCV::V0);
358 if (!isAllOnesMask(V0Defs.lookup(&MI)))
359 return false;
360
361 MI.setDesc(TII->get(NewOpc));
362 MI.removeOperand(1); // Passthru operand
363 MI.tieOperands(0, 1); // Tie false to dest
364 MI.removeOperand(3); // Mask operand
365 MI.addOperand(
367
368 // vmv.v.v doesn't have a mask operand, so we may be able to inflate the
369 // register class for the destination and passthru operands e.g. VRNoV0 -> VR
370 MRI->recomputeRegClass(MI.getOperand(0).getReg());
371 MRI->recomputeRegClass(MI.getOperand(1).getReg());
372 return true;
373}
374
375bool RISCVVectorPeephole::convertToUnmasked(MachineInstr &MI) const {
377 RISCV::getMaskedPseudoInfo(MI.getOpcode());
378 if (!I)
379 return false;
380
381 if (!isAllOnesMask(V0Defs.lookup(&MI)))
382 return false;
383
384 // There are two classes of pseudos in the table - compares and
385 // everything else. See the comment on RISCVMaskedPseudo for details.
386 const unsigned Opc = I->UnmaskedPseudo;
387 const MCInstrDesc &MCID = TII->get(Opc);
388 [[maybe_unused]] const bool HasPolicyOp =
390 const bool HasPassthru = RISCVII::isFirstDefTiedToFirstUse(MCID);
391#ifndef NDEBUG
392 const MCInstrDesc &MaskedMCID = TII->get(MI.getOpcode());
395 "Masked and unmasked pseudos are inconsistent");
396 assert(HasPolicyOp == HasPassthru && "Unexpected pseudo structure");
397#endif
398 (void)HasPolicyOp;
399
400 MI.setDesc(MCID);
401
402 // TODO: Increment all MaskOpIdxs in tablegen by num of explicit defs?
403 unsigned MaskOpIdx = I->MaskOpIdx + MI.getNumExplicitDefs();
404 MI.removeOperand(MaskOpIdx);
405
406 // The unmasked pseudo will no longer be constrained to the vrnov0 reg class,
407 // so try and relax it to vr.
408 MRI->recomputeRegClass(MI.getOperand(0).getReg());
409 unsigned PassthruOpIdx = MI.getNumExplicitDefs();
410 if (HasPassthru) {
411 if (MI.getOperand(PassthruOpIdx).getReg() != RISCV::NoRegister)
412 MRI->recomputeRegClass(MI.getOperand(PassthruOpIdx).getReg());
413 } else
414 MI.removeOperand(PassthruOpIdx);
415
416 return true;
417}
418
419/// Check if it's safe to move From down to To, checking that no physical
420/// registers are clobbered.
421static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To) {
422 assert(From.getParent() == To.getParent() && !From.hasImplicitDef());
423 SmallVector<Register> PhysUses;
424 for (const MachineOperand &MO : From.all_uses())
425 if (MO.getReg().isPhysical())
426 PhysUses.push_back(MO.getReg());
427 bool SawStore = false;
428 for (auto II = From.getIterator(); II != To.getIterator(); II++) {
429 for (Register PhysReg : PhysUses)
430 if (II->definesRegister(PhysReg, nullptr))
431 return false;
432 if (II->mayStore()) {
433 SawStore = true;
434 break;
435 }
436 }
437 return From.isSafeToMove(SawStore);
438}
439
440/// If a PseudoVMV_V_V is the only user of its input, fold its passthru and VL
441/// into it.
442///
443/// %x = PseudoVADD_V_V_M1 %passthru, %a, %b, %vl1, sew, policy
444/// %y = PseudoVMV_V_V_M1 %passthru, %x, %vl2, sew, policy
445/// (where %vl1 <= %vl2, see related tryToReduceVL)
446///
447/// ->
448///
449/// %y = PseudoVADD_V_V_M1 %passthru, %a, %b, vl1, sew, policy
450bool RISCVVectorPeephole::foldVMV_V_V(MachineInstr &MI) {
451 if (RISCV::getRVVMCOpcode(MI.getOpcode()) != RISCV::VMV_V_V)
452 return false;
453
454 MachineOperand &Passthru = MI.getOperand(1);
455
456 if (!MRI->hasOneUse(MI.getOperand(2).getReg()))
457 return false;
458
459 MachineInstr *Src = MRI->getVRegDef(MI.getOperand(2).getReg());
460 if (!Src || Src->hasUnmodeledSideEffects() ||
461 Src->getParent() != MI.getParent() || Src->getNumDefs() != 1 ||
462 !RISCVII::isFirstDefTiedToFirstUse(Src->getDesc()) ||
463 !RISCVII::hasVLOp(Src->getDesc().TSFlags) ||
464 !RISCVII::hasVecPolicyOp(Src->getDesc().TSFlags))
465 return false;
466
467 // Src needs to have the same VLMAX as MI
468 if (getSEWLMULRatio(MI) != getSEWLMULRatio(*Src))
469 return false;
470
471 // Src needs to have the same passthru as VMV_V_V
472 MachineOperand &SrcPassthru = Src->getOperand(1);
473 if (SrcPassthru.getReg() != RISCV::NoRegister &&
474 SrcPassthru.getReg() != Passthru.getReg())
475 return false;
476
477 // Src VL will have already been reduced if legal (see tryToReduceVL),
478 // so we don't need to handle a smaller source VL here. However, the
479 // user's VL may be larger
480 MachineOperand &SrcVL = Src->getOperand(RISCVII::getVLOpNum(Src->getDesc()));
481 if (!isVLKnownLE(SrcVL, MI.getOperand(3)))
482 return false;
483
484 // If Src ends up using MI's passthru/VL, move it so it can access it.
485 // TODO: We don't need to do this if they already dominate Src.
486 if (!SrcPassthru.isIdenticalTo(Passthru)) {
487 if (!isSafeToMove(*Src, MI))
488 return false;
489 Src->moveBefore(&MI);
490 }
491
492 if (SrcPassthru.getReg() != Passthru.getReg()) {
493 SrcPassthru.setReg(Passthru.getReg());
494 // If Src is masked then its passthru needs to be in VRNoV0.
495 if (Passthru.getReg() != RISCV::NoRegister)
496 MRI->constrainRegClass(Passthru.getReg(),
497 TII->getRegClass(Src->getDesc(), 1, TRI,
498 *Src->getParent()->getParent()));
499 }
500
501 // Use a conservative tu,mu policy, RISCVInsertVSETVLI will relax it if
502 // passthru is undef.
503 Src->getOperand(RISCVII::getVecPolicyOpNum(Src->getDesc()))
505
506 MRI->replaceRegWith(MI.getOperand(0).getReg(), Src->getOperand(0).getReg());
507 MI.eraseFromParent();
508 V0Defs.erase(&MI);
509
510 return true;
511}
512
513bool RISCVVectorPeephole::runOnMachineFunction(MachineFunction &MF) {
514 if (skipFunction(MF.getFunction()))
515 return false;
516
517 // Skip if the vector extension is not enabled.
519 if (!ST->hasVInstructions())
520 return false;
521
522 TII = ST->getInstrInfo();
523 MRI = &MF.getRegInfo();
524 TRI = MRI->getTargetRegisterInfo();
525
526 bool Changed = false;
527
528 // Masked pseudos coming out of isel will have their mask operand in the form:
529 //
530 // $v0:vr = COPY %mask:vr
531 // %x:vr = Pseudo_MASK %a:vr, %b:br, $v0:vr
532 //
533 // Because $v0 isn't in SSA, keep track of its definition at each use so we
534 // can check mask operands.
535 for (const MachineBasicBlock &MBB : MF) {
536 const MachineInstr *CurrentV0Def = nullptr;
537 for (const MachineInstr &MI : MBB) {
538 if (MI.readsRegister(RISCV::V0, TRI))
539 V0Defs[&MI] = CurrentV0Def;
540
541 if (MI.definesRegister(RISCV::V0, TRI))
542 CurrentV0Def = &MI;
543 }
544 }
545
546 for (MachineBasicBlock &MBB : MF) {
548 Changed |= convertToVLMAX(MI);
549 Changed |= tryToReduceVL(MI);
550 Changed |= convertToUnmasked(MI);
551 Changed |= convertToWholeRegister(MI);
552 Changed |= convertVMergeToVMv(MI);
553 Changed |= foldVMV_V_V(MI);
554 }
555 }
556
557 return Changed;
558}
559
561 return new RISCVVectorPeephole();
562}
unsigned const MachineRegisterInfo * MRI
aarch64 promote const
MachineBasicBlock & MBB
static uint64_t getConstant(const Value *IndexValue)
basic Basic Alias true
BlockVerifier::State From
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
static unsigned getSEWLMULRatio(const MachineInstr &MI)
if(RHS.isImm() &&RHS.getImm()==RISCV::VLMaxSentinel) return true
#define CASE_WHOLE_REGISTER_LMUL(lmul)
const MachineOperand & RHS
#define CASE_VMERGE_TO_VMV(lmul)
return LHS getImm()<
static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To)
Check if it's safe to move From down to To, checking that no physical registers are clobbered.
#define DEBUG_TYPE
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
Value * LHS
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
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:569
bool isCopy() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:346
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:579
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
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.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
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
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
Definition: ilist_node.h:132
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
@ TAIL_UNDISTURBED_MASK_UNDISTURBED
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static VLMUL getLMul(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool activeElementsAffectResult(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
static constexpr int64_t VLMaxSentinel
NodeAddr< DefNode * > Def
Definition: RDFGraph.h:384
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:656
unsigned M1(unsigned Val)
Definition: VE.h:376
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FunctionPass * createRISCVVectorPeepholePass()