LLVM 24.0.0git
RISCVInsertVSETVLI.cpp
Go to the documentation of this file.
1//===- RISCVInsertVSETVLI.cpp - Insert VSETVLI instructions ---------------===//
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 file implements a function pass that inserts VSETVLI instructions where
10// needed and expands the vl outputs of VLEFF/VLSEGFF to PseudoReadVL
11// instructions.
12//
13// This pass consists of 3 phases:
14//
15// Phase 1 collects how each basic block affects VL/VTYPE.
16//
17// Phase 2 uses the information from phase 1 to do a data flow analysis to
18// propagate the VL/VTYPE changes through the function. This gives us the
19// VL/VTYPE at the start of each basic block.
20//
21// Phase 3 inserts VSETVLI instructions in each basic block. Information from
22// phase 2 is used to prevent inserting a VSETVLI before the first vector
23// instruction in the block if possible.
24//
25//===----------------------------------------------------------------------===//
26
27#include "RISCV.h"
28#include "RISCVSubtarget.h"
31#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Analysis.h"
40#include <queue>
41using namespace llvm;
42using namespace RISCV;
43
44#define DEBUG_TYPE "riscv-insert-vsetvli"
45#define RISCV_INSERT_VSETVLI_NAME "RISC-V Insert VSETVLI pass"
46
47STATISTIC(NumInsertedVSETVL, "Number of VSETVL inst inserted");
48STATISTIC(NumCoalescedVSETVL, "Number of VSETVL inst coalesced");
49
50namespace {
51
52/// Given a virtual register \p Reg, return the corresponding VNInfo for it.
53/// This will return nullptr if the virtual register is an implicit_def or
54/// if LiveIntervals is not available.
56 const LiveIntervals *LIS) {
57 assert(Reg.isVirtual());
58 if (!LIS)
59 return nullptr;
60 auto &LI = LIS->getInterval(Reg);
62 return LI.getVNInfoBefore(SI);
63}
64
66 return MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
67}
68
69struct BlockData {
70 // The VSETVLIInfo that represents the VL/VTYPE settings on exit from this
71 // block. Calculated in Phase 2.
72 VSETVLIInfo Exit;
73
74 // The VSETVLIInfo that represents the VL/VTYPE settings from all predecessor
75 // blocks. Calculated in Phase 2, and used by Phase 3.
76 VSETVLIInfo Pred;
77
78 // Keeps track of whether the block is already in the queue.
79 bool InQueue = false;
80
81 BlockData() = default;
82};
83
84enum TKTMMode {
85 VSETTK = 0,
86 VSETTM = 1,
87};
88
89class RISCVInsertVSETVLILegacy : public MachineFunctionPass {
90public:
91 static char ID;
92
93 RISCVInsertVSETVLILegacy() : MachineFunctionPass(ID) {}
94 bool runOnMachineFunction(MachineFunction &MF) override;
95
96 void getAnalysisUsage(AnalysisUsage &AU) const override {
97 AU.setPreservesCFG();
98
99 AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
100 AU.addPreserved<LiveIntervalsWrapperPass>();
101 AU.addPreserved<SlotIndexesWrapperPass>();
102 AU.addPreserved<LiveDebugVariablesWrapperLegacy>();
103 AU.addPreserved<LiveStacksWrapperLegacy>();
104
106 }
107
108 StringRef getPassName() const override { return RISCV_INSERT_VSETVLI_NAME; }
109};
110
111class RISCVInsertVSETVLIImpl {
112 const RISCVSubtarget *ST;
113 const TargetInstrInfo *TII;
114 MachineRegisterInfo *MRI;
115 // Possibly null!
116 LiveIntervals *LIS;
117 RISCVVSETVLIInfoAnalysis VIA;
118
119 std::vector<BlockData> BlockInfo;
120 std::queue<const MachineBasicBlock *> WorkList;
121
122 bool needVSETVLI(const DemandedFields &Used, const VSETVLIInfo &Require,
123 const VSETVLIInfo &CurInfo) const;
124 bool needVSETVLIPHI(const VSETVLIInfo &Require,
125 const MachineBasicBlock &MBB) const;
126 void insertVSETVLI(MachineBasicBlock &MBB,
128 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo);
129
130 void transferBefore(VSETVLIInfo &Info, const MachineInstr &MI) const;
131 void transferAfter(VSETVLIInfo &Info, const MachineInstr &MI) const;
132 bool computeVLVTYPEChanges(const MachineBasicBlock &MBB,
133 VSETVLIInfo &Info) const;
134 void computeIncomingVLVTYPE(const MachineBasicBlock &MBB);
135 void emitVSETVLIs(MachineBasicBlock &MBB);
136 void doPRE(MachineBasicBlock &MBB);
137 void insertReadVL(MachineBasicBlock &MBB);
138
139 bool canMutatePriorConfig(const MachineInstr &PrevMI, const MachineInstr &MI,
140 const DemandedFields &Used,
141 MachineInstr *&AVLDefToMove) const;
142 void coalesceVSETVLIs(MachineBasicBlock &MBB) const;
143 bool canMutatePriorConfigWithTWiden(const MachineInstr &PrevMI,
144 const MachineInstr &MI) const;
145 void coalesceVSETVLIsForTWiden(MachineBasicBlock &MBB) const;
146 bool insertVSETMTK(MachineBasicBlock &MBB, TKTMMode Mode) const;
147
148public:
149 bool runOnMachineFunction(MachineFunction &MF, LiveIntervals *LISToUpdate);
150};
151
152} // end anonymous namespace
153
154char RISCVInsertVSETVLILegacy::ID = 0;
155char &llvm::RISCVInsertVSETVLILegacyID = RISCVInsertVSETVLILegacy::ID;
156
158 false, false)
159
160void RISCVInsertVSETVLIImpl::insertVSETVLI(MachineBasicBlock &MBB,
161 MachineBasicBlock::iterator InsertPt,
163 const VSETVLIInfo &PrevInfo) {
164 ++NumInsertedVSETVL;
165
166 if (PrevInfo.isKnown()) {
167 // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same
168 // VLMAX.
169 if (Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) {
170 auto MI = BuildMI(MBB, InsertPt, DL,
171 TII->get(Info.getTWiden() ? RISCV::PseudoSF_VSETTNTX0X0
172 : RISCV::PseudoVSETVLIX0X0))
173 .addDef(RISCV::X0, RegState::Dead)
174 .addReg(RISCV::X0, RegState::Kill)
175 .addImm(Info.encodeVTYPE())
176 .addReg(RISCV::VL, RegState::Implicit);
177 if (LIS)
178 LIS->InsertMachineInstrInMaps(*MI);
179 return;
180 }
181
182 // If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If
183 // it has the same VLMAX we want and the last VL/VTYPE we observed is the
184 // same, we can use the X0, X0 form.
185 if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
186 if (const MachineInstr *DefMI = Info.getAVLDefMI(LIS);
187 DefMI && RISCVInstrInfo::isVectorConfigInstr(*DefMI)) {
188 VSETVLIInfo DefInfo = VIA.getInfoForVSETVLI(*DefMI);
189 if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
190 auto MI =
191 BuildMI(MBB, InsertPt, DL,
192 TII->get(Info.getTWiden() ? RISCV::PseudoSF_VSETTNTX0X0
193 : RISCV::PseudoVSETVLIX0X0))
194 .addDef(RISCV::X0, RegState::Dead)
195 .addReg(RISCV::X0, RegState::Kill)
196 .addImm(Info.encodeVTYPE())
197 .addReg(RISCV::VL, RegState::Implicit);
198 if (LIS)
199 LIS->InsertMachineInstrInMaps(*MI);
200 return;
201 }
202 }
203 }
204 }
205
206 if (Info.hasAVLImm()) {
207 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI))
208 .addDef(RISCV::X0, RegState::Dead)
209 .addImm(Info.getAVLImm())
210 .addImm(Info.encodeVTYPE());
211 if (LIS)
212 LIS->InsertMachineInstrInMaps(*MI);
213 return;
214 }
215
216 if (Info.hasAVLVLMAX()) {
217 Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
218 auto MI = BuildMI(MBB, InsertPt, DL,
219 TII->get(Info.getTWiden() ? RISCV::PseudoSF_VSETTNTX0
220 : RISCV::PseudoVSETVLIX0))
221 .addDef(DestReg, RegState::Dead)
222 .addReg(RISCV::X0, RegState::Kill)
223 .addImm(Info.encodeVTYPE());
224 if (LIS) {
225 LIS->InsertMachineInstrInMaps(*MI);
226 LIS->createAndComputeVirtRegInterval(DestReg);
227 }
228 return;
229 }
230
231 Register AVLReg = Info.getAVLReg();
232 MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass);
233 auto MI = BuildMI(MBB, InsertPt, DL,
234 TII->get(Info.getTWiden() ? RISCV::PseudoSF_VSETTNT
235 : RISCV::PseudoVSETVLI))
236 .addDef(RISCV::X0, RegState::Dead)
237 .addReg(AVLReg)
238 .addImm(Info.encodeVTYPE());
239 if (LIS) {
241 LiveInterval &LI = LIS->getInterval(AVLReg);
243 const VNInfo *CurVNI = Info.getAVLVNInfo();
244 // If the AVL value isn't live at MI, do a quick check to see if it's easily
245 // extendable. Otherwise, we need to copy it.
246 if (LI.getVNInfoBefore(SI) != CurVNI) {
247 if (!LI.liveAt(SI) && LI.containsOneValue())
248 LIS->extendToIndices(LI, SI);
249 else {
250 Register AVLCopyReg =
251 MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
252 MachineBasicBlock *MBB = LIS->getMBBFromIndex(CurVNI->def);
254 if (CurVNI->isPHIDef())
255 II = MBB->getFirstNonPHI();
256 else {
257 II = LIS->getInstructionFromIndex(CurVNI->def);
258 II = std::next(II);
259 }
260 assert(II.isValid());
261 auto AVLCopy = BuildMI(*MBB, II, DL, TII->get(RISCV::COPY), AVLCopyReg)
262 .addReg(AVLReg);
263 LIS->InsertMachineInstrInMaps(*AVLCopy);
264 MI->getOperand(1).setReg(AVLCopyReg);
265 LIS->createAndComputeVirtRegInterval(AVLCopyReg);
266 }
267 }
268 }
269}
270
271/// Return true if a VSETVLI is required to transition from CurInfo to Require
272/// given a set of DemandedFields \p Used.
273bool RISCVInsertVSETVLIImpl::needVSETVLI(const DemandedFields &Used,
274 const VSETVLIInfo &Require,
275 const VSETVLIInfo &CurInfo) const {
276 if (!CurInfo.isKnown() || CurInfo.hasSEWLMULRatioOnly())
277 return true;
278
279 if (CurInfo.isCompatible(Used, Require, LIS))
280 return false;
281
282 return true;
283}
284
285// If we don't use LMUL or the SEW/LMUL ratio, then adjust LMUL so that we
286// maintain the SEW/LMUL ratio. This allows us to eliminate VL toggles in more
287// places.
289 const VSETVLIInfo &NewInfo,
290 DemandedFields &Demanded) {
291 VSETVLIInfo Info = NewInfo;
292
293 if (!Demanded.LMUL && !Demanded.SEWLMULRatio && PrevInfo.isKnown()) {
294 if (auto NewVLMul = RISCVVType::getSameRatioLMUL(PrevInfo.getSEWLMULRatio(),
295 Info.getSEW()))
296 Info.setVLMul(*NewVLMul);
298 }
299
300 return Info;
301}
302
303// Given an incoming state reaching MI, minimally modifies that state so that it
304// is compatible with MI. The resulting state is guaranteed to be semantically
305// legal for MI, but may not be the state requested by MI.
306void RISCVInsertVSETVLIImpl::transferBefore(VSETVLIInfo &Info,
307 const MachineInstr &MI) const {
308 if (ST->getCLOpts().insert_vsetvli_whole_vector_register_move_valid_vtype &&
310 (!Info.isKnown() || Info.hasSEWLMULRatioOnly())) {
311 // Use an arbitrary but valid AVL and VTYPE so vill will be cleared. It may
312 // be coalesced into another vsetvli since we won't demand any fields.
313 VSETVLIInfo NewInfo; // Need a new VSETVLIInfo to clear SEWLMULRatioOnly
314 NewInfo.setAVLImm(1);
315 NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true,
316 /*AltFmt*/ false, /*W*/ 0);
317 Info = NewInfo;
318 return;
319 }
320
321 if (!RISCVII::hasSEWOp(MI.getDesc().TSFlags))
322 return;
323
324 DemandedFields Demanded = getDemanded(MI, ST);
325
326 const VSETVLIInfo NewInfo = VIA.computeInfoForInstr(MI);
327 assert(NewInfo.isKnown());
328 if (Info.isValid() && !needVSETVLI(Demanded, NewInfo, Info))
329 return;
330
331 const VSETVLIInfo PrevInfo = Info;
332 if (!Info.isKnown())
333 Info = NewInfo;
334
335 const VSETVLIInfo IncomingInfo = adjustIncoming(PrevInfo, NewInfo, Demanded);
336
337 // If MI only demands that VL has the same zeroness, we only need to set the
338 // AVL if the zeroness differs. This removes a vsetvli entirely if the types
339 // match or allows use of cheaper avl preserving variant if VLMAX doesn't
340 // change. If VLMAX might change, we couldn't use the 'vsetvli x0, x0, vtype"
341 // variant, so we avoid the transform to prevent extending live range of an
342 // avl register operand.
343 // TODO: We can probably relax this for immediates.
344 bool EquallyZero = IncomingInfo.hasEquallyZeroAVL(PrevInfo, LIS) &&
345 IncomingInfo.hasSameVLMAX(PrevInfo);
346 if (Demanded.VLAny || (Demanded.VLZeroness && !EquallyZero))
347 Info.setAVL(IncomingInfo);
348
349 // If we only knew the sew/lmul ratio previously, replace the VTYPE.
350 if (Info.hasSEWLMULRatioOnly()) {
351 VSETVLIInfo RatiolessInfo = IncomingInfo;
352 RatiolessInfo.setAVL(Info);
353 Info = RatiolessInfo;
354 } else {
355 unsigned SEW =
356 ((Demanded.SEW || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
357 .getSEW();
358 Info.setVTYPE(
359 ((Demanded.LMUL || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
360 .getVLMUL(),
361 SEW,
362 // Prefer tail/mask agnostic since it can be relaxed to undisturbed
363 // later if needed.
364 (Demanded.TailPolicy ? IncomingInfo : Info).getTailAgnostic() ||
365 IncomingInfo.getTailAgnostic(),
366 (Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
367 IncomingInfo.getMaskAgnostic(),
368 // AltFmt requires SEW < 32.
369 (Demanded.AltFmt ? IncomingInfo : Info).getAltFmt() && SEW < 32,
370 Demanded.TWiden ? IncomingInfo.getTWiden() : 0);
371 }
372}
373
374// Given a state with which we evaluated MI (see transferBefore above for why
375// this might be different that the state MI requested), modify the state to
376// reflect the changes MI might make.
377void RISCVInsertVSETVLIImpl::transferAfter(VSETVLIInfo &Info,
378 const MachineInstr &MI) const {
379 if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
381 return;
382 }
383
384 // SETTM/TK will modify VTYPE, but it only affects the TM/TK bits.
385 // It is safe for other RVV operations.
386 // The TM/TK value will be maintained in insertVSETMTK.
387 if (RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(MI))
388 return;
389
390 if (RISCVInstrInfo::isFaultOnlyFirstLoad(MI)) {
391 // Update AVL to vl-output of the fault first load.
392 assert(MI.getOperand(1).getReg().isVirtual());
393 if (LIS) {
394 auto &LI = LIS->getInterval(MI.getOperand(1).getReg());
395 SlotIndex SI =
397 VNInfo *VNI = LI.getVNInfoAt(SI);
398 Info.setAVLRegDef(VNI, MI.getOperand(1).getReg());
399 } else
400 Info.setAVLRegDef(nullptr, MI.getOperand(1).getReg());
401 return;
402 }
403
404 // If this is something that updates VL/VTYPE that we don't know about, set
405 // the state to unknown.
406 if (MI.isCall() || MI.isInlineAsm() ||
407 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
408 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
410}
411
412bool RISCVInsertVSETVLIImpl::computeVLVTYPEChanges(const MachineBasicBlock &MBB,
413 VSETVLIInfo &Info) const {
414 bool HadVectorOp = false;
415
416 Info = BlockInfo[MBB.getNumber()].Pred;
417 for (const MachineInstr &MI : MBB) {
418 transferBefore(Info, MI);
419
420 if (RISCVInstrInfo::isVectorConfigInstr(MI) ||
421 RISCVII::hasSEWOp(MI.getDesc().TSFlags) ||
423 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI))
424 HadVectorOp = true;
425
426 transferAfter(Info, MI);
427 }
428
429 return HadVectorOp;
430}
431
432void RISCVInsertVSETVLIImpl::computeIncomingVLVTYPE(
433 const MachineBasicBlock &MBB) {
434
435 BlockData &BBInfo = BlockInfo[MBB.getNumber()];
436
437 BBInfo.InQueue = false;
438
439 // Start with the previous entry so that we keep the most conservative state
440 // we have ever found.
441 VSETVLIInfo InInfo = BBInfo.Pred;
442 if (MBB.pred_empty()) {
443 // There are no predecessors, so use the default starting status.
444 InInfo.setUnknown();
445 } else {
446 for (MachineBasicBlock *P : MBB.predecessors())
447 InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit);
448 }
449
450 // If we don't have any valid predecessor value, wait until we do.
451 if (!InInfo.isValid())
452 return;
453
454 // If no change, no need to rerun block
455 if (InInfo == BBInfo.Pred)
456 return;
457
458 BBInfo.Pred = InInfo;
459 LLVM_DEBUG(dbgs() << "Entry state of " << printMBBReference(MBB)
460 << " changed to " << BBInfo.Pred << "\n");
461
462 // Note: It's tempting to cache the state changes here, but due to the
463 // compatibility checks performed a blocks output state can change based on
464 // the input state. To cache, we'd have to add logic for finding
465 // never-compatible state changes.
466 VSETVLIInfo TmpStatus;
467 computeVLVTYPEChanges(MBB, TmpStatus);
468
469 // If the new exit value matches the old exit value, we don't need to revisit
470 // any blocks.
471 if (BBInfo.Exit == TmpStatus)
472 return;
473
474 BBInfo.Exit = TmpStatus;
475 LLVM_DEBUG(dbgs() << "Exit state of " << printMBBReference(MBB)
476 << " changed to " << BBInfo.Exit << "\n");
477
478 // Add the successors to the work list so we can propagate the changed exit
479 // status.
480 for (MachineBasicBlock *S : MBB.successors())
481 if (!BlockInfo[S->getNumber()].InQueue) {
482 BlockInfo[S->getNumber()].InQueue = true;
483 WorkList.push(S);
484 }
485}
486
487// If we weren't able to prove a vsetvli was directly unneeded, it might still
488// be unneeded if the AVL was a phi node where all incoming values are VL
489// outputs from the last VSETVLI in their respective basic blocks.
490bool RISCVInsertVSETVLIImpl::needVSETVLIPHI(
491 const VSETVLIInfo &Require, const MachineBasicBlock &MBB) const {
492 if (!Require.hasAVLReg())
493 return true;
494
495 if (!LIS)
496 return true;
497
498 // We need the AVL to have been produced by a PHI node in this basic block.
499 const VNInfo *Valno = Require.getAVLVNInfo();
500 if (!Valno->isPHIDef() || LIS->getMBBFromIndex(Valno->def) != &MBB)
501 return true;
502
503 const LiveRange &LR = LIS->getInterval(Require.getAVLReg());
504
505 for (auto *PBB : MBB.predecessors()) {
506 const VSETVLIInfo &PBBExit = BlockInfo[PBB->getNumber()].Exit;
507
508 // We need the PHI input to the be the output of a VSET(I)VLI.
509 const VNInfo *Value = LR.getVNInfoBefore(LIS->getMBBEndIdx(PBB));
510 if (!Value)
511 return true;
512 MachineInstr *DefMI = LIS->getInstructionFromIndex(Value->def);
513 if (!DefMI || !RISCVInstrInfo::isVectorConfigInstr(*DefMI))
514 return true;
515
516 // We found a VSET(I)VLI make sure it matches the output of the
517 // predecessor block.
518 VSETVLIInfo DefInfo = VIA.getInfoForVSETVLI(*DefMI);
519 if (DefInfo != PBBExit)
520 return true;
521
522 // Require has the same VL as PBBExit, so if the exit from the
523 // predecessor has the VTYPE we are looking for we might be able
524 // to avoid a VSETVLI.
525 if (PBBExit.isUnknown() || !PBBExit.hasSameVTYPE(Require))
526 return true;
527 }
528
529 // If all the incoming values to the PHI checked out, we don't need
530 // to insert a VSETVLI.
531 return false;
532}
533
534void RISCVInsertVSETVLIImpl::emitVSETVLIs(MachineBasicBlock &MBB) {
535 VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred;
536 // Track whether the prefix of the block we've scanned is transparent
537 // (meaning has not yet changed the abstract state).
538 bool PrefixTransparent = true;
539 for (MachineInstr &MI : MBB) {
540 const VSETVLIInfo PrevInfo = CurInfo;
541 transferBefore(CurInfo, MI);
542
543 // If this is an explicit VSETVLI or VSETIVLI, update our state.
544 if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
545 // Conservatively, mark the VL and VTYPE as live.
546 assert(MI.getOperand(3).getReg() == RISCV::VL &&
547 MI.getOperand(4).getReg() == RISCV::VTYPE &&
548 "Unexpected operands where VL and VTYPE should be");
549
550 if (LIS) {
551 // Clearing a dead flag extends that def past its previous dead-def
552 // slot, so the stale VL/VTYPE range must be dropped.
553 if (MI.getOperand(3).isDead())
554 LIS->removeAllRegUnitsForPhysReg(RISCV::VL);
555 if (MI.getOperand(4).isDead())
556 LIS->removeAllRegUnitsForPhysReg(RISCV::VTYPE);
557 }
558
559 MI.getOperand(3).setIsDead(false);
560 MI.getOperand(4).setIsDead(false);
561 PrefixTransparent = false;
562 }
563
564 if (ST->getCLOpts().insert_vsetvli_whole_vector_register_move_valid_vtype &&
566 if (!PrevInfo.isCompatible(DemandedFields::all(), CurInfo, LIS)) {
567 insertVSETVLI(MBB, MI, MI.getDebugLoc(), CurInfo, PrevInfo);
568 PrefixTransparent = false;
569 }
570 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
571 /*isImp*/ true));
572 }
573
574 uint64_t TSFlags = MI.getDesc().TSFlags;
575 if (RISCVII::hasSEWOp(TSFlags)) {
576 if (!PrevInfo.isCompatible(DemandedFields::all(), CurInfo, LIS)) {
577 // If this is the first implicit state change, and the state change
578 // requested can be proven to produce the same register contents, we
579 // can skip emitting the actual state change and continue as if we
580 // had since we know the GPR result of the implicit state change
581 // wouldn't be used and VL/VTYPE registers are correct. Note that
582 // we *do* need to model the state as if it changed as while the
583 // register contents are unchanged, the abstract model can change.
584 if (!PrefixTransparent || needVSETVLIPHI(CurInfo, MBB))
585 insertVSETVLI(MBB, MI, MI.getDebugLoc(), CurInfo, PrevInfo);
586 PrefixTransparent = false;
587 }
588
589 if (RISCVII::hasVLOp(TSFlags)) {
590 MachineOperand &VLOp = getVLOp(MI);
591 if (VLOp.isReg()) {
592 Register Reg = VLOp.getReg();
593
594 // Erase the AVL operand from the instruction.
595 VLOp.setReg(Register());
596 VLOp.setIsKill(false);
597 if (LIS) {
598 LiveInterval &LI = LIS->getInterval(Reg);
600 LIS->shrinkToUses(&LI, &DeadMIs);
601 // We might have separate components that need split due to
602 // needVSETVLIPHI causing us to skip inserting a new VL def.
604 LIS->splitSeparateComponents(LI, SplitLIs);
605
606 // If the AVL was an immediate > 31, then it would have been emitted
607 // as an ADDI. However, the ADDI might not have been used in the
608 // vsetvli, or a vsetvli might not have been emitted, so it may be
609 // dead now.
610 for (MachineInstr *DeadMI : DeadMIs) {
611 if (!TII->isAddImmediate(*DeadMI, Reg))
612 continue;
613 LIS->RemoveMachineInstrFromMaps(*DeadMI);
614 Register AddReg = DeadMI->getOperand(1).getReg();
615 DeadMI->eraseFromParent();
616 if (AddReg.isVirtual())
617 LIS->shrinkToUses(&LIS->getInterval(AddReg));
618 }
619 }
620 }
621 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false,
622 /*isImp*/ true));
623 }
624 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
625 /*isImp*/ true));
626 }
627
628 if (MI.isInlineAsm()) {
629 MI.addRegisterDefined(RISCV::VL, /*RegInfo=*/nullptr);
630 MI.addRegisterDefined(RISCV::VTYPE, /*RegInfo=*/nullptr);
631 }
632
633 if (MI.isCall() || MI.isInlineAsm() ||
634 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
635 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
636 PrefixTransparent = false;
637
638 transferAfter(CurInfo, MI);
639 }
640
641 const auto &Info = BlockInfo[MBB.getNumber()];
642 if (CurInfo != Info.Exit) {
643 LLVM_DEBUG(dbgs() << "in block " << printMBBReference(MBB) << "\n");
644 LLVM_DEBUG(dbgs() << " begin state: " << Info.Pred << "\n");
645 LLVM_DEBUG(dbgs() << " expected end state: " << Info.Exit << "\n");
646 LLVM_DEBUG(dbgs() << " actual end state: " << CurInfo << "\n");
647 }
648 assert(CurInfo == Info.Exit && "InsertVSETVLI dataflow invariant violated");
649}
650
651/// Perform simple partial redundancy elimination of the VSETVLI instructions
652/// we're about to insert by looking for cases where we can PRE from the
653/// beginning of one block to the end of one of its predecessors. Specifically,
654/// this is geared to catch the common case of a fixed length vsetvl in a single
655/// block loop when it could execute once in the preheader instead.
656void RISCVInsertVSETVLIImpl::doPRE(MachineBasicBlock &MBB) {
657 if (!BlockInfo[MBB.getNumber()].Pred.isUnknown())
658 return;
659
660 MachineBasicBlock *UnavailablePred = nullptr;
661 VSETVLIInfo AvailableInfo;
662 for (MachineBasicBlock *P : MBB.predecessors()) {
663 const VSETVLIInfo &PredInfo = BlockInfo[P->getNumber()].Exit;
664 if (PredInfo.isUnknown()) {
665 if (UnavailablePred)
666 return;
667 UnavailablePred = P;
668 } else if (!AvailableInfo.isValid()) {
669 AvailableInfo = PredInfo;
670 } else if (AvailableInfo != PredInfo) {
671 return;
672 }
673 }
674
675 // Unreachable, single pred, or full redundancy. Note that FRE is handled by
676 // phase 3.
677 if (!UnavailablePred || !AvailableInfo.isValid())
678 return;
679
680 if (!LIS)
681 return;
682
683 // If we don't know the exact VTYPE, we can't copy the vsetvli to the exit of
684 // the unavailable pred.
685 if (AvailableInfo.hasSEWLMULRatioOnly())
686 return;
687
688 // Critical edge - TODO: consider splitting?
689 if (UnavailablePred->succ_size() != 1)
690 return;
691
692 // If the AVL value is a register (other than our VLMAX sentinel),
693 // we need to prove the value is available at the point we're going
694 // to insert the vsetvli at.
695 if (AvailableInfo.hasAVLReg()) {
696 SlotIndex SI = AvailableInfo.getAVLVNInfo()->def;
697 // This is an inline dominance check which covers the case of
698 // UnavailablePred being the preheader of a loop.
699 if (LIS->getMBBFromIndex(SI) != UnavailablePred)
700 return;
701 if (!UnavailablePred->terminators().empty() &&
702 SI >= LIS->getInstructionIndex(*UnavailablePred->getFirstTerminator()))
703 return;
704 }
705
706 // Model the effect of changing the input state of the block MBB to
707 // AvailableInfo. We're looking for two issues here; one legality,
708 // one profitability.
709 // 1) If the block doesn't use some of the fields from VL or VTYPE, we
710 // may hit the end of the block with a different end state. We can
711 // not make this change without reflowing later blocks as well.
712 // 2) If we don't actually remove a transition, inserting a vsetvli
713 // into the predecessor block would be correct, but unprofitable.
714 VSETVLIInfo OldInfo = BlockInfo[MBB.getNumber()].Pred;
715 VSETVLIInfo CurInfo = AvailableInfo;
716 int TransitionsRemoved = 0;
717 for (const MachineInstr &MI : MBB) {
718 const VSETVLIInfo LastInfo = CurInfo;
719 const VSETVLIInfo LastOldInfo = OldInfo;
720 transferBefore(CurInfo, MI);
721 transferBefore(OldInfo, MI);
722 if (CurInfo == LastInfo)
723 TransitionsRemoved++;
724 if (LastOldInfo == OldInfo)
725 TransitionsRemoved--;
726 transferAfter(CurInfo, MI);
727 transferAfter(OldInfo, MI);
728 if (CurInfo == OldInfo)
729 // Convergence. All transitions after this must match by construction.
730 break;
731 }
732 if (CurInfo != OldInfo || TransitionsRemoved <= 0)
733 // Issues 1 and 2 above
734 return;
735
736 // Finally, update both data flow state and insert the actual vsetvli.
737 // Doing both keeps the code in sync with the dataflow results, which
738 // is critical for correctness of phase 3.
739 auto OldExit = BlockInfo[UnavailablePred->getNumber()].Exit;
740 LLVM_DEBUG(dbgs() << "PRE VSETVLI from " << MBB.getName() << " to "
741 << UnavailablePred->getName() << " with state "
742 << AvailableInfo << "\n");
743 BlockInfo[UnavailablePred->getNumber()].Exit = AvailableInfo;
744 BlockInfo[MBB.getNumber()].Pred = AvailableInfo;
745
746 // Note there's an implicit assumption here that terminators never use
747 // or modify VL or VTYPE. Also, fallthrough will return end().
748 auto InsertPt = UnavailablePred->getFirstInstrTerminator();
749 insertVSETVLI(*UnavailablePred, InsertPt,
750 UnavailablePred->findDebugLoc(InsertPt),
751 AvailableInfo, OldExit);
752}
753
754// Return true if we can mutate PrevMI to match MI without changing any the
755// fields which would be observed.
756// If AVLDefToMove is non-null after the call, it points to an ADDI
757// instruction that needs to be moved before PrevMI.
758bool RISCVInsertVSETVLIImpl::canMutatePriorConfig(
759 const MachineInstr &PrevMI, const MachineInstr &MI,
760 const DemandedFields &Used, MachineInstr *&AVLDefToMove) const {
761 AVLDefToMove = nullptr;
762 // If the VL values aren't equal, return false if either a) the former is
763 // demanded, or b) we can't rewrite the former to be the later for
764 // implementation reasons.
765 if (!RISCVInstrInfo::isVLPreservingConfig(MI)) {
766 if (Used.VLAny)
767 return false;
768
769 if (Used.VLZeroness) {
770 if (RISCVInstrInfo::isVLPreservingConfig(PrevMI))
771 return false;
772 if (!VIA.getInfoForVSETVLI(PrevMI).hasEquallyZeroAVL(
773 VIA.getInfoForVSETVLI(MI), LIS))
774 return false;
775 }
776
777 auto &AVL = MI.getOperand(1);
778
779 // If the AVL is a register, we need to make sure its definition is the same
780 // at PrevMI as it was at MI.
781 if (AVL.isReg() && AVL.getReg() != RISCV::X0) {
782 VNInfo *VNI = getVNInfoFromReg(AVL.getReg(), MI, LIS);
783 VNInfo *PrevVNI = getVNInfoFromReg(AVL.getReg(), PrevMI, LIS);
784 if (!VNI || !PrevVNI || VNI != PrevVNI) {
785 // If LIS is null, we were not able to get the VNInfo so we don't know
786 // if the AVL def needs to be moved.
787 if (!LIS)
788 return false;
789 // If the AVL is defined by a load immediate instruction (ADDI x0, imm),
790 // it can be moved earlier since it has no register dependencies.
791 if (!AVL.getReg().isVirtual())
792 return false;
793
794 MachineInstr *DefMI = MRI->getUniqueVRegDef(AVL.getReg());
795 if (!DefMI || !RISCVInstrInfo::isLoadImmediate(*DefMI) ||
796 DefMI->getParent() != PrevMI.getParent()) {
797 return false;
798 }
799 // Mark that this ADDI needs to be moved.
800 AVLDefToMove = DefMI;
801 }
802 }
803
804 // If we define VL and need to move the definition up, check we can extend
805 // the live interval upwards from MI to PrevMI.
806 Register VL = MI.getOperand(0).getReg();
807 if (VL.isVirtual() && LIS &&
808 LIS->getInterval(VL).overlaps(LIS->getInstructionIndex(PrevMI),
809 LIS->getInstructionIndex(MI)))
810 return false;
811 }
812
813 assert(PrevMI.getOperand(2).isImm() && MI.getOperand(2).isImm());
814 auto PriorVType = PrevMI.getOperand(2).getImm();
815 auto VType = MI.getOperand(2).getImm();
816 return areCompatibleVTYPEs(PriorVType, VType, Used);
817}
818
819void RISCVInsertVSETVLIImpl::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
820 MachineInstr *NextMI = nullptr;
821 // We can have arbitrary code in successors, so VL and VTYPE
822 // must be considered demanded.
823 DemandedFields Used;
824 Used.demandVL();
825 Used.demandVTYPE();
827
828 auto dropAVLUse = [&](MachineOperand &MO) {
829 if (!MO.isReg() || !MO.getReg().isVirtual())
830 return;
831 Register OldVLReg = MO.getReg();
832 MO.setReg(Register());
833
834 if (LIS)
835 LIS->shrinkToUses(&LIS->getInterval(OldVLReg));
836
837 MachineInstr *VLOpDef = MRI->getUniqueVRegDef(OldVLReg);
838 if (VLOpDef && TII->isAddImmediate(*VLOpDef, OldVLReg) &&
839 MRI->use_nodbg_empty(OldVLReg))
840 ToDelete.push_back(VLOpDef);
841 };
842
843 for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) {
844 // TODO: Support XSfmm.
845 if (RISCVII::hasTWidenOp(MI.getDesc().TSFlags) ||
846 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI)) {
847 NextMI = nullptr;
848 continue;
849 }
850
851 if (!RISCVInstrInfo::isVectorConfigInstr(MI)) {
852 Used.doUnion(getDemanded(MI, ST));
853 if (MI.isCall() || MI.isInlineAsm() ||
854 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
855 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
856 NextMI = nullptr;
857 continue;
858 }
859
860 if (!MI.getOperand(0).isDead())
861 Used.demandVL();
862
863 if (NextMI) {
864 if (!Used.usedVL() && !Used.usedVTYPE()) {
865 dropAVLUse(MI.getOperand(1));
866 if (LIS)
868 MI.eraseFromParent();
869 NumCoalescedVSETVL++;
870 // Leave NextMI unchanged
871 continue;
872 }
873
874 MachineInstr *AVLDefToMove = nullptr;
875 if (canMutatePriorConfig(MI, *NextMI, Used, AVLDefToMove)) {
876 if (!RISCVInstrInfo::isVLPreservingConfig(*NextMI)) {
877 Register DefReg = NextMI->getOperand(0).getReg();
878
879 MI.getOperand(0).setReg(DefReg);
880 MI.getOperand(0).setIsDead(false);
881
882 // Move the AVL from NextMI to MI
883 dropAVLUse(MI.getOperand(1));
884 if (NextMI->getOperand(1).isImm())
885 MI.getOperand(1).ChangeToImmediate(NextMI->getOperand(1).getImm());
886 else {
887 MI.getOperand(1).ChangeToRegister(NextMI->getOperand(1).getReg(),
888 false);
889
890 // If canMutatePriorConfig indicated that an ADDI needs to be moved,
891 // move it now.
892 if (AVLDefToMove) {
893 AVLDefToMove->moveBefore(&MI);
894 if (LIS)
895 LIS->handleMove(*AVLDefToMove);
896 }
897 }
898 dropAVLUse(NextMI->getOperand(1));
899
900 // The def of DefReg moved to MI, so extend the LiveInterval up to
901 // it.
902 if (DefReg.isVirtual() && LIS) {
903 LiveInterval &DefLI = LIS->getInterval(DefReg);
904 SlotIndex MISlot = LIS->getInstructionIndex(MI).getRegSlot();
905 SlotIndex NextMISlot =
906 LIS->getInstructionIndex(*NextMI).getRegSlot();
907 VNInfo *DefVNI = DefLI.getVNInfoAt(NextMISlot);
908 LiveInterval::Segment S(MISlot, NextMISlot, DefVNI);
909 DefLI.addSegment(S);
910 DefVNI->def = MISlot;
911 // Mark DefLI as spillable if it was previously unspillable
912 DefLI.setWeight(0);
913
914 // DefReg may have had no uses, in which case we need to shrink
915 // the LiveInterval up to MI.
916 LIS->shrinkToUses(&DefLI);
917 }
918
919 MI.setDesc(NextMI->getDesc());
920 }
921 MI.getOperand(2).setImm(NextMI->getOperand(2).getImm());
922
923 dropAVLUse(NextMI->getOperand(1));
924 if (LIS)
925 LIS->RemoveMachineInstrFromMaps(*NextMI);
926 NextMI->eraseFromParent();
927 NumCoalescedVSETVL++;
928 // fallthrough
929 }
930 }
931 NextMI = &MI;
932 Used = getDemanded(MI, ST);
933 }
934
935 // Loop over the dead AVL values, and delete them now. This has
936 // to be outside the above loop to avoid invalidating iterators.
937 for (auto *MI : ToDelete) {
938 assert(MI->getOpcode() == RISCV::ADDI);
939 Register AddReg = MI->getOperand(1).getReg();
940 if (LIS) {
941 LIS->removeInterval(MI->getOperand(0).getReg());
943 }
944 MI->eraseFromParent();
945 if (LIS && AddReg.isVirtual())
946 LIS->shrinkToUses(&LIS->getInterval(AddReg));
947 }
948}
949
950// When twiden != 0, LMUL, tail policy, and mask policy from the user are
951// ignored. The tail policy and mask policy are always treated as agnostic. The
952// normal RVV instruction will ignore the twiden parameter. This observation
953// could allow the RVV instruction and xsfmm instruction to share the same
954// configuration instruction.
955//
956// We need to make sure the AVL, SEW, and AltFmt is same between VSETVL and
957// VSETVLTN.
958//
959// For example:
960//
961// %avl = SETTM or SETTK
962// ...
963// VSETVL %avl, type1
964// VSETVLTNT %avl, type2
965//
966// ->
967//
968// %avl = SETTM or SETTK
969// ...
970// VSETVLTNT %avl, type2
971//
972bool RISCVInsertVSETVLIImpl::canMutatePriorConfigWithTWiden(
973 const MachineInstr &PrevMI, const MachineInstr &MI) const {
974
975 if (PrevMI.getOpcode() != RISCV::PseudoVSETVLI)
976 return false;
977
978 if (MI.getOpcode() != RISCV::PseudoSF_VSETTNT)
979 return false;
980
981 auto PrevInfo = VIA.getInfoForVSETVLI(PrevMI);
982 auto CurrInfo = VIA.getInfoForVSETVLI(MI);
983
984 assert(CurrInfo.hasAVLReg() && "Invalid PseudoSF_VSETTNT without an AVLReg.");
985
986 auto AVLReg = CurrInfo.getAVLReg();
987
988 auto *AVLRegDefMI = MRI->getUniqueVRegDef(AVLReg);
989
990 if (!AVLRegDefMI)
991 return false;
992
993 if (!RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(*AVLRegDefMI))
994 return false;
995
996 auto AVLRegDefMIInfo = VIA.computeInfoForInstr(*AVLRegDefMI);
997 if (AVLRegDefMIInfo.getTWiden() != CurrInfo.getTWiden())
998 return false;
999
1000 if (AVLRegDefMIInfo.getSEW() != PrevInfo.getSEW())
1001 return false;
1002
1003 // CurrInfo twiden != 0, so TailAgnostic and MaskAgnostic bit default to 1
1004 if (!PrevInfo.getTailAgnostic() || !PrevInfo.getMaskAgnostic())
1005 return false;
1006
1007 if (!PrevInfo.hasSameAVL(CurrInfo))
1008 return false;
1009
1010 if (PrevInfo.getSEW() != CurrInfo.getSEW())
1011 return false;
1012
1013 if (PrevInfo.getAltFmt() != CurrInfo.getAltFmt())
1014 return false;
1015
1016 // The PrevMI's LMUL should be at least 8/KMAX; otherwise, converting it to a
1017 // tile-widening version could result in a VLMAX smaller than what AVLRegDefMI
1018 // expects, causing the LMUL information from PrevMI to be lost.
1019 auto [LMul, Fractional] = decodeVLMUL(PrevInfo.getVLMUL());
1020 unsigned KMAX = (CurrInfo.getSEW() >= 32) ? 1 : (32 / CurrInfo.getSEW());
1021
1022 if (Fractional || LMul < (8 / KMAX))
1023 return false;
1024
1025 return true;
1026}
1027
1028void RISCVInsertVSETVLIImpl::coalesceVSETVLIsForTWiden(
1029 MachineBasicBlock &MBB) const {
1030 MachineInstr *NextMI = nullptr;
1031
1032 for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) {
1033
1034 if (!RISCVInstrInfo::isVectorConfigInstr(MI))
1035 continue;
1036
1037 if (NextMI) {
1038 // If only TWiden different. Update the MI and drop the NextMI.
1039 if (canMutatePriorConfigWithTWiden(MI, *NextMI)) {
1040
1041 auto NextInfo = VIA.getInfoForVSETVLI(*NextMI);
1042 MI.getOperand(2).setImm(NextInfo.encodeVTYPE());
1043
1044 if (LIS)
1045 LIS->RemoveMachineInstrFromMaps(*NextMI);
1046 NextMI->eraseFromParent();
1047 }
1048 }
1049 NextMI = &MI;
1050 }
1051}
1052
1053void RISCVInsertVSETVLIImpl::insertReadVL(MachineBasicBlock &MBB) {
1054 for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
1055 MachineInstr &MI = *I++;
1056 if (RISCVInstrInfo::isFaultOnlyFirstLoad(MI)) {
1057 Register VLOutput = MI.getOperand(1).getReg();
1058 assert(VLOutput.isVirtual());
1059 if (!MI.getOperand(1).isDead()) {
1060 auto ReadVLMI = BuildMI(MBB, I, MI.getDebugLoc(),
1061 TII->get(RISCV::PseudoReadVL), VLOutput);
1062 // Move the LiveInterval's definition down to PseudoReadVL.
1063 if (LIS) {
1064 SlotIndex NewDefSI =
1065 LIS->InsertMachineInstrInMaps(*ReadVLMI).getRegSlot();
1066 LiveInterval &DefLI = LIS->getInterval(VLOutput);
1067 LiveRange::Segment *DefSeg = DefLI.getSegmentContaining(NewDefSI);
1068 VNInfo *DefVNI = DefLI.getVNInfoAt(DefSeg->start);
1069 DefLI.removeSegment(DefSeg->start, NewDefSI);
1070 DefVNI->def = NewDefSI;
1071 }
1072 }
1073 // We don't use the vl output of the VLEFF/VLSEGFF anymore.
1074 MI.getOperand(1).setReg(RISCV::X0);
1075 MI.addRegisterDefined(RISCV::VL, MRI->getTargetRegisterInfo());
1076 }
1077 }
1078}
1079
1080bool RISCVInsertVSETVLIImpl::insertVSETMTK(MachineBasicBlock &MBB,
1081 TKTMMode Mode) const {
1082
1083 bool Changed = false;
1084 for (auto &MI : MBB) {
1085 uint64_t TSFlags = MI.getDesc().TSFlags;
1086 if (RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(MI) ||
1087 !RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasTWidenOp(TSFlags))
1088 continue;
1089
1090 VSETVLIInfo CurrInfo = VIA.computeInfoForInstr(MI);
1091
1092 unsigned Opcode = 0, OpNum = 0;
1093 switch (Mode) {
1094 case VSETTK:
1095 if (!RISCVII::hasTKOp(TSFlags))
1096 continue;
1097 OpNum = RISCVII::getTKOpNum(MI.getDesc());
1098 Opcode = RISCV::PseudoSF_VSETTK;
1099 break;
1100 case VSETTM:
1101 if (!RISCVII::hasTMOp(TSFlags))
1102 continue;
1103 OpNum = RISCVII::getTMOpNum(MI.getDesc());
1104 Opcode = RISCV::PseudoSF_VSETTM;
1105 break;
1106 }
1107
1108 assert(OpNum && Opcode && "Invalid OpNum or Opcode");
1109
1110 MachineOperand &Op = MI.getOperand(OpNum);
1111
1112 auto TmpMI = BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(Opcode))
1113 .addDef(RISCV::X0, RegState::Dead)
1114 .addReg(Op.getReg())
1115 .addImm(Log2_32(CurrInfo.getSEW()))
1116 .addImm(CurrInfo.getTWiden());
1117
1118 Changed = true;
1119 Register Reg = Op.getReg();
1120 Op.setReg(Register());
1121 Op.setIsKill(false);
1122 if (LIS) {
1123 LIS->InsertMachineInstrInMaps(*TmpMI);
1124 LiveInterval &LI = LIS->getInterval(Reg);
1125
1126 // Erase the AVL operand from the instruction.
1127 LIS->shrinkToUses(&LI);
1128 // TODO: Enable this once needVSETVLIPHI is supported.
1129 // SmallVector<LiveInterval *> SplitLIs;
1130 // LIS->splitSeparateComponents(LI, SplitLIs);
1131 }
1132 }
1133 return Changed;
1134}
1135
1136bool RISCVInsertVSETVLIImpl::runOnMachineFunction(MachineFunction &MF,
1137 LiveIntervals *LISToUpdate) {
1138 // Skip if the vector extension is not enabled.
1139 ST = &MF.getSubtarget<RISCVSubtarget>();
1140 if (!ST->hasVInstructions())
1141 return false;
1142
1143 LLVM_DEBUG(dbgs() << "Entering InsertVSETVLI for " << MF.getName() << "\n");
1144
1145 TII = ST->getInstrInfo();
1146 MRI = &MF.getRegInfo();
1147 LIS = LISToUpdate;
1148 VIA = RISCVVSETVLIInfoAnalysis(ST, LIS);
1149
1150 assert(BlockInfo.empty() && "Expect empty block infos");
1151 BlockInfo.resize(MF.getNumBlockIDs());
1152
1153 bool HaveVectorOp = false;
1154
1155 // Phase 1 - determine how VL/VTYPE are affected by the each block.
1156 for (const MachineBasicBlock &MBB : MF) {
1157 VSETVLIInfo TmpStatus;
1158 HaveVectorOp |= computeVLVTYPEChanges(MBB, TmpStatus);
1159 // Initial exit state is whatever change we found in the block.
1160 BlockData &BBInfo = BlockInfo[MBB.getNumber()];
1161 BBInfo.Exit = TmpStatus;
1162 LLVM_DEBUG(dbgs() << "Initial exit state of " << printMBBReference(MBB)
1163 << " is " << BBInfo.Exit << "\n");
1164
1165 }
1166
1167 // If we didn't find any instructions that need VSETVLI, we're done.
1168 if (!HaveVectorOp) {
1169 BlockInfo.clear();
1170 return false;
1171 }
1172
1173 // Phase 2 - determine the exit VL/VTYPE from each block. We add all
1174 // blocks to the list here, but will also add any that need to be revisited
1175 // during Phase 2 processing.
1176 for (const MachineBasicBlock &MBB : MF) {
1177 WorkList.push(&MBB);
1178 BlockInfo[MBB.getNumber()].InQueue = true;
1179 }
1180 while (!WorkList.empty()) {
1181 const MachineBasicBlock &MBB = *WorkList.front();
1182 WorkList.pop();
1183 computeIncomingVLVTYPE(MBB);
1184 }
1185
1186 // Perform partial redundancy elimination of vsetvli transitions.
1187 for (MachineBasicBlock &MBB : MF)
1188 doPRE(MBB);
1189
1190 // Phase 3 - add any vsetvli instructions needed in the block. Use the
1191 // Phase 2 information to avoid adding vsetvlis before the first vector
1192 // instruction in the block if the VL/VTYPE is satisfied by its
1193 // predecessors.
1194 for (MachineBasicBlock &MBB : MF)
1195 emitVSETVLIs(MBB);
1196
1197 // Now that all vsetvlis are explicit, go through and do block local
1198 // DSE and peephole based demanded fields based transforms. Note that
1199 // this *must* be done outside the main dataflow so long as we allow
1200 // any cross block analysis within the dataflow. We can't have both
1201 // demanded fields based mutation and non-local analysis in the
1202 // dataflow at the same time without introducing inconsistencies.
1203 // We're visiting blocks from the bottom up because a VSETVLI in the
1204 // earlier block might become dead when its uses in later blocks are
1205 // optimized away.
1206 for (MachineBasicBlock *MBB : post_order(&MF))
1207 coalesceVSETVLIs(*MBB);
1208
1209 if (ST->hasVendorXSfmmbase()) {
1210 for (MachineBasicBlock &MBB : MF)
1211 coalesceVSETVLIsForTWiden(MBB);
1212 }
1213
1214 // Insert PseudoReadVL after VLEFF/VLSEGFF and replace it with the vl output
1215 // of VLEFF/VLSEGFF.
1216 for (MachineBasicBlock &MBB : MF)
1217 insertReadVL(MBB);
1218
1219 if (ST->hasVendorXSfmmbase()) {
1220 for (MachineBasicBlock &MBB : MF) {
1221 insertVSETMTK(MBB, VSETTM);
1222 insertVSETMTK(MBB, VSETTK);
1223 }
1224 }
1225
1226 BlockInfo.clear();
1227 return HaveVectorOp;
1228}
1229
1230/// Returns an instance of the Insert VSETVLI pass.
1232 return new RISCVInsertVSETVLILegacy();
1233}
1234
1235bool RISCVInsertVSETVLILegacy::runOnMachineFunction(MachineFunction &MF) {
1236 RISCVInsertVSETVLIImpl Impl;
1237 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
1238 LiveIntervals *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
1239 return Impl.runOnMachineFunction(MF, LIS);
1240}
1241
1242PreservedAnalyses
1245 RISCVInsertVSETVLIImpl Impl;
1247 bool Changed = Impl.runOnMachineFunction(MF, LIS);
1248 if (!Changed)
1249 return PreservedAnalyses::all();
1252 .preserve<LiveIntervalsAnalysis>()
1253 .preserve<SlotIndexesAnalysis>()
1254 .preserve<LiveDebugVariablesAnalysis>()
1255 .preserve<LiveStacksAnalysis>();
1256}
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
uint64_t uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
uint64_t IntrinsicInst * II
#define P(N)
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static VSETVLIInfo adjustIncoming(const VSETVLIInfo &PrevInfo, const VSETVLIInfo &NewInfo, DemandedFields &Demanded)
#define RISCV_INSERT_VSETVLI_NAME
MachineRegisterInfo & MRI
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Optimize VGPR LiveRange
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
BlockData()=default
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
A debug info location.
Definition DebugLoc.h:126
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
LiveInterval - This class represents the liveness of a register, or stack slot.
void setWeight(float Value)
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LLVM_ABI void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void extendToIndices(LiveRange &LR, ArrayRef< SlotIndex > Indices, ArrayRef< SlotIndex > Undefs)
Extend the live range LR to reach all points in Indices.
LLVM_ABI void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
bool liveAt(SlotIndex index) const
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
bool containsOneValue() const
LLVM_ABI void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
LLVM_ABI instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void moveBefore(MachineInstr *MovePos)
Move the instruction before MovePos.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
const RISCVOptions & getCLOpts() const
bool hasVInstructions() const
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) const
VSETVLIInfo computeInfoForInstr(const MachineInstr &MI) const
Defines the abstract state with which the forward dataflow models the values of the VL and VTYPE regi...
bool hasSameVTYPE(const VSETVLIInfo &Other) const
VSETVLIInfo intersect(const VSETVLIInfo &Other) const
bool hasSameVLMAX(const VSETVLIInfo &Other) const
bool isCompatible(const DemandedFields &Used, const VSETVLIInfo &Require, const LiveIntervals *LIS) const
bool hasSameAVL(const VSETVLIInfo &Other) const
const VNInfo * getAVLVNInfo() const
RISCVVType::VLMUL getVLMUL() const
bool hasEquallyZeroAVL(const VSETVLIInfo &Other, const LiveIntervals *LIS) const
void setAVL(const VSETVLIInfo &Info)
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:70
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
void push_back(const T &Elt)
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
Pass manager infrastructure for declaring and invalidating analyses.
static unsigned getTMOpNum(const MCInstrDesc &Desc)
static bool hasTWidenOp(uint64_t TSFlags)
static unsigned getTKOpNum(const MCInstrDesc &Desc)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasTKOp(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static bool hasTMOp(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
LLVM_ABI std::optional< VLMUL > getSameRatioLMUL(unsigned Ratio, unsigned EEW)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static const MachineOperand & getVLOp(const MachineInstr &MI)
DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST)
Return the fields and properties demanded by the provided instruction.
bool areCompatibleVTYPEs(uint64_t CurVType, uint64_t NewVType, const DemandedFields &Used)
Return true if moving from CurVType to NewVType is indistinguishable from the perspective of an instr...
static VNInfo * getVNInfoFromReg(Register Reg, const MachineInstr &MI, const LiveIntervals *LIS)
Given a virtual register Reg, return the corresponding VNInfo for it.
bool isVectorCopy(const TargetRegisterInfo *TRI, const MachineInstr &MI)
Return true if MI is a copy that will be lowered to one or more vmvNr.vs.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Dead
Unused definition.
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:649
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
DWARFExpression::Operation Op
char & RISCVInsertVSETVLILegacyID
FunctionPass * createRISCVInsertVSETVLILegacyPass()
Returns an instance of the Insert VSETVLI pass.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Which subfields of VL or VTYPE have values we need to preserve?
enum llvm::RISCV::DemandedFields::@326061152055210015167034143142117063364004052074 SEW
enum llvm::RISCV::DemandedFields::@201276154261047021277240313173154105356124146047 LMUL