LLVM 23.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"
36#include <queue>
37using namespace llvm;
38using namespace RISCV;
39
40#define DEBUG_TYPE "riscv-insert-vsetvli"
41#define RISCV_INSERT_VSETVLI_NAME "RISC-V Insert VSETVLI pass"
42
43STATISTIC(NumInsertedVSETVL, "Number of VSETVL inst inserted");
44STATISTIC(NumCoalescedVSETVL, "Number of VSETVL inst coalesced");
45
47 DEBUG_TYPE "-whole-vector-register-move-valid-vtype", cl::Hidden,
48 cl::desc("Insert vsetvlis before vmvNr.vs to ensure vtype is valid and "
49 "vill is cleared"),
50 cl::init(true));
51
52namespace {
53
54/// Given a virtual register \p Reg, return the corresponding VNInfo for it.
55/// This will return nullptr if the virtual register is an implicit_def or
56/// if LiveIntervals is not available.
58 const LiveIntervals *LIS) {
59 assert(Reg.isVirtual());
60 if (!LIS)
61 return nullptr;
62 auto &LI = LIS->getInterval(Reg);
64 return LI.getVNInfoBefore(SI);
65}
66
68 return MI.getOperand(RISCVII::getVLOpNum(MI.getDesc()));
69}
70
71struct BlockData {
72 // The VSETVLIInfo that represents the VL/VTYPE settings on exit from this
73 // block. Calculated in Phase 2.
74 VSETVLIInfo Exit;
75
76 // The VSETVLIInfo that represents the VL/VTYPE settings from all predecessor
77 // blocks. Calculated in Phase 2, and used by Phase 3.
78 VSETVLIInfo Pred;
79
80 // Keeps track of whether the block is already in the queue.
81 bool InQueue = false;
82
83 BlockData() = default;
84};
85
86enum TKTMMode {
87 VSETTK = 0,
88 VSETTM = 1,
89};
90
91class RISCVInsertVSETVLI : public MachineFunctionPass {
92 const RISCVSubtarget *ST;
93 const TargetInstrInfo *TII;
94 MachineRegisterInfo *MRI;
95 // Possibly null!
96 LiveIntervals *LIS;
97 RISCVVSETVLIInfoAnalysis VIA;
98
99 std::vector<BlockData> BlockInfo;
100 std::queue<const MachineBasicBlock *> WorkList;
101
102public:
103 static char ID;
104
105 RISCVInsertVSETVLI() : MachineFunctionPass(ID) {}
106 bool runOnMachineFunction(MachineFunction &MF) override;
107
108 void getAnalysisUsage(AnalysisUsage &AU) const override {
109 AU.setPreservesCFG();
110
111 AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
112 AU.addPreserved<LiveIntervalsWrapperPass>();
113 AU.addPreserved<SlotIndexesWrapperPass>();
114 AU.addPreserved<LiveDebugVariablesWrapperLegacy>();
115 AU.addPreserved<LiveStacksWrapperLegacy>();
116
118 }
119
120 StringRef getPassName() const override { return RISCV_INSERT_VSETVLI_NAME; }
121
122private:
123 bool needVSETVLI(const DemandedFields &Used, const VSETVLIInfo &Require,
124 const VSETVLIInfo &CurInfo) const;
125 bool needVSETVLIPHI(const VSETVLIInfo &Require,
126 const MachineBasicBlock &MBB) const;
127 void insertVSETVLI(MachineBasicBlock &MBB,
129 const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo);
130
131 void transferBefore(VSETVLIInfo &Info, const MachineInstr &MI) const;
132 void transferAfter(VSETVLIInfo &Info, const MachineInstr &MI) const;
133 bool computeVLVTYPEChanges(const MachineBasicBlock &MBB,
134 VSETVLIInfo &Info) const;
135 void computeIncomingVLVTYPE(const MachineBasicBlock &MBB);
136 void emitVSETVLIs(MachineBasicBlock &MBB);
137 void doPRE(MachineBasicBlock &MBB);
138 void insertReadVL(MachineBasicBlock &MBB);
139
140 bool canMutatePriorConfig(const MachineInstr &PrevMI, const MachineInstr &MI,
141 const DemandedFields &Used,
142 MachineInstr *&AVLDefToMove) const;
143 void coalesceVSETVLIs(MachineBasicBlock &MBB) const;
144 bool insertVSETMTK(MachineBasicBlock &MBB, TKTMMode Mode) const;
145};
146
147} // end anonymous namespace
148
149char RISCVInsertVSETVLI::ID = 0;
150char &llvm::RISCVInsertVSETVLIID = RISCVInsertVSETVLI::ID;
151
153 false, false)
154
155void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
156 MachineBasicBlock::iterator InsertPt,
158 const VSETVLIInfo &PrevInfo) {
159 ++NumInsertedVSETVL;
160
161 if (Info.getTWiden()) {
162 if (Info.hasAVLVLMAX()) {
163 Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
164 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNTX0))
165 .addReg(DestReg, RegState::Define | RegState::Dead)
166 .addReg(RISCV::X0, RegState::Kill)
167 .addImm(Info.encodeVTYPE());
168 if (LIS) {
169 LIS->InsertMachineInstrInMaps(*MI);
170 LIS->createAndComputeVirtRegInterval(DestReg);
171 }
172 } else {
173 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoSF_VSETTNT))
174 .addReg(RISCV::X0, RegState::Define | RegState::Dead)
175 .addReg(Info.getAVLReg())
176 .addImm(Info.encodeVTYPE());
177 if (LIS)
178 LIS->InsertMachineInstrInMaps(*MI);
179 }
180 return;
181 }
182
183 if (PrevInfo.isValid() && !PrevInfo.isUnknown()) {
184 // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same
185 // VLMAX.
186 if (Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) {
187 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0X0))
188 .addReg(RISCV::X0, RegState::Define | RegState::Dead)
189 .addReg(RISCV::X0, RegState::Kill)
190 .addImm(Info.encodeVTYPE())
191 .addReg(RISCV::VL, RegState::Implicit);
192 if (LIS)
193 LIS->InsertMachineInstrInMaps(*MI);
194 return;
195 }
196
197 // If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If
198 // it has the same VLMAX we want and the last VL/VTYPE we observed is the
199 // same, we can use the X0, X0 form.
200 if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
201 if (const MachineInstr *DefMI = Info.getAVLDefMI(LIS);
202 DefMI && RISCVInstrInfo::isVectorConfigInstr(*DefMI)) {
203 VSETVLIInfo DefInfo = VIA.getInfoForVSETVLI(*DefMI);
204 if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
205 auto MI =
206 BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0X0))
207 .addReg(RISCV::X0, RegState::Define | RegState::Dead)
208 .addReg(RISCV::X0, RegState::Kill)
209 .addImm(Info.encodeVTYPE())
210 .addReg(RISCV::VL, RegState::Implicit);
211 if (LIS)
212 LIS->InsertMachineInstrInMaps(*MI);
213 return;
214 }
215 }
216 }
217 }
218
219 if (Info.hasAVLImm()) {
220 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETIVLI))
221 .addReg(RISCV::X0, RegState::Define | RegState::Dead)
222 .addImm(Info.getAVLImm())
223 .addImm(Info.encodeVTYPE());
224 if (LIS)
225 LIS->InsertMachineInstrInMaps(*MI);
226 return;
227 }
228
229 if (Info.hasAVLVLMAX()) {
230 Register DestReg = MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
231 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0))
232 .addReg(DestReg, RegState::Define | RegState::Dead)
233 .addReg(RISCV::X0, RegState::Kill)
234 .addImm(Info.encodeVTYPE());
235 if (LIS) {
236 LIS->InsertMachineInstrInMaps(*MI);
237 LIS->createAndComputeVirtRegInterval(DestReg);
238 }
239 return;
240 }
241
242 Register AVLReg = Info.getAVLReg();
243 MRI->constrainRegClass(AVLReg, &RISCV::GPRNoX0RegClass);
244 auto MI = BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLI))
246 .addReg(AVLReg)
247 .addImm(Info.encodeVTYPE());
248 if (LIS) {
250 LiveInterval &LI = LIS->getInterval(AVLReg);
252 const VNInfo *CurVNI = Info.getAVLVNInfo();
253 // If the AVL value isn't live at MI, do a quick check to see if it's easily
254 // extendable. Otherwise, we need to copy it.
255 if (LI.getVNInfoBefore(SI) != CurVNI) {
256 if (!LI.liveAt(SI) && LI.containsOneValue())
257 LIS->extendToIndices(LI, SI);
258 else {
259 Register AVLCopyReg =
260 MRI->createVirtualRegister(&RISCV::GPRNoX0RegClass);
261 MachineBasicBlock *MBB = LIS->getMBBFromIndex(CurVNI->def);
263 if (CurVNI->isPHIDef())
264 II = MBB->getFirstNonPHI();
265 else {
266 II = LIS->getInstructionFromIndex(CurVNI->def);
267 II = std::next(II);
268 }
269 assert(II.isValid());
270 auto AVLCopy = BuildMI(*MBB, II, DL, TII->get(RISCV::COPY), AVLCopyReg)
271 .addReg(AVLReg);
272 LIS->InsertMachineInstrInMaps(*AVLCopy);
273 MI->getOperand(1).setReg(AVLCopyReg);
274 LIS->createAndComputeVirtRegInterval(AVLCopyReg);
275 }
276 }
277 }
278}
279
280/// Return true if a VSETVLI is required to transition from CurInfo to Require
281/// given a set of DemandedFields \p Used.
282bool RISCVInsertVSETVLI::needVSETVLI(const DemandedFields &Used,
283 const VSETVLIInfo &Require,
284 const VSETVLIInfo &CurInfo) const {
285 if (!CurInfo.isValid() || CurInfo.isUnknown() || CurInfo.hasSEWLMULRatioOnly())
286 return true;
287
288 if (CurInfo.isCompatible(Used, Require, LIS))
289 return false;
290
291 return true;
292}
293
294// If we don't use LMUL or the SEW/LMUL ratio, then adjust LMUL so that we
295// maintain the SEW/LMUL ratio. This allows us to eliminate VL toggles in more
296// places.
298 const VSETVLIInfo &NewInfo,
299 DemandedFields &Demanded) {
300 VSETVLIInfo Info = NewInfo;
301
302 if (!Demanded.LMUL && !Demanded.SEWLMULRatio && PrevInfo.isValid() &&
303 !PrevInfo.isUnknown()) {
304 if (auto NewVLMul = RISCVVType::getSameRatioLMUL(PrevInfo.getSEWLMULRatio(),
305 Info.getSEW()))
306 Info.setVLMul(*NewVLMul);
308 }
309
310 return Info;
311}
312
313// Given an incoming state reaching MI, minimally modifies that state so that it
314// is compatible with MI. The resulting state is guaranteed to be semantically
315// legal for MI, but may not be the state requested by MI.
316void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
317 const MachineInstr &MI) const {
320 (Info.isUnknown() || !Info.isValid() || Info.hasSEWLMULRatioOnly())) {
321 // Use an arbitrary but valid AVL and VTYPE so vill will be cleared. It may
322 // be coalesced into another vsetvli since we won't demand any fields.
323 VSETVLIInfo NewInfo; // Need a new VSETVLIInfo to clear SEWLMULRatioOnly
324 NewInfo.setAVLImm(1);
325 NewInfo.setVTYPE(RISCVVType::LMUL_1, /*sew*/ 8, /*ta*/ true, /*ma*/ true,
326 /*AltFmt*/ false, /*W*/ 0);
327 Info = NewInfo;
328 return;
329 }
330
331 if (!RISCVII::hasSEWOp(MI.getDesc().TSFlags))
332 return;
333
334 DemandedFields Demanded = getDemanded(MI, ST);
335
336 const VSETVLIInfo NewInfo = VIA.computeInfoForInstr(MI);
337 assert(NewInfo.isValid() && !NewInfo.isUnknown());
338 if (Info.isValid() && !needVSETVLI(Demanded, NewInfo, Info))
339 return;
340
341 const VSETVLIInfo PrevInfo = Info;
342 if (!Info.isValid() || Info.isUnknown())
343 Info = NewInfo;
344
345 const VSETVLIInfo IncomingInfo = adjustIncoming(PrevInfo, NewInfo, Demanded);
346
347 // If MI only demands that VL has the same zeroness, we only need to set the
348 // AVL if the zeroness differs. This removes a vsetvli entirely if the types
349 // match or allows use of cheaper avl preserving variant if VLMAX doesn't
350 // change. If VLMAX might change, we couldn't use the 'vsetvli x0, x0, vtype"
351 // variant, so we avoid the transform to prevent extending live range of an
352 // avl register operand.
353 // TODO: We can probably relax this for immediates.
354 bool EquallyZero = IncomingInfo.hasEquallyZeroAVL(PrevInfo, LIS) &&
355 IncomingInfo.hasSameVLMAX(PrevInfo);
356 if (Demanded.VLAny || (Demanded.VLZeroness && !EquallyZero))
357 Info.setAVL(IncomingInfo);
358
359 // If we only knew the sew/lmul ratio previously, replace the VTYPE.
360 if (Info.hasSEWLMULRatioOnly()) {
361 VSETVLIInfo RatiolessInfo = IncomingInfo;
362 RatiolessInfo.setAVL(Info);
363 Info = RatiolessInfo;
364 } else {
365 unsigned SEW =
366 ((Demanded.SEW || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
367 .getSEW();
368 Info.setVTYPE(
369 ((Demanded.LMUL || Demanded.SEWLMULRatio) ? IncomingInfo : Info)
370 .getVLMUL(),
371 SEW,
372 // Prefer tail/mask agnostic since it can be relaxed to undisturbed
373 // later if needed.
374 (Demanded.TailPolicy ? IncomingInfo : Info).getTailAgnostic() ||
375 IncomingInfo.getTailAgnostic(),
376 (Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
377 IncomingInfo.getMaskAgnostic(),
378 // AltFmt requires SEW < 32.
379 (Demanded.AltFmt ? IncomingInfo : Info).getAltFmt() && SEW < 32,
380 Demanded.TWiden ? IncomingInfo.getTWiden() : 0);
381 }
382}
383
384// Given a state with which we evaluated MI (see transferBefore above for why
385// this might be different that the state MI requested), modify the state to
386// reflect the changes MI might make.
387void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
388 const MachineInstr &MI) const {
389 if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
391 return;
392 }
393
394 if (RISCVInstrInfo::isFaultOnlyFirstLoad(MI)) {
395 // Update AVL to vl-output of the fault first load.
396 assert(MI.getOperand(1).getReg().isVirtual());
397 if (LIS) {
398 auto &LI = LIS->getInterval(MI.getOperand(1).getReg());
399 SlotIndex SI =
401 VNInfo *VNI = LI.getVNInfoAt(SI);
402 Info.setAVLRegDef(VNI, MI.getOperand(1).getReg());
403 } else
404 Info.setAVLRegDef(nullptr, MI.getOperand(1).getReg());
405 return;
406 }
407
408 // If this is something that updates VL/VTYPE that we don't know about, set
409 // the state to unknown.
410 if (MI.isCall() || MI.isInlineAsm() ||
411 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
412 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
414}
415
416bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB,
417 VSETVLIInfo &Info) const {
418 bool HadVectorOp = false;
419
420 Info = BlockInfo[MBB.getNumber()].Pred;
421 for (const MachineInstr &MI : MBB) {
422 transferBefore(Info, MI);
423
424 if (RISCVInstrInfo::isVectorConfigInstr(MI) ||
425 RISCVII::hasSEWOp(MI.getDesc().TSFlags) ||
427 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI))
428 HadVectorOp = true;
429
430 transferAfter(Info, MI);
431 }
432
433 return HadVectorOp;
434}
435
436void RISCVInsertVSETVLI::computeIncomingVLVTYPE(const MachineBasicBlock &MBB) {
437
438 BlockData &BBInfo = BlockInfo[MBB.getNumber()];
439
440 BBInfo.InQueue = false;
441
442 // Start with the previous entry so that we keep the most conservative state
443 // we have ever found.
444 VSETVLIInfo InInfo = BBInfo.Pred;
445 if (MBB.pred_empty()) {
446 // There are no predecessors, so use the default starting status.
447 InInfo.setUnknown();
448 } else {
449 for (MachineBasicBlock *P : MBB.predecessors())
450 InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit);
451 }
452
453 // If we don't have any valid predecessor value, wait until we do.
454 if (!InInfo.isValid())
455 return;
456
457 // If no change, no need to rerun block
458 if (InInfo == BBInfo.Pred)
459 return;
460
461 BBInfo.Pred = InInfo;
462 LLVM_DEBUG(dbgs() << "Entry state of " << printMBBReference(MBB)
463 << " changed to " << BBInfo.Pred << "\n");
464
465 // Note: It's tempting to cache the state changes here, but due to the
466 // compatibility checks performed a blocks output state can change based on
467 // the input state. To cache, we'd have to add logic for finding
468 // never-compatible state changes.
469 VSETVLIInfo TmpStatus;
470 computeVLVTYPEChanges(MBB, TmpStatus);
471
472 // If the new exit value matches the old exit value, we don't need to revisit
473 // any blocks.
474 if (BBInfo.Exit == TmpStatus)
475 return;
476
477 BBInfo.Exit = TmpStatus;
478 LLVM_DEBUG(dbgs() << "Exit state of " << printMBBReference(MBB)
479 << " changed to " << BBInfo.Exit << "\n");
480
481 // Add the successors to the work list so we can propagate the changed exit
482 // status.
483 for (MachineBasicBlock *S : MBB.successors())
484 if (!BlockInfo[S->getNumber()].InQueue) {
485 BlockInfo[S->getNumber()].InQueue = true;
486 WorkList.push(S);
487 }
488}
489
490// If we weren't able to prove a vsetvli was directly unneeded, it might still
491// be unneeded if the AVL was a phi node where all incoming values are VL
492// outputs from the last VSETVLI in their respective basic blocks.
493bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
494 const MachineBasicBlock &MBB) const {
495 if (!Require.hasAVLReg())
496 return true;
497
498 if (!LIS)
499 return true;
500
501 // We need the AVL to have been produced by a PHI node in this basic block.
502 const VNInfo *Valno = Require.getAVLVNInfo();
503 if (!Valno->isPHIDef() || LIS->getMBBFromIndex(Valno->def) != &MBB)
504 return true;
505
506 const LiveRange &LR = LIS->getInterval(Require.getAVLReg());
507
508 for (auto *PBB : MBB.predecessors()) {
509 const VSETVLIInfo &PBBExit = BlockInfo[PBB->getNumber()].Exit;
510
511 // We need the PHI input to the be the output of a VSET(I)VLI.
512 const VNInfo *Value = LR.getVNInfoBefore(LIS->getMBBEndIdx(PBB));
513 if (!Value)
514 return true;
515 MachineInstr *DefMI = LIS->getInstructionFromIndex(Value->def);
516 if (!DefMI || !RISCVInstrInfo::isVectorConfigInstr(*DefMI))
517 return true;
518
519 // We found a VSET(I)VLI make sure it matches the output of the
520 // predecessor block.
521 VSETVLIInfo DefInfo = VIA.getInfoForVSETVLI(*DefMI);
522 if (DefInfo != PBBExit)
523 return true;
524
525 // Require has the same VL as PBBExit, so if the exit from the
526 // predecessor has the VTYPE we are looking for we might be able
527 // to avoid a VSETVLI.
528 if (PBBExit.isUnknown() || !PBBExit.hasSameVTYPE(Require))
529 return true;
530 }
531
532 // If all the incoming values to the PHI checked out, we don't need
533 // to insert a VSETVLI.
534 return false;
535}
536
537void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
538 VSETVLIInfo CurInfo = BlockInfo[MBB.getNumber()].Pred;
539 // Track whether the prefix of the block we've scanned is transparent
540 // (meaning has not yet changed the abstract state).
541 bool PrefixTransparent = true;
542 for (MachineInstr &MI : MBB) {
543 const VSETVLIInfo PrevInfo = CurInfo;
544 transferBefore(CurInfo, MI);
545
546 // If this is an explicit VSETVLI or VSETIVLI, update our state.
547 if (RISCVInstrInfo::isVectorConfigInstr(MI)) {
548 // Conservatively, mark the VL and VTYPE as live.
549 assert(MI.getOperand(3).getReg() == RISCV::VL &&
550 MI.getOperand(4).getReg() == RISCV::VTYPE &&
551 "Unexpected operands where VL and VTYPE should be");
552 MI.getOperand(3).setIsDead(false);
553 MI.getOperand(4).setIsDead(false);
554 PrefixTransparent = false;
555 }
556
559 if (!PrevInfo.isCompatible(DemandedFields::all(), CurInfo, LIS)) {
560 insertVSETVLI(MBB, MI, MI.getDebugLoc(), CurInfo, PrevInfo);
561 PrefixTransparent = false;
562 }
563 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
564 /*isImp*/ true));
565 }
566
567 uint64_t TSFlags = MI.getDesc().TSFlags;
568 if (RISCVII::hasSEWOp(TSFlags)) {
569 if (!PrevInfo.isCompatible(DemandedFields::all(), CurInfo, LIS)) {
570 // If this is the first implicit state change, and the state change
571 // requested can be proven to produce the same register contents, we
572 // can skip emitting the actual state change and continue as if we
573 // had since we know the GPR result of the implicit state change
574 // wouldn't be used and VL/VTYPE registers are correct. Note that
575 // we *do* need to model the state as if it changed as while the
576 // register contents are unchanged, the abstract model can change.
577 if (!PrefixTransparent || needVSETVLIPHI(CurInfo, MBB))
578 insertVSETVLI(MBB, MI, MI.getDebugLoc(), CurInfo, PrevInfo);
579 PrefixTransparent = false;
580 }
581
582 if (RISCVII::hasVLOp(TSFlags)) {
583 MachineOperand &VLOp = getVLOp(MI);
584 if (VLOp.isReg()) {
585 Register Reg = VLOp.getReg();
586
587 // Erase the AVL operand from the instruction.
588 VLOp.setReg(Register());
589 VLOp.setIsKill(false);
590 if (LIS) {
591 LiveInterval &LI = LIS->getInterval(Reg);
593 LIS->shrinkToUses(&LI, &DeadMIs);
594 // We might have separate components that need split due to
595 // needVSETVLIPHI causing us to skip inserting a new VL def.
597 LIS->splitSeparateComponents(LI, SplitLIs);
598
599 // If the AVL was an immediate > 31, then it would have been emitted
600 // as an ADDI. However, the ADDI might not have been used in the
601 // vsetvli, or a vsetvli might not have been emitted, so it may be
602 // dead now.
603 for (MachineInstr *DeadMI : DeadMIs) {
604 if (!TII->isAddImmediate(*DeadMI, Reg))
605 continue;
606 LIS->RemoveMachineInstrFromMaps(*DeadMI);
607 Register AddReg = DeadMI->getOperand(1).getReg();
608 DeadMI->eraseFromParent();
609 if (AddReg.isVirtual())
610 LIS->shrinkToUses(&LIS->getInterval(AddReg));
611 }
612 }
613 }
614 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false,
615 /*isImp*/ true));
616 }
617 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
618 /*isImp*/ true));
619 }
620
621 if (MI.isInlineAsm()) {
622 MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ true,
623 /*isImp*/ true));
624 MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ true,
625 /*isImp*/ true));
626 }
627
628 if (MI.isCall() || MI.isInlineAsm() ||
629 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
630 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
631 PrefixTransparent = false;
632
633 transferAfter(CurInfo, MI);
634 }
635
636 const auto &Info = BlockInfo[MBB.getNumber()];
637 if (CurInfo != Info.Exit) {
638 LLVM_DEBUG(dbgs() << "in block " << printMBBReference(MBB) << "\n");
639 LLVM_DEBUG(dbgs() << " begin state: " << Info.Pred << "\n");
640 LLVM_DEBUG(dbgs() << " expected end state: " << Info.Exit << "\n");
641 LLVM_DEBUG(dbgs() << " actual end state: " << CurInfo << "\n");
642 }
643 assert(CurInfo == Info.Exit && "InsertVSETVLI dataflow invariant violated");
644}
645
646/// Perform simple partial redundancy elimination of the VSETVLI instructions
647/// we're about to insert by looking for cases where we can PRE from the
648/// beginning of one block to the end of one of its predecessors. Specifically,
649/// this is geared to catch the common case of a fixed length vsetvl in a single
650/// block loop when it could execute once in the preheader instead.
651void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
652 if (!BlockInfo[MBB.getNumber()].Pred.isUnknown())
653 return;
654
655 MachineBasicBlock *UnavailablePred = nullptr;
656 VSETVLIInfo AvailableInfo;
657 for (MachineBasicBlock *P : MBB.predecessors()) {
658 const VSETVLIInfo &PredInfo = BlockInfo[P->getNumber()].Exit;
659 if (PredInfo.isUnknown()) {
660 if (UnavailablePred)
661 return;
662 UnavailablePred = P;
663 } else if (!AvailableInfo.isValid()) {
664 AvailableInfo = PredInfo;
665 } else if (AvailableInfo != PredInfo) {
666 return;
667 }
668 }
669
670 // Unreachable, single pred, or full redundancy. Note that FRE is handled by
671 // phase 3.
672 if (!UnavailablePred || !AvailableInfo.isValid())
673 return;
674
675 if (!LIS)
676 return;
677
678 // If we don't know the exact VTYPE, we can't copy the vsetvli to the exit of
679 // the unavailable pred.
680 if (AvailableInfo.hasSEWLMULRatioOnly())
681 return;
682
683 // Critical edge - TODO: consider splitting?
684 if (UnavailablePred->succ_size() != 1)
685 return;
686
687 // If the AVL value is a register (other than our VLMAX sentinel),
688 // we need to prove the value is available at the point we're going
689 // to insert the vsetvli at.
690 if (AvailableInfo.hasAVLReg()) {
691 SlotIndex SI = AvailableInfo.getAVLVNInfo()->def;
692 // This is an inline dominance check which covers the case of
693 // UnavailablePred being the preheader of a loop.
694 if (LIS->getMBBFromIndex(SI) != UnavailablePred)
695 return;
696 if (!UnavailablePred->terminators().empty() &&
697 SI >= LIS->getInstructionIndex(*UnavailablePred->getFirstTerminator()))
698 return;
699 }
700
701 // Model the effect of changing the input state of the block MBB to
702 // AvailableInfo. We're looking for two issues here; one legality,
703 // one profitability.
704 // 1) If the block doesn't use some of the fields from VL or VTYPE, we
705 // may hit the end of the block with a different end state. We can
706 // not make this change without reflowing later blocks as well.
707 // 2) If we don't actually remove a transition, inserting a vsetvli
708 // into the predecessor block would be correct, but unprofitable.
709 VSETVLIInfo OldInfo = BlockInfo[MBB.getNumber()].Pred;
710 VSETVLIInfo CurInfo = AvailableInfo;
711 int TransitionsRemoved = 0;
712 for (const MachineInstr &MI : MBB) {
713 const VSETVLIInfo LastInfo = CurInfo;
714 const VSETVLIInfo LastOldInfo = OldInfo;
715 transferBefore(CurInfo, MI);
716 transferBefore(OldInfo, MI);
717 if (CurInfo == LastInfo)
718 TransitionsRemoved++;
719 if (LastOldInfo == OldInfo)
720 TransitionsRemoved--;
721 transferAfter(CurInfo, MI);
722 transferAfter(OldInfo, MI);
723 if (CurInfo == OldInfo)
724 // Convergence. All transitions after this must match by construction.
725 break;
726 }
727 if (CurInfo != OldInfo || TransitionsRemoved <= 0)
728 // Issues 1 and 2 above
729 return;
730
731 // Finally, update both data flow state and insert the actual vsetvli.
732 // Doing both keeps the code in sync with the dataflow results, which
733 // is critical for correctness of phase 3.
734 auto OldExit = BlockInfo[UnavailablePred->getNumber()].Exit;
735 LLVM_DEBUG(dbgs() << "PRE VSETVLI from " << MBB.getName() << " to "
736 << UnavailablePred->getName() << " with state "
737 << AvailableInfo << "\n");
738 BlockInfo[UnavailablePred->getNumber()].Exit = AvailableInfo;
739 BlockInfo[MBB.getNumber()].Pred = AvailableInfo;
740
741 // Note there's an implicit assumption here that terminators never use
742 // or modify VL or VTYPE. Also, fallthrough will return end().
743 auto InsertPt = UnavailablePred->getFirstInstrTerminator();
744 insertVSETVLI(*UnavailablePred, InsertPt,
745 UnavailablePred->findDebugLoc(InsertPt),
746 AvailableInfo, OldExit);
747}
748
749// Return true if we can mutate PrevMI to match MI without changing any the
750// fields which would be observed.
751// If AVLDefToMove is non-null after the call, it points to an ADDI
752// instruction that needs to be moved before PrevMI.
753bool RISCVInsertVSETVLI::canMutatePriorConfig(
754 const MachineInstr &PrevMI, const MachineInstr &MI,
755 const DemandedFields &Used, MachineInstr *&AVLDefToMove) const {
756 AVLDefToMove = nullptr;
757 // If the VL values aren't equal, return false if either a) the former is
758 // demanded, or b) we can't rewrite the former to be the later for
759 // implementation reasons.
760 if (!RISCVInstrInfo::isVLPreservingConfig(MI)) {
761 if (Used.VLAny)
762 return false;
763
764 if (Used.VLZeroness) {
765 if (RISCVInstrInfo::isVLPreservingConfig(PrevMI))
766 return false;
767 if (!VIA.getInfoForVSETVLI(PrevMI).hasEquallyZeroAVL(
768 VIA.getInfoForVSETVLI(MI), LIS))
769 return false;
770 }
771
772 auto &AVL = MI.getOperand(1);
773
774 // If the AVL is a register, we need to make sure its definition is the same
775 // at PrevMI as it was at MI.
776 if (AVL.isReg() && AVL.getReg() != RISCV::X0) {
777 VNInfo *VNI = getVNInfoFromReg(AVL.getReg(), MI, LIS);
778 VNInfo *PrevVNI = getVNInfoFromReg(AVL.getReg(), PrevMI, LIS);
779 if (!VNI || !PrevVNI || VNI != PrevVNI) {
780 // If the AVL is defined by a load immediate instruction (ADDI x0, imm),
781 // it can be moved earlier since it has no register dependencies.
782 if (!AVL.getReg().isVirtual())
783 return false;
784
785 MachineInstr *DefMI = MRI->getUniqueVRegDef(AVL.getReg());
786 if (!DefMI || !RISCVInstrInfo::isLoadImmediate(*DefMI) ||
787 DefMI->getParent() != PrevMI.getParent()) {
788 return false;
789 }
790 // Mark that this ADDI needs to be moved.
791 AVLDefToMove = DefMI;
792 }
793 }
794
795 // If we define VL and need to move the definition up, check we can extend
796 // the live interval upwards from MI to PrevMI.
797 Register VL = MI.getOperand(0).getReg();
798 if (VL.isVirtual() && LIS &&
799 LIS->getInterval(VL).overlaps(LIS->getInstructionIndex(PrevMI),
800 LIS->getInstructionIndex(MI)))
801 return false;
802 }
803
804 assert(PrevMI.getOperand(2).isImm() && MI.getOperand(2).isImm());
805 auto PriorVType = PrevMI.getOperand(2).getImm();
806 auto VType = MI.getOperand(2).getImm();
807 return areCompatibleVTYPEs(PriorVType, VType, Used);
808}
809
810void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
811 MachineInstr *NextMI = nullptr;
812 // We can have arbitrary code in successors, so VL and VTYPE
813 // must be considered demanded.
814 DemandedFields Used;
815 Used.demandVL();
816 Used.demandVTYPE();
818
819 auto dropAVLUse = [&](MachineOperand &MO) {
820 if (!MO.isReg() || !MO.getReg().isVirtual())
821 return;
822 Register OldVLReg = MO.getReg();
823 MO.setReg(Register());
824
825 if (LIS)
826 LIS->shrinkToUses(&LIS->getInterval(OldVLReg));
827
828 MachineInstr *VLOpDef = MRI->getUniqueVRegDef(OldVLReg);
829 if (VLOpDef && TII->isAddImmediate(*VLOpDef, OldVLReg) &&
830 MRI->use_nodbg_empty(OldVLReg))
831 ToDelete.push_back(VLOpDef);
832 };
833
834 for (MachineInstr &MI : make_early_inc_range(reverse(MBB))) {
835 // TODO: Support XSfmm.
836 if (RISCVII::hasTWidenOp(MI.getDesc().TSFlags) ||
837 RISCVInstrInfo::isXSfmmVectorConfigInstr(MI)) {
838 NextMI = nullptr;
839 continue;
840 }
841
842 if (!RISCVInstrInfo::isVectorConfigInstr(MI)) {
843 Used.doUnion(getDemanded(MI, ST));
844 if (MI.isCall() || MI.isInlineAsm() ||
845 MI.modifiesRegister(RISCV::VL, /*TRI=*/nullptr) ||
846 MI.modifiesRegister(RISCV::VTYPE, /*TRI=*/nullptr))
847 NextMI = nullptr;
848 continue;
849 }
850
851 if (!MI.getOperand(0).isDead())
852 Used.demandVL();
853
854 if (NextMI) {
855 if (!Used.usedVL() && !Used.usedVTYPE()) {
856 dropAVLUse(MI.getOperand(1));
857 if (LIS)
859 MI.eraseFromParent();
860 NumCoalescedVSETVL++;
861 // Leave NextMI unchanged
862 continue;
863 }
864
865 MachineInstr *AVLDefToMove = nullptr;
866 if (canMutatePriorConfig(MI, *NextMI, Used, AVLDefToMove)) {
867 if (!RISCVInstrInfo::isVLPreservingConfig(*NextMI)) {
868 Register DefReg = NextMI->getOperand(0).getReg();
869
870 MI.getOperand(0).setReg(DefReg);
871 MI.getOperand(0).setIsDead(false);
872
873 // Move the AVL from NextMI to MI
874 dropAVLUse(MI.getOperand(1));
875 if (NextMI->getOperand(1).isImm())
876 MI.getOperand(1).ChangeToImmediate(NextMI->getOperand(1).getImm());
877 else {
878 MI.getOperand(1).ChangeToRegister(NextMI->getOperand(1).getReg(),
879 false);
880
881 // If canMutatePriorConfig indicated that an ADDI needs to be moved,
882 // move it now.
883 if (AVLDefToMove) {
884 AVLDefToMove->moveBefore(&MI);
885 if (LIS)
886 LIS->handleMove(*AVLDefToMove);
887 }
888 }
889 dropAVLUse(NextMI->getOperand(1));
890
891 // The def of DefReg moved to MI, so extend the LiveInterval up to
892 // it.
893 if (DefReg.isVirtual() && LIS) {
894 LiveInterval &DefLI = LIS->getInterval(DefReg);
895 SlotIndex MISlot = LIS->getInstructionIndex(MI).getRegSlot();
896 SlotIndex NextMISlot =
897 LIS->getInstructionIndex(*NextMI).getRegSlot();
898 VNInfo *DefVNI = DefLI.getVNInfoAt(NextMISlot);
899 LiveInterval::Segment S(MISlot, NextMISlot, DefVNI);
900 DefLI.addSegment(S);
901 DefVNI->def = MISlot;
902 // Mark DefLI as spillable if it was previously unspillable
903 DefLI.setWeight(0);
904
905 // DefReg may have had no uses, in which case we need to shrink
906 // the LiveInterval up to MI.
907 LIS->shrinkToUses(&DefLI);
908 }
909
910 MI.setDesc(NextMI->getDesc());
911 }
912 MI.getOperand(2).setImm(NextMI->getOperand(2).getImm());
913
914 dropAVLUse(NextMI->getOperand(1));
915 if (LIS)
916 LIS->RemoveMachineInstrFromMaps(*NextMI);
917 NextMI->eraseFromParent();
918 NumCoalescedVSETVL++;
919 // fallthrough
920 }
921 }
922 NextMI = &MI;
923 Used = getDemanded(MI, ST);
924 }
925
926 // Loop over the dead AVL values, and delete them now. This has
927 // to be outside the above loop to avoid invalidating iterators.
928 for (auto *MI : ToDelete) {
929 assert(MI->getOpcode() == RISCV::ADDI);
930 Register AddReg = MI->getOperand(1).getReg();
931 if (LIS) {
932 LIS->removeInterval(MI->getOperand(0).getReg());
934 }
935 MI->eraseFromParent();
936 if (LIS && AddReg.isVirtual())
937 LIS->shrinkToUses(&LIS->getInterval(AddReg));
938 }
939}
940
941void RISCVInsertVSETVLI::insertReadVL(MachineBasicBlock &MBB) {
942 for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
943 MachineInstr &MI = *I++;
944 if (RISCVInstrInfo::isFaultOnlyFirstLoad(MI)) {
945 Register VLOutput = MI.getOperand(1).getReg();
946 assert(VLOutput.isVirtual());
947 if (!MI.getOperand(1).isDead()) {
948 auto ReadVLMI = BuildMI(MBB, I, MI.getDebugLoc(),
949 TII->get(RISCV::PseudoReadVL), VLOutput);
950 // Move the LiveInterval's definition down to PseudoReadVL.
951 if (LIS) {
952 SlotIndex NewDefSI =
953 LIS->InsertMachineInstrInMaps(*ReadVLMI).getRegSlot();
954 LiveInterval &DefLI = LIS->getInterval(VLOutput);
955 LiveRange::Segment *DefSeg = DefLI.getSegmentContaining(NewDefSI);
956 VNInfo *DefVNI = DefLI.getVNInfoAt(DefSeg->start);
957 DefLI.removeSegment(DefSeg->start, NewDefSI);
958 DefVNI->def = NewDefSI;
959 }
960 }
961 // We don't use the vl output of the VLEFF/VLSEGFF anymore.
962 MI.getOperand(1).setReg(RISCV::X0);
963 MI.addRegisterDefined(RISCV::VL, MRI->getTargetRegisterInfo());
964 }
965 }
966}
967
968bool RISCVInsertVSETVLI::insertVSETMTK(MachineBasicBlock &MBB,
969 TKTMMode Mode) const {
970
971 bool Changed = false;
972 for (auto &MI : MBB) {
973 uint64_t TSFlags = MI.getDesc().TSFlags;
974 if (RISCVInstrInfo::isXSfmmVectorConfigTMTKInstr(MI) ||
975 !RISCVII::hasSEWOp(TSFlags) || !RISCVII::hasTWidenOp(TSFlags))
976 continue;
977
978 VSETVLIInfo CurrInfo = VIA.computeInfoForInstr(MI);
979
980 unsigned Opcode = 0, OpNum = 0;
981 switch (Mode) {
982 case VSETTK:
983 if (!RISCVII::hasTKOp(TSFlags))
984 continue;
985 OpNum = RISCVII::getTKOpNum(MI.getDesc());
986 Opcode = RISCV::PseudoSF_VSETTK;
987 break;
988 case VSETTM:
989 if (!RISCVII::hasTMOp(TSFlags))
990 continue;
991 OpNum = RISCVII::getTMOpNum(MI.getDesc());
992 Opcode = RISCV::PseudoSF_VSETTM;
993 break;
994 }
995
996 assert(OpNum && Opcode && "Invalid OpNum or Opcode");
997
998 MachineOperand &Op = MI.getOperand(OpNum);
999
1000 auto TmpMI = BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(Opcode))
1001 .addReg(RISCV::X0, RegState::Define | RegState::Dead)
1002 .addReg(Op.getReg())
1003 .addImm(Log2_32(CurrInfo.getSEW()))
1004 .addImm(CurrInfo.getTWiden());
1005
1006 Changed = true;
1007 Register Reg = Op.getReg();
1008 Op.setReg(Register());
1009 Op.setIsKill(false);
1010 if (LIS) {
1011 LIS->InsertMachineInstrInMaps(*TmpMI);
1012 LiveInterval &LI = LIS->getInterval(Reg);
1013
1014 // Erase the AVL operand from the instruction.
1015 LIS->shrinkToUses(&LI);
1016 // TODO: Enable this once needVSETVLIPHI is supported.
1017 // SmallVector<LiveInterval *> SplitLIs;
1018 // LIS->splitSeparateComponents(LI, SplitLIs);
1019 }
1020 }
1021 return Changed;
1022}
1023
1024bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
1025 // Skip if the vector extension is not enabled.
1026 ST = &MF.getSubtarget<RISCVSubtarget>();
1027 if (!ST->hasVInstructions())
1028 return false;
1029
1030 LLVM_DEBUG(dbgs() << "Entering InsertVSETVLI for " << MF.getName() << "\n");
1031
1032 TII = ST->getInstrInfo();
1033 MRI = &MF.getRegInfo();
1034 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
1035 LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
1036 VIA = RISCVVSETVLIInfoAnalysis(ST, LIS);
1037
1038 assert(BlockInfo.empty() && "Expect empty block infos");
1039 BlockInfo.resize(MF.getNumBlockIDs());
1040
1041 bool HaveVectorOp = false;
1042
1043 // Phase 1 - determine how VL/VTYPE are affected by the each block.
1044 for (const MachineBasicBlock &MBB : MF) {
1045 VSETVLIInfo TmpStatus;
1046 HaveVectorOp |= computeVLVTYPEChanges(MBB, TmpStatus);
1047 // Initial exit state is whatever change we found in the block.
1048 BlockData &BBInfo = BlockInfo[MBB.getNumber()];
1049 BBInfo.Exit = TmpStatus;
1050 LLVM_DEBUG(dbgs() << "Initial exit state of " << printMBBReference(MBB)
1051 << " is " << BBInfo.Exit << "\n");
1052
1053 }
1054
1055 // If we didn't find any instructions that need VSETVLI, we're done.
1056 if (!HaveVectorOp) {
1057 BlockInfo.clear();
1058 return false;
1059 }
1060
1061 // Phase 2 - determine the exit VL/VTYPE from each block. We add all
1062 // blocks to the list here, but will also add any that need to be revisited
1063 // during Phase 2 processing.
1064 for (const MachineBasicBlock &MBB : MF) {
1065 WorkList.push(&MBB);
1066 BlockInfo[MBB.getNumber()].InQueue = true;
1067 }
1068 while (!WorkList.empty()) {
1069 const MachineBasicBlock &MBB = *WorkList.front();
1070 WorkList.pop();
1071 computeIncomingVLVTYPE(MBB);
1072 }
1073
1074 // Perform partial redundancy elimination of vsetvli transitions.
1075 for (MachineBasicBlock &MBB : MF)
1076 doPRE(MBB);
1077
1078 // Phase 3 - add any vsetvli instructions needed in the block. Use the
1079 // Phase 2 information to avoid adding vsetvlis before the first vector
1080 // instruction in the block if the VL/VTYPE is satisfied by its
1081 // predecessors.
1082 for (MachineBasicBlock &MBB : MF)
1083 emitVSETVLIs(MBB);
1084
1085 // Now that all vsetvlis are explicit, go through and do block local
1086 // DSE and peephole based demanded fields based transforms. Note that
1087 // this *must* be done outside the main dataflow so long as we allow
1088 // any cross block analysis within the dataflow. We can't have both
1089 // demanded fields based mutation and non-local analysis in the
1090 // dataflow at the same time without introducing inconsistencies.
1091 // We're visiting blocks from the bottom up because a VSETVLI in the
1092 // earlier block might become dead when its uses in later blocks are
1093 // optimized away.
1094 for (MachineBasicBlock *MBB : post_order(&MF))
1095 coalesceVSETVLIs(*MBB);
1096
1097 // Insert PseudoReadVL after VLEFF/VLSEGFF and replace it with the vl output
1098 // of VLEFF/VLSEGFF.
1099 for (MachineBasicBlock &MBB : MF)
1100 insertReadVL(MBB);
1101
1102 for (MachineBasicBlock &MBB : MF) {
1103 insertVSETMTK(MBB, VSETTM);
1104 insertVSETMTK(MBB, VSETTK);
1105 }
1106
1107 BlockInfo.clear();
1108 return HaveVectorOp;
1109}
1110
1111/// Returns an instance of the Insert VSETVLI pass.
1113 return new RISCVInsertVSETVLI();
1114}
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
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 cl::opt< bool > EnsureWholeVectorRegisterMoveValidVTYPE(DEBUG_TYPE "-whole-vector-register-move-valid-vtype", cl::Hidden, cl::desc("Insert vsetvlis before vmvNr.vs to ensure vtype is valid and " "vill is cleared"), cl::init(true))
static VSETVLIInfo adjustIncoming(const VSETVLIInfo &PrevInfo, const VSETVLIInfo &NewInfo, DemandedFields &Demanded)
#define RISCV_INSERT_VSETVLI_NAME
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:114
BlockData()=default
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:270
A debug info location.
Definition DebugLoc.h:123
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
LiveInterval - This class represents the liveness of a register, or stack slot.
void setWeight(float Value)
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.
Representation of each machine instruction.
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 MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
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
const VNInfo * getAVLVNInfo() 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:66
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...
Changed
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)
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.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Dead
Unused definition.
@ Define
Register 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:634
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:331
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:207
FunctionPass * createRISCVInsertVSETVLIPass()
Returns an instance of the Insert VSETVLI pass.
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 & RISCVInsertVSETVLIID
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