[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