[llvm] [NFC][RISCV] Keep AVLReg define instr inside VSETVLInfo (PR #89180)
Piyou Chen via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 27 02:25:23 PDT 2024
https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/89180
>From 01dd2f9706281247b992fd1509e8820a291fc0fe 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/7] [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 c40b9031543fe2..4973f805e4e563 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 &&
@@ -459,6 +459,8 @@ class VSETVLIInfo {
unsigned AVLImm;
};
+ const MachineInstr *AVLDefMI;
+
enum : uint8_t {
Uninitialized,
AVLIsReg,
@@ -477,7 +479,7 @@ class VSETVLIInfo {
public:
VSETVLIInfo()
- : AVLImm(0), TailAgnostic(false), MaskAgnostic(false),
+ : AVLImm(0), AVLDefMI(nullptr), TailAgnostic(false), MaskAgnostic(false),
SEWLMULRatioOnly(false) {}
static VSETVLIInfo getUnknown() {
@@ -504,6 +506,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; }
@@ -518,12 +521,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())
@@ -543,7 +550,7 @@ class VSETVLIInfo {
if (hasAVLImm())
return getAVLImm() > 0;
if (hasAVLReg()) {
- MachineInstr *MI = MRI.getUniqueVRegDef(getAVLReg());
+ const MachineInstr *MI = getAVLDefMI();
assert(MI);
return isNonZeroLoadImmediate(*MI);
}
@@ -870,7 +877,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());
@@ -883,7 +891,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());
@@ -956,6 +964,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));
@@ -976,10 +986,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);
@@ -1017,10 +1026,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)
@@ -1138,8 +1147,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;
}
@@ -1225,13 +1234,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;
}
@@ -1346,7 +1357,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 != PBBExit)
return true;
@@ -1500,7 +1511,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.
@@ -1580,8 +1591,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 816fa6b53456a65b962ad8b19e50154eb5d00634 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/7] 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 4973f805e4e563..3e5d44bac2965c 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -546,7 +546,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()) {
@@ -561,11 +561,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 {
@@ -666,7 +665,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);
@@ -1203,7 +1202,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);
@@ -1592,7 +1591,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 e19a2dbbdbba7bd4e7dd489c2e06d5dcbaa4221d 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/7] 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 3e5d44bac2965c..7c326d15c92439 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -463,7 +463,7 @@ class VSETVLIInfo {
enum : uint8_t {
Uninitialized,
- AVLIsReg,
+ AVLIsDefMI,
AVLIsImm,
AVLIsVLMAX,
AVLIsIgnored,
@@ -492,10 +492,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) {
@@ -509,7 +510,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 {
@@ -527,10 +528,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())
@@ -890,7 +889,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());
@@ -962,9 +961,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));
@@ -1239,9 +1238,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 2182cf98ce0840c5bde62412c76750c6cbf920a5 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/7] 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 7c326d15c92439..b475032fade8f4 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -455,12 +455,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,
@@ -479,7 +477,7 @@ class VSETVLIInfo {
public:
VSETVLIInfo()
- : AVLImm(0), AVLDefMI(nullptr), TailAgnostic(false), MaskAgnostic(false),
+ : AVLImm(0), TailAgnostic(false), MaskAgnostic(false),
SEWLMULRatioOnly(false) {}
static VSETVLIInfo getUnknown() {
@@ -492,9 +490,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;
}
@@ -507,29 +504,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())
@@ -548,7 +547,7 @@ class VSETVLIInfo {
bool hasNonZeroAVL() const {
if (hasAVLImm())
return getAVLImm() > 0;
- if (hasAVLReg()) {
+ if (hasAVLDefMI()) {
const MachineInstr *MI = getAVLDefMI();
assert(MI);
return isNonZeroLoadImmediate(*MI);
@@ -567,8 +566,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();
@@ -748,8 +747,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())
@@ -889,7 +888,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());
@@ -961,9 +960,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));
@@ -983,7 +980,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);
@@ -1023,7 +1020,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)) {
@@ -1142,11 +1139,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;
}
@@ -1238,10 +1235,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;
}
@@ -1332,14 +1326,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;
@@ -1509,7 +1500,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 a5074f5fbbb821befa82bf4c8f92e3a24060ca31 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/7] 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 b475032fade8f4..a4eb40c5716621 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -454,14 +454,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,
@@ -490,10 +494,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) {
@@ -506,29 +511,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())
@@ -547,9 +551,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())
@@ -566,7 +569,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())
@@ -747,7 +750,7 @@ class VSETVLIInfo {
OS << "Uninitialized";
if (isUnknown())
OS << "unknown";
- if (hasAVLDefMI())
+ if (hasAVLReg())
OS << "AVLReg=" << (unsigned)getAVLReg();
if (hasAVLImm())
OS << "AVLImm=" << (unsigned)AVLImm;
@@ -888,7 +891,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());
@@ -960,7 +963,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));
@@ -980,7 +983,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);
@@ -1020,9 +1023,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)) {
@@ -1139,9 +1141,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))
@@ -1235,7 +1236,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;
}
@@ -1326,7 +1328,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.
@@ -1500,9 +1502,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 4ed7160880d8120d7664780e13d043f54a803827 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/7] 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 a4eb40c5716621..dfa3bd87672650 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -522,9 +522,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) {
@@ -532,7 +532,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())
@@ -551,10 +551,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())
@@ -570,7 +568,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();
@@ -984,9 +982,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);
@@ -1024,9 +1022,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)
@@ -1142,9 +1140,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;
}
@@ -1332,7 +1330,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;
@@ -1503,7 +1501,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)
>From bedde94f197c7714b8a4937839e66c6b63ce7791 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Thu, 25 Apr 2024 22:06:15 -0700
Subject: [PATCH 7/7] hasSameAVL also consider AVLReg
---
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index dfa3bd87672650..b5fd508fa77de2 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -568,7 +568,8 @@ class VSETVLIInfo {
bool hasSameAVL(const VSETVLIInfo &Other) const {
if (hasAVLReg() && Other.hasAVLReg())
- return getAVLDefMI().isIdenticalTo(Other.getAVLDefMI());
+ return getAVLDefMI().isIdenticalTo(Other.getAVLDefMI()) &&
+ getAVLReg() == Other.getAVLReg();
if (hasAVLImm() && Other.hasAVLImm())
return getAVLImm() == Other.getAVLImm();
More information about the llvm-commits
mailing list