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