[llvm] [NFC][RISCV] Keep AVLReg define instr inside VSETVLInfo (PR #89180)

Piyou Chen via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 25 04:11:59 PDT 2024


https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/89180

>From 2aed28e3cb115bbe9364be9530cf481dc16c1954 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Thu, 18 Apr 2024 00:30:46 -0700
Subject: [PATCH 1/6] [RISCV] Keep AVLReg define instr inside VSETVLInfo

Currently, the vsetvli pass track the define instruction through MRI->getVRegDef due to the SSA form.

This patch keeps the AVLReg DefMI within VSETVLInfo during construction. And replace MRI->getVRegDef(AVLReg) with getAVLRegDefMI().

This information is useful when vsetvli pass live in post-ra situation.

The testcases don't change because the VReg always has a unique def in SSA.
---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 47 ++++++++++++--------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 3d598dd6f708ef..c6146dad263a31 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -156,7 +156,7 @@ static std::optional<unsigned> getEEWForLoadStore(const MachineInstr &MI) {
   }
 }
 
-static bool isNonZeroLoadImmediate(MachineInstr &MI) {
+static bool isNonZeroLoadImmediate(const MachineInstr &MI) {
   return MI.getOpcode() == RISCV::ADDI &&
     MI.getOperand(1).isReg() && MI.getOperand(2).isImm() &&
     MI.getOperand(1).getReg() == RISCV::X0 &&
@@ -448,6 +448,8 @@ class VSETVLIInfo {
     unsigned AVLImm;
   };
 
+  const MachineInstr *AVLDefMI;
+
   enum : uint8_t {
     Uninitialized,
     AVLIsReg,
@@ -466,7 +468,7 @@ class VSETVLIInfo {
 
 public:
   VSETVLIInfo()
-      : AVLImm(0), TailAgnostic(false), MaskAgnostic(false),
+      : AVLImm(0), AVLDefMI(nullptr), TailAgnostic(false), MaskAgnostic(false),
         SEWLMULRatioOnly(false) {}
 
   static VSETVLIInfo getUnknown() {
@@ -493,6 +495,7 @@ class VSETVLIInfo {
   void setAVLVLMAX() { State = AVLIsVLMAX; }
 
   void setAVLIgnored() { State = AVLIsIgnored; }
+  void setAVLDefMI(const MachineInstr *DefMI) { AVLDefMI = DefMI; }
 
   bool hasAVLImm() const { return State == AVLIsImm; }
   bool hasAVLReg() const { return State == AVLIsReg; }
@@ -507,12 +510,16 @@ class VSETVLIInfo {
     return AVLImm;
   }
 
+  const MachineInstr *getAVLDefMI() const { return AVLDefMI; }
+
   void setAVL(VSETVLIInfo Info) {
     assert(Info.isValid());
     if (Info.isUnknown())
       setUnknown();
-    else if (Info.hasAVLReg())
+    else if (Info.hasAVLReg()) {
       setAVLReg(Info.getAVLReg());
+      setAVLDefMI(Info.getAVLDefMI());
+    }
     else if (Info.hasAVLVLMAX())
       setAVLVLMAX();
     else if (Info.hasAVLIgnored())
@@ -532,7 +539,7 @@ class VSETVLIInfo {
     if (hasAVLImm())
       return getAVLImm() > 0;
     if (hasAVLReg()) {
-      MachineInstr *MI = MRI.getUniqueVRegDef(getAVLReg());
+      const MachineInstr *MI = getAVLDefMI();
       assert(MI);
       return isNonZeroLoadImmediate(*MI);
     }
@@ -859,7 +866,8 @@ INITIALIZE_PASS(RISCVCoalesceVSETVLI, "riscv-coalesce-vsetvli",
 
 // Return a VSETVLIInfo representing the changes made by this VSETVLI or
 // VSETIVLI instruction.
-static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
+static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI,
+                                     const MachineRegisterInfo &MRI) {
   VSETVLIInfo NewInfo;
   if (MI.getOpcode() == RISCV::PseudoVSETIVLI) {
     NewInfo.setAVLImm(MI.getOperand(1).getImm());
@@ -872,7 +880,7 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
     if (AVLReg == RISCV::X0)
       NewInfo.setAVLVLMAX();
     else
-      NewInfo.setAVLReg(AVLReg);
+      NewInfo.setAVLDefMI(MRI.getVRegDef(AVLReg));
   }
   NewInfo.setVTYPE(MI.getOperand(2).getImm());
 
@@ -945,6 +953,8 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
         InstrInfo.setAVLImm(Imm);
     } else {
       InstrInfo.setAVLReg(VLOp.getReg());
+      if (VLOp.getReg().isVirtual())
+        InstrInfo.setAVLDefMI(MRI->getVRegDef(VLOp.getReg()));
     }
   } else {
     assert(isScalarExtractInstr(MI));
@@ -965,10 +975,9 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
   // register AVLs to avoid extending live ranges without being sure we can
   // kill the original source reg entirely.
   if (InstrInfo.hasAVLReg()) {
-    MachineInstr *DefMI = MRI->getUniqueVRegDef(InstrInfo.getAVLReg());
-    assert(DefMI);
+    const MachineInstr *DefMI = InstrInfo.getAVLDefMI();
     if (isVectorConfigInstr(*DefMI)) {
-      VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI);
+      VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI, *MRI);
       if (DefInstrInfo.hasSameVLMAX(InstrInfo) &&
           (DefInstrInfo.hasAVLImm() || DefInstrInfo.hasAVLVLMAX()))
         InstrInfo.setAVL(DefInstrInfo);
@@ -1006,10 +1015,10 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
     // it has the same VLMAX we want and the last VL/VTYPE we observed is the
     // same, we can use the X0, X0 form.
     if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
-      MachineInstr *DefMI = MRI->getUniqueVRegDef(Info.getAVLReg());
+      const MachineInstr *DefMI = Info.getAVLDefMI();
       assert(DefMI);
       if (isVectorConfigInstr(*DefMI)) {
-        VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
+        VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
         if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
           BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0))
               .addReg(RISCV::X0, RegState::Define | RegState::Dead)
@@ -1127,8 +1136,8 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
   if (Require.hasAVLReg() && CurInfo.hasCompatibleVTYPE(Used, Require)) {
     MachineInstr *DefMI = MRI->getUniqueVRegDef(Require.getAVLReg());
     assert(DefMI);
-    if (isVectorConfigInstr(*DefMI)) {
-      VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
+    if (Require.getAVLDefMI() && isVectorConfigInstr(*Require.getAVLDefMI())) {
+      VSETVLIInfo DefInfo = getInfoForVSETVLI(*Require.getAVLDefMI(), *MRI);
       if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo))
         return false;
     }
@@ -1214,13 +1223,15 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
 void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
                                        const MachineInstr &MI) const {
   if (isVectorConfigInstr(MI)) {
-    Info = getInfoForVSETVLI(MI);
+    Info = getInfoForVSETVLI(MI, *MRI);
     return;
   }
 
   if (RISCV::isFaultFirstLoad(MI)) {
     // Update AVL to vl-output of the fault first load.
     Info.setAVLReg(MI.getOperand(1).getReg());
+    if (MI.getOperand(1).getReg().isVirtual())
+      Info.setAVLDefMI(MRI->getVRegDef(MI.getOperand(1).getReg()));
     return;
   }
 
@@ -1339,7 +1350,7 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
 
     // We found a VSET(I)VLI make sure it matches the output of the
     // predecessor block.
-    VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
+    VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
     if (!DefInfo.hasSameAVL(PBBInfo.Exit) ||
         !DefInfo.hasSameVTYPE(PBBInfo.Exit))
       return true;
@@ -1488,7 +1499,7 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
   // we need to prove the value is available at the point we're going
   // to insert the vsetvli at.
   if (AvailableInfo.hasAVLReg()) {
-    MachineInstr *AVLDefMI = MRI->getUniqueVRegDef(AvailableInfo.getAVLReg());
+    const MachineInstr *AVLDefMI = AvailableInfo.getAVLDefMI();
     assert(AVLDefMI);
     // This is an inline dominance check which covers the case of
     // UnavailablePred being the preheader of a loop.
@@ -1573,8 +1584,8 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
     if (Used.VLZeroness) {
       if (isVLPreservingConfig(PrevMI))
         return false;
-      if (!getInfoForVSETVLI(PrevMI).hasEquallyZeroAVL(getInfoForVSETVLI(MI),
-                                                       MRI))
+      if (!getInfoForVSETVLI(PrevMI, MRI)
+               .hasEquallyZeroAVL(getInfoForVSETVLI(MI, MRI), MRI))
         return false;
     }
 

>From 0e8d15809d916619be95bd71b31e8617b6411e3d Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 24 Apr 2024 07:24:12 -0700
Subject: [PATCH 2/6] Get rid of MRI from hasNonZeroAVL and hasEquallyZeroAVL

---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index c6146dad263a31..2843c2698fddf2 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -535,7 +535,7 @@ class VSETVLIInfo {
   bool getTailAgnostic() const { return TailAgnostic; }
   bool getMaskAgnostic() const { return MaskAgnostic; }
 
-  bool hasNonZeroAVL(const MachineRegisterInfo &MRI) const {
+  bool hasNonZeroAVL() const {
     if (hasAVLImm())
       return getAVLImm() > 0;
     if (hasAVLReg()) {
@@ -550,11 +550,10 @@ class VSETVLIInfo {
     return false;
   }
 
-  bool hasEquallyZeroAVL(const VSETVLIInfo &Other,
-                         const MachineRegisterInfo &MRI) const {
+  bool hasEquallyZeroAVL(const VSETVLIInfo &Other) const {
     if (hasSameAVL(Other))
       return true;
-    return (hasNonZeroAVL(MRI) && Other.hasNonZeroAVL(MRI));
+    return (hasNonZeroAVL() && Other.hasNonZeroAVL());
   }
 
   bool hasSameAVL(const VSETVLIInfo &Other) const {
@@ -655,7 +654,7 @@ class VSETVLIInfo {
     if (Used.VLAny && !(hasSameAVL(Require) && hasSameVLMAX(Require)))
       return false;
 
-    if (Used.VLZeroness && !hasEquallyZeroAVL(Require, MRI))
+    if (Used.VLZeroness && !hasEquallyZeroAVL(Require))
       return false;
 
     return hasCompatibleVTYPE(Used, Require);
@@ -1192,7 +1191,7 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
   // variant, so we avoid the transform to prevent extending live range of an
   // avl register operand.
   // TODO: We can probably relax this for immediates.
-  bool EquallyZero = IncomingInfo.hasEquallyZeroAVL(PrevInfo, *MRI) &&
+  bool EquallyZero = IncomingInfo.hasEquallyZeroAVL(PrevInfo) &&
                      IncomingInfo.hasSameVLMAX(PrevInfo);
   if (Demanded.VLAny || (Demanded.VLZeroness && !EquallyZero))
     Info.setAVL(IncomingInfo);
@@ -1585,7 +1584,7 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
       if (isVLPreservingConfig(PrevMI))
         return false;
       if (!getInfoForVSETVLI(PrevMI, MRI)
-               .hasEquallyZeroAVL(getInfoForVSETVLI(MI, MRI), MRI))
+               .hasEquallyZeroAVL(getInfoForVSETVLI(MI, MRI)))
         return false;
     }
 

>From 32b4e045f97eccd0c74220419ab6cc5b617214bd Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 24 Apr 2024 21:29:41 -0700
Subject: [PATCH 3/6] Merge setDefMI into setReg

---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 30 ++++++++++----------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 2843c2698fddf2..a411ebeb1aada0 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -452,7 +452,7 @@ class VSETVLIInfo {
 
   enum : uint8_t {
     Uninitialized,
-    AVLIsReg,
+    AVLIsDefMI,
     AVLIsImm,
     AVLIsVLMAX,
     AVLIsIgnored,
@@ -481,10 +481,11 @@ class VSETVLIInfo {
   void setUnknown() { State = Unknown; }
   bool isUnknown() const { return State == Unknown; }
 
-  void setAVLReg(Register Reg) {
+  void setAVLReg(Register Reg, const MachineInstr *DefMI) {
     assert(Reg.isVirtual());
     AVLReg = Reg;
-    State = AVLIsReg;
+    AVLDefMI = DefMI;
+    State = AVLIsDefMI;
   }
 
   void setAVLImm(unsigned Imm) {
@@ -498,7 +499,7 @@ class VSETVLIInfo {
   void setAVLDefMI(const MachineInstr *DefMI) { AVLDefMI = DefMI; }
 
   bool hasAVLImm() const { return State == AVLIsImm; }
-  bool hasAVLReg() const { return State == AVLIsReg; }
+  bool hasAVLReg() const { return State == AVLIsDefMI; }
   bool hasAVLVLMAX() const { return State == AVLIsVLMAX; }
   bool hasAVLIgnored() const { return State == AVLIsIgnored; }
   Register getAVLReg() const {
@@ -516,10 +517,8 @@ class VSETVLIInfo {
     assert(Info.isValid());
     if (Info.isUnknown())
       setUnknown();
-    else if (Info.hasAVLReg()) {
-      setAVLReg(Info.getAVLReg());
-      setAVLDefMI(Info.getAVLDefMI());
-    }
+    else if (Info.hasAVLReg())
+      setAVLReg(Info.getAVLReg(), Info.getAVLDefMI());
     else if (Info.hasAVLVLMAX())
       setAVLVLMAX();
     else if (Info.hasAVLIgnored())
@@ -879,7 +878,7 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI,
     if (AVLReg == RISCV::X0)
       NewInfo.setAVLVLMAX();
     else
-      NewInfo.setAVLDefMI(MRI.getVRegDef(AVLReg));
+      NewInfo.setAVLReg(AVLReg, MRI.getVRegDef(AVLReg));
   }
   NewInfo.setVTYPE(MI.getOperand(2).getImm());
 
@@ -951,9 +950,9 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
       else
         InstrInfo.setAVLImm(Imm);
     } else {
-      InstrInfo.setAVLReg(VLOp.getReg());
-      if (VLOp.getReg().isVirtual())
-        InstrInfo.setAVLDefMI(MRI->getVRegDef(VLOp.getReg()));
+      InstrInfo.setAVLReg(VLOp.getReg(), VLOp.getReg().isVirtual()
+                                             ? MRI->getVRegDef(VLOp.getReg())
+                                             : nullptr);
     }
   } else {
     assert(isScalarExtractInstr(MI));
@@ -1228,9 +1227,10 @@ void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
 
   if (RISCV::isFaultFirstLoad(MI)) {
     // Update AVL to vl-output of the fault first load.
-    Info.setAVLReg(MI.getOperand(1).getReg());
-    if (MI.getOperand(1).getReg().isVirtual())
-      Info.setAVLDefMI(MRI->getVRegDef(MI.getOperand(1).getReg()));
+    Info.setAVLReg(MI.getOperand(1).getReg(),
+                   MI.getOperand(1).getReg().isVirtual()
+                       ? MRI->getVRegDef(MI.getOperand(1).getReg())
+                       : nullptr);
     return;
   }
 

>From 25ecf90f04520efeca844f2bc4e8c0a8fa22d43e Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 24 Apr 2024 23:08:35 -0700
Subject: [PATCH 4/6] Replace the setAVLReg and AVLIsReg with DefMI

---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 69 +++++++++-----------
 1 file changed, 30 insertions(+), 39 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index a411ebeb1aada0..c3e869ecf8f2c2 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -444,12 +444,10 @@ DemandedFields getDemanded(const MachineInstr &MI,
 /// values of the VL and VTYPE registers after insertion.
 class VSETVLIInfo {
   union {
-    Register AVLReg;
+    const MachineInstr *AVLDefMI;
     unsigned AVLImm;
   };
 
-  const MachineInstr *AVLDefMI;
-
   enum : uint8_t {
     Uninitialized,
     AVLIsDefMI,
@@ -468,7 +466,7 @@ class VSETVLIInfo {
 
 public:
   VSETVLIInfo()
-      : AVLImm(0), AVLDefMI(nullptr), TailAgnostic(false), MaskAgnostic(false),
+      : AVLImm(0), TailAgnostic(false), MaskAgnostic(false),
         SEWLMULRatioOnly(false) {}
 
   static VSETVLIInfo getUnknown() {
@@ -481,9 +479,8 @@ class VSETVLIInfo {
   void setUnknown() { State = Unknown; }
   bool isUnknown() const { return State == Unknown; }
 
-  void setAVLReg(Register Reg, const MachineInstr *DefMI) {
-    assert(Reg.isVirtual());
-    AVLReg = Reg;
+  void setAVLDefMI(const MachineInstr *DefMI) {
+    assert(DefMI);
     AVLDefMI = DefMI;
     State = AVLIsDefMI;
   }
@@ -496,29 +493,31 @@ class VSETVLIInfo {
   void setAVLVLMAX() { State = AVLIsVLMAX; }
 
   void setAVLIgnored() { State = AVLIsIgnored; }
-  void setAVLDefMI(const MachineInstr *DefMI) { AVLDefMI = DefMI; }
 
   bool hasAVLImm() const { return State == AVLIsImm; }
-  bool hasAVLReg() const { return State == AVLIsDefMI; }
+  bool hasAVLDefMI() const { return State == AVLIsDefMI; }
   bool hasAVLVLMAX() const { return State == AVLIsVLMAX; }
   bool hasAVLIgnored() const { return State == AVLIsIgnored; }
   Register getAVLReg() const {
-    assert(hasAVLReg());
-    return AVLReg;
+    assert(hasAVLDefMI());
+    return AVLDefMI->getOperand(0).getReg();
   }
   unsigned getAVLImm() const {
     assert(hasAVLImm());
     return AVLImm;
   }
 
-  const MachineInstr *getAVLDefMI() const { return AVLDefMI; }
+  const MachineInstr *getAVLDefMI() const {
+    assert(AVLDefMI);
+    return AVLDefMI;
+  }
 
   void setAVL(VSETVLIInfo Info) {
     assert(Info.isValid());
     if (Info.isUnknown())
       setUnknown();
-    else if (Info.hasAVLReg())
-      setAVLReg(Info.getAVLReg(), Info.getAVLDefMI());
+    else if (Info.hasAVLDefMI())
+      setAVLDefMI(Info.getAVLDefMI());
     else if (Info.hasAVLVLMAX())
       setAVLVLMAX();
     else if (Info.hasAVLIgnored())
@@ -537,7 +536,7 @@ class VSETVLIInfo {
   bool hasNonZeroAVL() const {
     if (hasAVLImm())
       return getAVLImm() > 0;
-    if (hasAVLReg()) {
+    if (hasAVLDefMI()) {
       const MachineInstr *MI = getAVLDefMI();
       assert(MI);
       return isNonZeroLoadImmediate(*MI);
@@ -556,8 +555,8 @@ class VSETVLIInfo {
   }
 
   bool hasSameAVL(const VSETVLIInfo &Other) const {
-    if (hasAVLReg() && Other.hasAVLReg())
-      return getAVLReg() == Other.getAVLReg();
+    if (hasAVLDefMI() && Other.hasAVLDefMI())
+      return getAVLDefMI()->isIdenticalTo(*Other.getAVLDefMI());
 
     if (hasAVLImm() && Other.hasAVLImm())
       return getAVLImm() == Other.getAVLImm();
@@ -737,8 +736,8 @@ class VSETVLIInfo {
       OS << "Uninitialized";
     if (isUnknown())
       OS << "unknown";
-    if (hasAVLReg())
-      OS << "AVLReg=" << (unsigned)AVLReg;
+    if (hasAVLDefMI())
+      OS << "AVLReg=" << (unsigned)getAVLReg();
     if (hasAVLImm())
       OS << "AVLImm=" << (unsigned)AVLImm;
     if (hasAVLVLMAX())
@@ -878,7 +877,7 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI,
     if (AVLReg == RISCV::X0)
       NewInfo.setAVLVLMAX();
     else
-      NewInfo.setAVLReg(AVLReg, MRI.getVRegDef(AVLReg));
+      NewInfo.setAVLDefMI(MRI.getVRegDef(AVLReg));
   }
   NewInfo.setVTYPE(MI.getOperand(2).getImm());
 
@@ -950,9 +949,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
       else
         InstrInfo.setAVLImm(Imm);
     } else {
-      InstrInfo.setAVLReg(VLOp.getReg(), VLOp.getReg().isVirtual()
-                                             ? MRI->getVRegDef(VLOp.getReg())
-                                             : nullptr);
+      InstrInfo.setAVLDefMI(MRI->getVRegDef(VLOp.getReg()));
     }
   } else {
     assert(isScalarExtractInstr(MI));
@@ -972,7 +969,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
   // AVL operand with the AVL of the defining vsetvli.  We avoid general
   // register AVLs to avoid extending live ranges without being sure we can
   // kill the original source reg entirely.
-  if (InstrInfo.hasAVLReg()) {
+  if (InstrInfo.hasAVLDefMI()) {
     const MachineInstr *DefMI = InstrInfo.getAVLDefMI();
     if (isVectorConfigInstr(*DefMI)) {
       VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI, *MRI);
@@ -1012,7 +1009,7 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
     // If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If
     // it has the same VLMAX we want and the last VL/VTYPE we observed is the
     // same, we can use the X0, X0 form.
-    if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
+    if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLDefMI()) {
       const MachineInstr *DefMI = Info.getAVLDefMI();
       assert(DefMI);
       if (isVectorConfigInstr(*DefMI)) {
@@ -1131,11 +1128,11 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
   // it might be defined by a VSET(I)VLI. If it has the same VLMAX we need
   // and the last VL/VTYPE we observed is the same, we don't need a
   // VSETVLI here.
-  if (Require.hasAVLReg() && CurInfo.hasCompatibleVTYPE(Used, Require)) {
-    MachineInstr *DefMI = MRI->getUniqueVRegDef(Require.getAVLReg());
+  if (Require.hasAVLDefMI() && CurInfo.hasCompatibleVTYPE(Used, Require)) {
+    const MachineInstr *DefMI = Require.getAVLDefMI();
     assert(DefMI);
-    if (Require.getAVLDefMI() && isVectorConfigInstr(*Require.getAVLDefMI())) {
-      VSETVLIInfo DefInfo = getInfoForVSETVLI(*Require.getAVLDefMI(), *MRI);
+    if (DefMI && isVectorConfigInstr(*DefMI)) {
+      VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
       if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo))
         return false;
     }
@@ -1227,10 +1224,7 @@ void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
 
   if (RISCV::isFaultFirstLoad(MI)) {
     // Update AVL to vl-output of the fault first load.
-    Info.setAVLReg(MI.getOperand(1).getReg(),
-                   MI.getOperand(1).getReg().isVirtual()
-                       ? MRI->getVRegDef(MI.getOperand(1).getReg())
-                       : nullptr);
+    Info.setAVLDefMI(MRI->getVRegDef(MI.getOperand(1).getReg()));
     return;
   }
 
@@ -1321,14 +1315,11 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
   if (DisableInsertVSETVLPHIOpt)
     return true;
 
-  if (!Require.hasAVLReg())
+  if (!Require.hasAVLDefMI())
     return true;
 
-  Register AVLReg = Require.getAVLReg();
-
   // We need the AVL to be produce by a PHI node in this basic block.
-  MachineInstr *PHI = MRI->getUniqueVRegDef(AVLReg);
-  assert(PHI);
+  const MachineInstr *PHI = Require.getAVLDefMI();
   if (PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB)
     return true;
 
@@ -1497,7 +1488,7 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
   // If the AVL value is a register (other than our VLMAX sentinel),
   // we need to prove the value is available at the point we're going
   // to insert the vsetvli at.
-  if (AvailableInfo.hasAVLReg()) {
+  if (AvailableInfo.hasAVLDefMI()) {
     const MachineInstr *AVLDefMI = AvailableInfo.getAVLDefMI();
     assert(AVLDefMI);
     // This is an inline dominance check which covers the case of

>From 94949dcd8842c0e432d022ac060c5844cda4b3be Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Thu, 25 Apr 2024 03:56:38 -0700
Subject: [PATCH 5/6] Store both AVLReg and AVLRegDefMI

---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 59 ++++++++++----------
 1 file changed, 30 insertions(+), 29 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index c3e869ecf8f2c2..e5392a054bf3b9 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -443,14 +443,18 @@ DemandedFields getDemanded(const MachineInstr &MI,
 /// Defines the abstract state with which the forward dataflow models the
 /// values of the VL and VTYPE registers after insertion.
 class VSETVLIInfo {
+  struct AVLDef {
+    const MachineInstr *DefMI;
+    Register DefReg;
+  };
   union {
-    const MachineInstr *AVLDefMI;
+    AVLDef AVLRegDef;
     unsigned AVLImm;
   };
 
   enum : uint8_t {
     Uninitialized,
-    AVLIsDefMI,
+    AVLIsReg,
     AVLIsImm,
     AVLIsVLMAX,
     AVLIsIgnored,
@@ -479,10 +483,11 @@ class VSETVLIInfo {
   void setUnknown() { State = Unknown; }
   bool isUnknown() const { return State == Unknown; }
 
-  void setAVLDefMI(const MachineInstr *DefMI) {
-    assert(DefMI);
-    AVLDefMI = DefMI;
-    State = AVLIsDefMI;
+  void setAVLRegDef(const MachineInstr *DefMI, Register AVLReg) {
+    assert(DefMI && AVLReg.isVirtual());
+    AVLRegDef.DefMI = DefMI;
+    AVLRegDef.DefReg = AVLReg;
+    State = AVLIsReg;
   }
 
   void setAVLImm(unsigned Imm) {
@@ -495,29 +500,28 @@ class VSETVLIInfo {
   void setAVLIgnored() { State = AVLIsIgnored; }
 
   bool hasAVLImm() const { return State == AVLIsImm; }
-  bool hasAVLDefMI() const { return State == AVLIsDefMI; }
+  bool hasAVLReg() const { return State == AVLIsReg; }
   bool hasAVLVLMAX() const { return State == AVLIsVLMAX; }
   bool hasAVLIgnored() const { return State == AVLIsIgnored; }
   Register getAVLReg() const {
-    assert(hasAVLDefMI());
-    return AVLDefMI->getOperand(0).getReg();
+    assert(hasAVLReg() && AVLRegDef.DefReg.isVirtual());
+    return AVLRegDef.DefReg;
   }
   unsigned getAVLImm() const {
     assert(hasAVLImm());
     return AVLImm;
   }
-
   const MachineInstr *getAVLDefMI() const {
-    assert(AVLDefMI);
-    return AVLDefMI;
+    assert(hasAVLReg() && AVLRegDef.DefMI);
+    return AVLRegDef.DefMI;
   }
 
   void setAVL(VSETVLIInfo Info) {
     assert(Info.isValid());
     if (Info.isUnknown())
       setUnknown();
-    else if (Info.hasAVLDefMI())
-      setAVLDefMI(Info.getAVLDefMI());
+    else if (Info.hasAVLReg())
+      setAVLRegDef(Info.getAVLDefMI(), Info.getAVLReg());
     else if (Info.hasAVLVLMAX())
       setAVLVLMAX();
     else if (Info.hasAVLIgnored())
@@ -536,9 +540,8 @@ class VSETVLIInfo {
   bool hasNonZeroAVL() const {
     if (hasAVLImm())
       return getAVLImm() > 0;
-    if (hasAVLDefMI()) {
+    if (hasAVLReg()) {
       const MachineInstr *MI = getAVLDefMI();
-      assert(MI);
       return isNonZeroLoadImmediate(*MI);
     }
     if (hasAVLVLMAX())
@@ -555,7 +558,7 @@ class VSETVLIInfo {
   }
 
   bool hasSameAVL(const VSETVLIInfo &Other) const {
-    if (hasAVLDefMI() && Other.hasAVLDefMI())
+    if (hasAVLReg() && Other.hasAVLReg())
       return getAVLDefMI()->isIdenticalTo(*Other.getAVLDefMI());
 
     if (hasAVLImm() && Other.hasAVLImm())
@@ -736,7 +739,7 @@ class VSETVLIInfo {
       OS << "Uninitialized";
     if (isUnknown())
       OS << "unknown";
-    if (hasAVLDefMI())
+    if (hasAVLReg())
       OS << "AVLReg=" << (unsigned)getAVLReg();
     if (hasAVLImm())
       OS << "AVLImm=" << (unsigned)AVLImm;
@@ -877,7 +880,7 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI,
     if (AVLReg == RISCV::X0)
       NewInfo.setAVLVLMAX();
     else
-      NewInfo.setAVLDefMI(MRI.getVRegDef(AVLReg));
+      NewInfo.setAVLRegDef(MRI.getVRegDef(AVLReg), AVLReg);
   }
   NewInfo.setVTYPE(MI.getOperand(2).getImm());
 
@@ -949,7 +952,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
       else
         InstrInfo.setAVLImm(Imm);
     } else {
-      InstrInfo.setAVLDefMI(MRI->getVRegDef(VLOp.getReg()));
+      InstrInfo.setAVLRegDef(MRI->getVRegDef(VLOp.getReg()), VLOp.getReg());
     }
   } else {
     assert(isScalarExtractInstr(MI));
@@ -969,7 +972,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
   // AVL operand with the AVL of the defining vsetvli.  We avoid general
   // register AVLs to avoid extending live ranges without being sure we can
   // kill the original source reg entirely.
-  if (InstrInfo.hasAVLDefMI()) {
+  if (InstrInfo.hasAVLReg()) {
     const MachineInstr *DefMI = InstrInfo.getAVLDefMI();
     if (isVectorConfigInstr(*DefMI)) {
       VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI, *MRI);
@@ -1009,9 +1012,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
     // If our AVL is a virtual register, it might be defined by a VSET(I)VLI. If
     // it has the same VLMAX we want and the last VL/VTYPE we observed is the
     // same, we can use the X0, X0 form.
-    if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLDefMI()) {
+    if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
       const MachineInstr *DefMI = Info.getAVLDefMI();
-      assert(DefMI);
       if (isVectorConfigInstr(*DefMI)) {
         VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
         if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
@@ -1128,9 +1130,8 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
   // it might be defined by a VSET(I)VLI. If it has the same VLMAX we need
   // and the last VL/VTYPE we observed is the same, we don't need a
   // VSETVLI here.
-  if (Require.hasAVLDefMI() && CurInfo.hasCompatibleVTYPE(Used, Require)) {
+  if (Require.hasAVLReg() && CurInfo.hasCompatibleVTYPE(Used, Require)) {
     const MachineInstr *DefMI = Require.getAVLDefMI();
-    assert(DefMI);
     if (DefMI && isVectorConfigInstr(*DefMI)) {
       VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
       if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo))
@@ -1224,7 +1225,8 @@ void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
 
   if (RISCV::isFaultFirstLoad(MI)) {
     // Update AVL to vl-output of the fault first load.
-    Info.setAVLDefMI(MRI->getVRegDef(MI.getOperand(1).getReg()));
+    Info.setAVLRegDef(MRI->getVRegDef(MI.getOperand(1).getReg()),
+                      MI.getOperand(1).getReg());
     return;
   }
 
@@ -1315,7 +1317,7 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
   if (DisableInsertVSETVLPHIOpt)
     return true;
 
-  if (!Require.hasAVLDefMI())
+  if (!Require.hasAVLReg())
     return true;
 
   // We need the AVL to be produce by a PHI node in this basic block.
@@ -1488,9 +1490,8 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
   // If the AVL value is a register (other than our VLMAX sentinel),
   // we need to prove the value is available at the point we're going
   // to insert the vsetvli at.
-  if (AvailableInfo.hasAVLDefMI()) {
+  if (AvailableInfo.hasAVLReg()) {
     const MachineInstr *AVLDefMI = AvailableInfo.getAVLDefMI();
-    assert(AVLDefMI);
     // This is an inline dominance check which covers the case of
     // UnavailablePred being the preheader of a loop.
     if (AVLDefMI->getParent() != UnavailablePred)

>From 1ac04f959eb332769d62b198d6c5dea76991678f Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Thu, 25 Apr 2024 04:11:40 -0700
Subject: [PATCH 6/6] Use const reference for getAVLDefMI and remove some
 useless assert

---
 llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 36 +++++++++-----------
 1 file changed, 17 insertions(+), 19 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index e5392a054bf3b9..5f70b68095544b 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -511,9 +511,9 @@ class VSETVLIInfo {
     assert(hasAVLImm());
     return AVLImm;
   }
-  const MachineInstr *getAVLDefMI() const {
+  const MachineInstr &getAVLDefMI() const {
     assert(hasAVLReg() && AVLRegDef.DefMI);
-    return AVLRegDef.DefMI;
+    return *AVLRegDef.DefMI;
   }
 
   void setAVL(VSETVLIInfo Info) {
@@ -521,7 +521,7 @@ class VSETVLIInfo {
     if (Info.isUnknown())
       setUnknown();
     else if (Info.hasAVLReg())
-      setAVLRegDef(Info.getAVLDefMI(), Info.getAVLReg());
+      setAVLRegDef(&Info.getAVLDefMI(), Info.getAVLReg());
     else if (Info.hasAVLVLMAX())
       setAVLVLMAX();
     else if (Info.hasAVLIgnored())
@@ -540,10 +540,8 @@ class VSETVLIInfo {
   bool hasNonZeroAVL() const {
     if (hasAVLImm())
       return getAVLImm() > 0;
-    if (hasAVLReg()) {
-      const MachineInstr *MI = getAVLDefMI();
-      return isNonZeroLoadImmediate(*MI);
-    }
+    if (hasAVLReg())
+      return isNonZeroLoadImmediate(getAVLDefMI());
     if (hasAVLVLMAX())
       return true;
     if (hasAVLIgnored())
@@ -559,7 +557,7 @@ class VSETVLIInfo {
 
   bool hasSameAVL(const VSETVLIInfo &Other) const {
     if (hasAVLReg() && Other.hasAVLReg())
-      return getAVLDefMI()->isIdenticalTo(*Other.getAVLDefMI());
+      return getAVLDefMI().isIdenticalTo(Other.getAVLDefMI());
 
     if (hasAVLImm() && Other.hasAVLImm())
       return getAVLImm() == Other.getAVLImm();
@@ -973,9 +971,9 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
   // register AVLs to avoid extending live ranges without being sure we can
   // kill the original source reg entirely.
   if (InstrInfo.hasAVLReg()) {
-    const MachineInstr *DefMI = InstrInfo.getAVLDefMI();
-    if (isVectorConfigInstr(*DefMI)) {
-      VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI, *MRI);
+    const MachineInstr &DefMI = InstrInfo.getAVLDefMI();
+    if (isVectorConfigInstr(DefMI)) {
+      VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(DefMI, *MRI);
       if (DefInstrInfo.hasSameVLMAX(InstrInfo) &&
           (DefInstrInfo.hasAVLImm() || DefInstrInfo.hasAVLVLMAX()))
         InstrInfo.setAVL(DefInstrInfo);
@@ -1013,9 +1011,9 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
     // it has the same VLMAX we want and the last VL/VTYPE we observed is the
     // same, we can use the X0, X0 form.
     if (Info.hasSameVLMAX(PrevInfo) && Info.hasAVLReg()) {
-      const MachineInstr *DefMI = Info.getAVLDefMI();
-      if (isVectorConfigInstr(*DefMI)) {
-        VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
+      const MachineInstr &DefMI = Info.getAVLDefMI();
+      if (isVectorConfigInstr(DefMI)) {
+        VSETVLIInfo DefInfo = getInfoForVSETVLI(DefMI, *MRI);
         if (DefInfo.hasSameAVL(PrevInfo) && DefInfo.hasSameVLMAX(PrevInfo)) {
           BuildMI(MBB, InsertPt, DL, TII->get(RISCV::PseudoVSETVLIX0))
               .addReg(RISCV::X0, RegState::Define | RegState::Dead)
@@ -1131,9 +1129,9 @@ bool RISCVInsertVSETVLI::needVSETVLI(const MachineInstr &MI,
   // and the last VL/VTYPE we observed is the same, we don't need a
   // VSETVLI here.
   if (Require.hasAVLReg() && CurInfo.hasCompatibleVTYPE(Used, Require)) {
-    const MachineInstr *DefMI = Require.getAVLDefMI();
-    if (DefMI && isVectorConfigInstr(*DefMI)) {
-      VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI, *MRI);
+    const MachineInstr &DefMI = Require.getAVLDefMI();
+    if (isVectorConfigInstr(DefMI)) {
+      VSETVLIInfo DefInfo = getInfoForVSETVLI(DefMI, *MRI);
       if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo))
         return false;
     }
@@ -1321,7 +1319,7 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
     return true;
 
   // We need the AVL to be produce by a PHI node in this basic block.
-  const MachineInstr *PHI = Require.getAVLDefMI();
+  const MachineInstr *PHI = &Require.getAVLDefMI();
   if (PHI->getOpcode() != RISCV::PHI || PHI->getParent() != &MBB)
     return true;
 
@@ -1491,7 +1489,7 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
   // we need to prove the value is available at the point we're going
   // to insert the vsetvli at.
   if (AvailableInfo.hasAVLReg()) {
-    const MachineInstr *AVLDefMI = AvailableInfo.getAVLDefMI();
+    const MachineInstr *AVLDefMI = &AvailableInfo.getAVLDefMI();
     // This is an inline dominance check which covers the case of
     // UnavailablePred being the preheader of a loop.
     if (AVLDefMI->getParent() != UnavailablePred)



More information about the llvm-commits mailing list