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.
11 //
12 // This pass consists of 3 phases:
13 //
14 // Phase 1 collects how each basic block affects VL/VTYPE.
15 //
16 // Phase 2 uses the information from phase 1 to do a data flow analysis to
17 // propagate the VL/VTYPE changes through the function. This gives us the
18 // VL/VTYPE at the start of each basic block.
19 //
20 // Phase 3 inserts VSETVLI instructions in each basic block. Information from
21 // phase 2 is used to prevent inserting a VSETVLI before the first vector
22 // instruction in the block if possible.
23 //
24 //===----------------------------------------------------------------------===//
25 
26 #include "RISCV.h"
27 #include "RISCVSubtarget.h"
28 #include "llvm/CodeGen/LiveIntervals.h"
29 #include "llvm/CodeGen/MachineFunctionPass.h"
30 #include <queue>
31 using namespace llvm;
32 
33 #define DEBUG_TYPE "riscv-insert-vsetvli"
34 #define RISCV_INSERT_VSETVLI_NAME "RISCV Insert VSETVLI pass"
35 
36 static cl::opt<bool> DisableInsertVSETVLPHIOpt(
37     "riscv-disable-insert-vsetvl-phi-opt", cl::init(false), cl::Hidden,
38     cl::desc("Disable looking through phis when inserting vsetvlis."));
39 
40 namespace {
41 
42 class VSETVLIInfo {
43   union {
44     Register AVLReg;
45     unsigned AVLImm;
46   };
47 
48   enum : uint8_t {
49     Uninitialized,
50     AVLIsReg,
51     AVLIsImm,
52     Unknown,
53   } State = Uninitialized;
54 
55   // Fields from VTYPE.
56   RISCVII::VLMUL VLMul = RISCVII::LMUL_1;
57   uint8_t SEW = 0;
58   bool TailAgnostic = false;
59   bool MaskAgnostic = false;
60 
61 public:
62   VSETVLIInfo() : AVLImm(0) {}
63 
64   static VSETVLIInfo getUnknown() {
65     VSETVLIInfo Info;
66     Info.setUnknown();
67     return Info;
68   }
69 
70   bool isValid() const { return State != Uninitialized; }
71   void setUnknown() { State = Unknown; }
72   bool isUnknown() const { return State == Unknown; }
73 
74   void setAVLReg(Register Reg) {
75     AVLReg = Reg;
76     State = AVLIsReg;
77   }
78 
79   void setAVLImm(unsigned Imm) {
80     AVLImm = Imm;
81     State = AVLIsImm;
82   }
83 
84   bool hasAVLImm() const { return State == AVLIsImm; }
85   bool hasAVLReg() const { return State == AVLIsReg; }
86   Register getAVLReg() const {
87     assert(hasAVLReg());
88     return AVLReg;
89   }
90   unsigned getAVLImm() const {
91     assert(hasAVLImm());
92     return AVLImm;
93   }
94 
95   bool hasSameAVL(const VSETVLIInfo &Other) const {
96     assert(isValid() && Other.isValid() &&
97            "Can't compare invalid VSETVLIInfos");
98     assert(!isUnknown() && !Other.isUnknown() &&
99            "Can't compare AVL in unknown state");
100     if (hasAVLReg() && Other.hasAVLReg())
101       return getAVLReg() == Other.getAVLReg();
102 
103     if (hasAVLImm() && Other.hasAVLImm())
104       return getAVLImm() == Other.getAVLImm();
105 
106     return false;
107   }
108 
109   void setVTYPE(unsigned VType) {
110     assert(isValid() && !isUnknown() &&
111            "Can't set VTYPE for uninitialized or unknown");
112     VLMul = RISCVVType::getVLMUL(VType);
113     SEW = RISCVVType::getSEW(VType);
114     TailAgnostic = RISCVVType::isTailAgnostic(VType);
115     MaskAgnostic = RISCVVType::isMaskAgnostic(VType);
116   }
117   void setVTYPE(RISCVII::VLMUL L, unsigned S, bool TA, bool MA) {
118     assert(isValid() && !isUnknown() &&
119            "Can't set VTYPE for uninitialized or unknown");
120     VLMul = L;
121     SEW = S;
122     TailAgnostic = TA;
123     MaskAgnostic = MA;
124   }
125 
126   unsigned encodeVTYPE() const {
127     assert(isValid() && !isUnknown() &&
128            "Can't encode VTYPE for uninitialized or unknown");
129     return RISCVVType::encodeVTYPE(VLMul, SEW, TailAgnostic, MaskAgnostic);
130   }
131 
132   bool hasSameVTYPE(const VSETVLIInfo &Other) const {
133     assert(isValid() && Other.isValid() &&
134            "Can't compare invalid VSETVLIInfos");
135     assert(!isUnknown() && !Other.isUnknown() &&
136            "Can't compare VTYPE in unknown state");
137     return std::tie(VLMul, SEW, TailAgnostic, MaskAgnostic) ==
138            std::tie(Other.VLMul, Other.SEW, Other.TailAgnostic,
139                     Other.MaskAgnostic);
140   }
141 
142   // Convert VLMUL to a fixed point value with 3 bits of fraction.
143   unsigned getSEWLMULRatio() const {
144     assert(isValid() && !isUnknown() &&
145            "Can't use VTYPE for uninitialized or unknown");
146     unsigned LMul;
147     bool Fractional;
148     std::tie(LMul, Fractional) = RISCVVType::decodeVLMUL(VLMul);
149 
150     // Convert LMul to a fixed point value with 3 fractional bits.
151     LMul = Fractional ? (8 / LMul) : (LMul * 8);
152 
153     assert(SEW >= 8 && "Unexpected SEW value");
154     return (SEW * 8) / LMul;
155   }
156 
157   // Check if the VTYPE for these two VSETVLIInfos produce the same VLMAX.
158   bool hasSameVLMAX(const VSETVLIInfo &Other) const {
159     assert(isValid() && Other.isValid() &&
160            "Can't compare invalid VSETVLIInfos");
161     assert(!isUnknown() && !Other.isUnknown() &&
162            "Can't compare VTYPE in unknown state");
163     return getSEWLMULRatio() == Other.getSEWLMULRatio();
164   }
165 
166   bool isCompatible(const VSETVLIInfo &Other) const {
167     assert(isValid() && Other.isValid() &&
168            "Can't compare invalid VSETVLIInfos");
169     // Nothing is compatible with Unknown.
170     if (isUnknown() || Other.isUnknown())
171       return false;
172 
173     // If other doesn't need an AVLReg and the SEW matches, consider it
174     // compatible.
175     if (Other.hasAVLReg() && Other.AVLReg == RISCV::NoRegister) {
176       if (SEW == Other.SEW)
177         return true;
178     }
179 
180     // VTypes must match.
181     if (!hasSameVTYPE(Other))
182       return false;
183 
184     if (hasAVLImm() != Other.hasAVLImm())
185       return false;
186 
187     if (hasAVLImm())
188       return getAVLImm() == Other.getAVLImm();
189 
190     return getAVLReg() == Other.getAVLReg();
191   }
192 
193   bool operator==(const VSETVLIInfo &Other) const {
194     // Uninitialized is only equal to another Uninitialized.
195     if (!isValid())
196       return !Other.isValid();
197     if (!Other.isValid())
198       return !isValid();
199 
200     // Unknown is only equal to another Unknown.
201     if (isUnknown())
202       return Other.isUnknown();
203     if (Other.isUnknown())
204       return isUnknown();
205 
206     // Otherwise compare the VTYPE and AVL.
207     return hasSameVTYPE(Other) && hasSameAVL(Other);
208   }
209 
210   bool operator!=(const VSETVLIInfo &Other) const { return !(*this == Other); }
211 
212   // Calculate the VSETVLIInfo visible to a block assuming this and Other are
213   // both predecessors.
214   VSETVLIInfo intersect(const VSETVLIInfo &Other) const {
215     // If the new value isn't valid, ignore it.
216     if (!Other.isValid())
217       return *this;
218 
219     // If this value isn't valid, this must be the first predecessor, use it.
220     if (!isValid())
221       return Other;
222 
223     if (*this == Other)
224       return *this;
225 
226     // If the configurations don't match, assume unknown.
227     return VSETVLIInfo::getUnknown();
228   }
229 
230   // Calculate the VSETVLIInfo visible at the end of the block assuming this
231   // is the predecessor value, and Other is change for this block.
232   VSETVLIInfo merge(const VSETVLIInfo &Other) const {
233     assert(isValid() && "Can only merge with a valid VSETVLInfo");
234 
235     // Nothing changed from the predecessor, keep it.
236     if (!Other.isValid())
237       return *this;
238 
239     // If the change is compatible with the input, we won't create a VSETVLI
240     // and should keep the predecessor.
241     if (isCompatible(Other))
242       return *this;
243 
244     // Otherwise just use whatever is in this block.
245     return Other;
246   }
247 };
248 
249 struct BlockData {
250   // The VSETVLIInfo that represents the net changes to the VL/VTYPE registers
251   // made by this block. Calculated in Phase 1.
252   VSETVLIInfo Change;
253 
254   // The VSETVLIInfo that represents the VL/VTYPE settings on exit from this
255   // block. Calculated in Phase 2.
256   VSETVLIInfo Exit;
257 
258   // The VSETVLIInfo that represents the VL/VTYPE settings from all predecessor
259   // blocks. Calculated in Phase 2, and used by Phase 3.
260   VSETVLIInfo Pred;
261 
262   // Keeps track of whether the block is already in the queue.
263   bool InQueue = false;
264 
265   BlockData() {}
266 };
267 
268 class RISCVInsertVSETVLI : public MachineFunctionPass {
269   const TargetInstrInfo *TII;
270   MachineRegisterInfo *MRI;
271 
272   std::vector<BlockData> BlockInfo;
273   std::queue<const MachineBasicBlock *> WorkList;
274 
275 public:
276   static char ID;
277 
278   RISCVInsertVSETVLI() : MachineFunctionPass(ID) {
279     initializeRISCVInsertVSETVLIPass(*PassRegistry::getPassRegistry());
280   }
281   bool runOnMachineFunction(MachineFunction &MF) override;
282 
283   void getAnalysisUsage(AnalysisUsage &AU) const override {
284     AU.setPreservesCFG();
285     MachineFunctionPass::getAnalysisUsage(AU);
286   }
287 
288   StringRef getPassName() const override { return RISCV_INSERT_VSETVLI_NAME; }
289 
290 private:
291   bool needVSETVLI(const VSETVLIInfo &Require, const VSETVLIInfo &CurInfo);
292   bool needVSETVLIPHI(const VSETVLIInfo &Require, const MachineBasicBlock &MBB);
293   void insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI,
294                      const VSETVLIInfo &Info, const VSETVLIInfo &PrevInfo);
295 
296   bool computeVLVTYPEChanges(const MachineBasicBlock &MBB);
297   void computeIncomingVLVTYPE(const MachineBasicBlock &MBB);
298   void emitVSETVLIs(MachineBasicBlock &MBB);
299 };
300 
301 } // end anonymous namespace
302 
303 char RISCVInsertVSETVLI::ID = 0;
304 
305 INITIALIZE_PASS(RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME,
306                 false, false)
307 
308 static MachineInstr *elideCopies(MachineInstr *MI,
309                                  const MachineRegisterInfo *MRI) {
310   while (true) {
311     if (!MI->isFullCopy())
312       return MI;
313     if (!Register::isVirtualRegister(MI->getOperand(1).getReg()))
314       return nullptr;
315     MI = MRI->getVRegDef(MI->getOperand(1).getReg());
316     if (!MI)
317       return nullptr;
318   }
319 }
320 
321 static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
322                                        const MachineRegisterInfo *MRI) {
323   VSETVLIInfo InstrInfo;
324   unsigned NumOperands = MI.getNumExplicitOperands();
325 
326   RISCVII::VLMUL VLMul = RISCVII::getLMul(TSFlags);
327 
328   unsigned Log2SEW = MI.getOperand(NumOperands - 1).getImm();
329   unsigned SEW = 1 << Log2SEW;
330   assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
331 
332   // Default to tail agnostic unless the destination is tied to a source.
333   // Unless the source is undef. In that case the user would have some control
334   // over the tail values. The tail policy is also ignored on instructions
335   // that only update element 0 like vmv.s.x or reductions so use agnostic
336   // there to match the common case.
337   // FIXME: This is conservatively correct, but we might want to detect that
338   // the input is undefined.
339   bool ForceTailAgnostic = RISCVII::doesForceTailAgnostic(TSFlags);
340   bool TailAgnostic = true;
341   unsigned UseOpIdx;
342   if (!ForceTailAgnostic && MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
343     TailAgnostic = false;
344     // If the tied operand is an IMPLICIT_DEF we can keep TailAgnostic.
345     const MachineOperand &UseMO = MI.getOperand(UseOpIdx);
346     MachineInstr *UseMI = MRI->getVRegDef(UseMO.getReg());
347     if (UseMI) {
348       UseMI = elideCopies(UseMI, MRI);
349       if (UseMI && UseMI->isImplicitDef())
350         TailAgnostic = true;
351     }
352   }
353 
354   if (RISCVII::hasVLOp(TSFlags)) {
355     const MachineOperand &VLOp = MI.getOperand(MI.getNumExplicitOperands() - 2);
356     if (VLOp.isImm())
357       InstrInfo.setAVLImm(VLOp.getImm());
358     else
359       InstrInfo.setAVLReg(VLOp.getReg());
360   } else
361     InstrInfo.setAVLReg(RISCV::NoRegister);
362   InstrInfo.setVTYPE(VLMul, SEW, /*TailAgnostic*/ TailAgnostic,
363                      /*MaskAgnostic*/ false);
364 
365   return InstrInfo;
366 }
367 
368 void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB, MachineInstr &MI,
369                                        const VSETVLIInfo &Info,
370                                        const VSETVLIInfo &PrevInfo) {
371   DebugLoc DL = MI.getDebugLoc();
372 
373   // Use X0, X0 form if the AVL is the same and the SEW+LMUL gives the same
374   // VLMAX.
375   if (PrevInfo.isValid() && !PrevInfo.isUnknown() &&
376       Info.hasSameAVL(PrevInfo) && Info.hasSameVLMAX(PrevInfo)) {
377     BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLI))
378         .addReg(RISCV::X0, RegState::Define | RegState::Dead)
379         .addReg(RISCV::X0, RegState::Kill)
380         .addImm(Info.encodeVTYPE())
381         .addReg(RISCV::VL, RegState::Implicit);
382     return;
383   }
384 
385   if (Info.hasAVLImm()) {
386     BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETIVLI))
387         .addReg(RISCV::X0, RegState::Define | RegState::Dead)
388         .addImm(Info.getAVLImm())
389         .addImm(Info.encodeVTYPE());
390     return;
391   }
392 
393   Register AVLReg = Info.getAVLReg();
394   if (AVLReg == RISCV::NoRegister) {
395     BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLI))
396         .addReg(RISCV::X0, RegState::Define | RegState::Dead)
397         .addReg(RISCV::X0, RegState::Kill)
398         .addImm(Info.encodeVTYPE())
399         .addReg(RISCV::VL, RegState::Implicit);
400     return;
401   }
402 
403   // Use X0 as the DestReg unless AVLReg is X0.
404   Register DestReg = RISCV::X0;
405   if (AVLReg == RISCV::X0)
406     DestReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
407   BuildMI(MBB, MI, DL, TII->get(RISCV::PseudoVSETVLI))
408       .addReg(DestReg, RegState::Define | RegState::Dead)
409       .addReg(AVLReg)
410       .addImm(Info.encodeVTYPE());
411 }
412 
413 // Return a VSETVLIInfo representing the changes made by this VSETVLI or
414 // VSETIVLI instruction.
415 static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
416   VSETVLIInfo NewInfo;
417   if (MI.getOpcode() == RISCV::PseudoVSETVLI) {
418     Register AVLReg = MI.getOperand(1).getReg();
419     assert((AVLReg != RISCV::X0 || MI.getOperand(0).getReg() != RISCV::X0) &&
420            "Can't handle X0, X0 vsetvli yet");
421     NewInfo.setAVLReg(AVLReg);
422   } else {
423     assert(MI.getOpcode() == RISCV::PseudoVSETIVLI);
424     NewInfo.setAVLImm(MI.getOperand(1).getImm());
425   }
426   NewInfo.setVTYPE(MI.getOperand(2).getImm());
427 
428   return NewInfo;
429 }
430 
431 bool RISCVInsertVSETVLI::needVSETVLI(const VSETVLIInfo &Require,
432                                      const VSETVLIInfo &CurInfo) {
433   if (CurInfo.isCompatible(Require))
434     return false;
435 
436   // We didn't find a compatible value. If our AVL is a virtual register,
437   // it might be defined by a VSET(I)VLI. If it has the same VTYPE we need
438   // and the last VL/VTYPE we observed is the same, we don't need a
439   // VSETVLI here.
440   if (!CurInfo.isUnknown() && Require.hasAVLReg() &&
441       Require.getAVLReg().isVirtual() && Require.hasSameVTYPE(CurInfo)) {
442     if (MachineInstr *DefMI = MRI->getVRegDef(Require.getAVLReg())) {
443       if (DefMI->getOpcode() == RISCV::PseudoVSETVLI ||
444           DefMI->getOpcode() == RISCV::PseudoVSETIVLI) {
445         VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
446         if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVTYPE(CurInfo))
447           return false;
448       }
449     }
450   }
451 
452   return true;
453 }
454 
455 bool RISCVInsertVSETVLI::computeVLVTYPEChanges(const MachineBasicBlock &MBB) {
456   bool HadVectorOp = false;
457 
458   BlockData &BBInfo = BlockInfo[MBB.getNumber()];
459   for (const MachineInstr &MI : MBB) {
460     // If this is an explicit VSETVLI or VSETIVLI, update our state.
461     if (MI.getOpcode() == RISCV::PseudoVSETVLI ||
462         MI.getOpcode() == RISCV::PseudoVSETIVLI) {
463       HadVectorOp = true;
464       BBInfo.Change = getInfoForVSETVLI(MI);
465       continue;
466     }
467 
468     uint64_t TSFlags = MI.getDesc().TSFlags;
469     if (RISCVII::hasSEWOp(TSFlags)) {
470       HadVectorOp = true;
471 
472       VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI);
473 
474       if (!BBInfo.Change.isValid()) {
475         BBInfo.Change = NewInfo;
476       } else {
477         // If this instruction isn't compatible with the previous VL/VTYPE
478         // we need to insert a VSETVLI.
479         if (needVSETVLI(NewInfo, BBInfo.Change))
480           BBInfo.Change = NewInfo;
481       }
482     }
483 
484     // If this is something that updates VL/VTYPE that we don't know about, set
485     // the state to unknown.
486     if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) ||
487         MI.modifiesRegister(RISCV::VTYPE)) {
488       BBInfo.Change = VSETVLIInfo::getUnknown();
489     }
490   }
491 
492   // Initial exit state is whatever change we found in the block.
493   BBInfo.Exit = BBInfo.Change;
494 
495   return HadVectorOp;
496 }
497 
498 void RISCVInsertVSETVLI::computeIncomingVLVTYPE(const MachineBasicBlock &MBB) {
499   BlockData &BBInfo = BlockInfo[MBB.getNumber()];
500 
501   BBInfo.InQueue = false;
502 
503   VSETVLIInfo InInfo;
504   if (MBB.pred_empty()) {
505     // There are no predecessors, so use the default starting status.
506     InInfo.setUnknown();
507   } else {
508     for (MachineBasicBlock *P : MBB.predecessors())
509       InInfo = InInfo.intersect(BlockInfo[P->getNumber()].Exit);
510   }
511 
512   // If we don't have any valid predecessor value, wait until we do.
513   if (!InInfo.isValid())
514     return;
515 
516   BBInfo.Pred = InInfo;
517 
518   VSETVLIInfo TmpStatus = BBInfo.Pred.merge(BBInfo.Change);
519 
520   // If the new exit value matches the old exit value, we don't need to revisit
521   // any blocks.
522   if (BBInfo.Exit == TmpStatus)
523     return;
524 
525   BBInfo.Exit = TmpStatus;
526 
527   // Add the successors to the work list so we can propagate the changed exit
528   // status.
529   for (MachineBasicBlock *S : MBB.successors())
530     if (!BlockInfo[S->getNumber()].InQueue)
531       WorkList.push(S);
532 }
533 
534 // If we weren't able to prove a vsetvli was directly unneeded, it might still
535 // be/ unneeded if the AVL is a phi node where all incoming values are VL
536 // outputs from the last VSETVLI in their respective basic blocks.
537 bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
538                                         const MachineBasicBlock &MBB) {
539   if (DisableInsertVSETVLPHIOpt)
540     return true;
541 
542   if (!Require.hasAVLReg())
543     return true;
544 
545   Register AVLReg = Require.getAVLReg();
546   if (!AVLReg.isVirtual())
547     return true;
548 
549   // We need the AVL to be produce by a PHI node in this basic block.
550   MachineInstr *PHI = MRI->getVRegDef(AVLReg);
551   if (!PHI || PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB)
552     return true;
553 
554   for (unsigned PHIOp = 1, NumOps = PHI->getNumOperands(); PHIOp != NumOps;
555        PHIOp += 2) {
556     Register InReg = PHI->getOperand(PHIOp).getReg();
557     MachineBasicBlock *PBB = PHI->getOperand(PHIOp + 1).getMBB();
558     const BlockData &PBBInfo = BlockInfo[PBB->getNumber()];
559     // If the exit from the predecessor has the VTYPE we are looking for
560     // we might be able to avoid a VSETVLI.
561     if (PBBInfo.Exit.isUnknown() || !PBBInfo.Exit.hasSameVTYPE(Require))
562       return true;
563 
564     // We need the PHI input to the be the output of a VSET(I)VLI.
565     MachineInstr *DefMI = MRI->getVRegDef(InReg);
566     if (!DefMI || (DefMI->getOpcode() != RISCV::PseudoVSETVLI &&
567                    DefMI->getOpcode() != RISCV::PseudoVSETIVLI))
568       return true;
569 
570     // We found a VSET(I)VLI make sure it matches the output of the
571     // predecessor block.
572     VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
573     if (!DefInfo.hasSameAVL(PBBInfo.Exit) ||
574         !DefInfo.hasSameVTYPE(PBBInfo.Exit))
575       return true;
576   }
577 
578   // If all the incoming values to the PHI checked out, we don't need
579   // to insert a VSETVLI.
580   return false;
581 }
582 
583 void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
584   VSETVLIInfo CurInfo;
585 
586   for (MachineInstr &MI : MBB) {
587     // If this is an explicit VSETVLI or VSETIVLI, update our state.
588     if (MI.getOpcode() == RISCV::PseudoVSETVLI ||
589         MI.getOpcode() == RISCV::PseudoVSETIVLI) {
590       // Conservatively, mark the VL and VTYPE as live.
591       assert(MI.getOperand(3).getReg() == RISCV::VL &&
592              MI.getOperand(4).getReg() == RISCV::VTYPE &&
593              "Unexpected operands where VL and VTYPE should be");
594       MI.getOperand(3).setIsDead(false);
595       MI.getOperand(4).setIsDead(false);
596       CurInfo = getInfoForVSETVLI(MI);
597       continue;
598     }
599 
600     uint64_t TSFlags = MI.getDesc().TSFlags;
601     if (RISCVII::hasSEWOp(TSFlags)) {
602       VSETVLIInfo NewInfo = computeInfoForInstr(MI, TSFlags, MRI);
603       if (RISCVII::hasVLOp(TSFlags)) {
604         MachineOperand &VLOp = MI.getOperand(MI.getNumExplicitOperands() - 2);
605         if (VLOp.isReg()) {
606           // Erase the AVL operand from the instruction.
607           VLOp.setReg(RISCV::NoRegister);
608           VLOp.setIsKill(false);
609         }
610         MI.addOperand(MachineOperand::CreateReg(RISCV::VL, /*isDef*/ false,
611                                                 /*isImp*/ true));
612       }
613       MI.addOperand(MachineOperand::CreateReg(RISCV::VTYPE, /*isDef*/ false,
614                                               /*isImp*/ true));
615 
616       if (!CurInfo.isValid()) {
617         // We haven't found any vector instructions or VL/VTYPE changes yet,
618         // use the predecessor information.
619         assert(BlockInfo[MBB.getNumber()].Pred.isValid() &&
620                "Expected a valid predecessor state.");
621         if (needVSETVLI(NewInfo, BlockInfo[MBB.getNumber()].Pred) &&
622             needVSETVLIPHI(NewInfo, MBB)) {
623           insertVSETVLI(MBB, MI, NewInfo, BlockInfo[MBB.getNumber()].Pred);
624           CurInfo = NewInfo;
625         }
626       } else {
627         // If this instruction isn't compatible with the previous VL/VTYPE
628         // we need to insert a VSETVLI.
629         if (needVSETVLI(NewInfo, CurInfo)) {
630           insertVSETVLI(MBB, MI, NewInfo, CurInfo);
631           CurInfo = NewInfo;
632         }
633       }
634     }
635 
636     // If this is something updates VL/VTYPE that we don't know about, set
637     // the state to unknown.
638     if (MI.isCall() || MI.isInlineAsm() || MI.modifiesRegister(RISCV::VL) ||
639         MI.modifiesRegister(RISCV::VTYPE)) {
640       CurInfo = VSETVLIInfo::getUnknown();
641     }
642   }
643 }
644 
645 bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
646   // Skip if the vector extension is not enabled.
647   const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
648   if (!ST.hasStdExtV())
649     return false;
650 
651   TII = ST.getInstrInfo();
652   MRI = &MF.getRegInfo();
653 
654   assert(BlockInfo.empty() && "Expect empty block infos");
655   BlockInfo.resize(MF.getNumBlockIDs());
656 
657   bool HaveVectorOp = false;
658 
659   // Phase 1 - determine how VL/VTYPE are affected by the each block.
660   for (const MachineBasicBlock &MBB : MF)
661     HaveVectorOp |= computeVLVTYPEChanges(MBB);
662 
663   // If we didn't find any instructions that need VSETVLI, we're done.
664   if (HaveVectorOp) {
665     // Phase 2 - determine the exit VL/VTYPE from each block. We add all
666     // blocks to the list here, but will also add any that need to be revisited
667     // during Phase 2 processing.
668     for (const MachineBasicBlock &MBB : MF) {
669       WorkList.push(&MBB);
670       BlockInfo[MBB.getNumber()].InQueue = true;
671     }
672     while (!WorkList.empty()) {
673       const MachineBasicBlock &MBB = *WorkList.front();
674       WorkList.pop();
675       computeIncomingVLVTYPE(MBB);
676     }
677 
678     // Phase 3 - add any vsetvli instructions needed in the block. Use the
679     // Phase 2 information to avoid adding vsetvlis before the first vector
680     // instruction in the block if the VL/VTYPE is satisfied by its
681     // predecessors.
682     for (MachineBasicBlock &MBB : MF)
683       emitVSETVLIs(MBB);
684   }
685 
686   BlockInfo.clear();
687 
688   return HaveVectorOp;
689 }
690 
691 /// Returns an instance of the Insert VSETVLI pass.
692 FunctionPass *llvm::createRISCVInsertVSETVLIPass() {
693   return new RISCVInsertVSETVLI();
694 }
695