Skip to content

[NFC][RISCV] Keep AVLReg define instr inside VSETVLInfo #89180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 28, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 48 additions & 47 deletions llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down Expand Up @@ -454,8 +454,12 @@ 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 {
Register AVLReg;
AVLDef AVLRegDef;
unsigned AVLImm;
};

Expand Down Expand Up @@ -490,9 +494,10 @@ class VSETVLIInfo {
void setUnknown() { State = Unknown; }
bool isUnknown() const { return State == Unknown; }

void setAVLReg(Register Reg) {
assert(Reg.isVirtual());
AVLReg = Reg;
void setAVLRegDef(const MachineInstr *DefMI, Register AVLReg) {
assert(DefMI && AVLReg.isVirtual());
AVLRegDef.DefMI = DefMI;
AVLRegDef.DefReg = AVLReg;
State = AVLIsReg;
}

Expand All @@ -510,20 +515,24 @@ class VSETVLIInfo {
bool hasAVLVLMAX() const { return State == AVLIsVLMAX; }
bool hasAVLIgnored() const { return State == AVLIsIgnored; }
Register getAVLReg() const {
assert(hasAVLReg());
return AVLReg;
assert(hasAVLReg() && AVLRegDef.DefReg.isVirtual());
return AVLRegDef.DefReg;
}
unsigned getAVLImm() const {
assert(hasAVLImm());
return AVLImm;
}
const MachineInstr &getAVLDefMI() const {
assert(hasAVLReg() && AVLRegDef.DefMI);
return *AVLRegDef.DefMI;
}

void setAVL(VSETVLIInfo Info) {
assert(Info.isValid());
if (Info.isUnknown())
setUnknown();
else if (Info.hasAVLReg())
setAVLReg(Info.getAVLReg());
setAVLRegDef(&Info.getAVLDefMI(), Info.getAVLReg());
else if (Info.hasAVLVLMAX())
setAVLVLMAX();
else if (Info.hasAVLIgnored())
Expand All @@ -539,31 +548,28 @@ 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()) {
MachineInstr *MI = MRI.getUniqueVRegDef(getAVLReg());
assert(MI);
return isNonZeroLoadImmediate(*MI);
}
if (hasAVLReg())
return isNonZeroLoadImmediate(getAVLDefMI());
if (hasAVLVLMAX())
return true;
if (hasAVLIgnored())
return false;
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 {
if (hasAVLReg() && Other.hasAVLReg())
return getAVLReg() == Other.getAVLReg();
return getAVLDefMI().isIdenticalTo(Other.getAVLDefMI()) &&
getAVLReg() == Other.getAVLReg();

if (hasAVLImm() && Other.hasAVLImm())
return getAVLImm() == Other.getAVLImm();
Expand Down Expand Up @@ -659,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);
Expand Down Expand Up @@ -744,7 +750,7 @@ class VSETVLIInfo {
if (isUnknown())
OS << "unknown";
if (hasAVLReg())
OS << "AVLReg=" << (unsigned)AVLReg;
OS << "AVLReg=" << (unsigned)getAVLReg();
if (hasAVLImm())
OS << "AVLImm=" << (unsigned)AVLImm;
if (hasAVLVLMAX())
Expand Down Expand Up @@ -870,7 +876,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());
Expand All @@ -883,7 +890,7 @@ static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
if (AVLReg == RISCV::X0)
NewInfo.setAVLVLMAX();
else
NewInfo.setAVLReg(AVLReg);
NewInfo.setAVLRegDef(MRI.getVRegDef(AVLReg), AVLReg);
}
NewInfo.setVTYPE(MI.getOperand(2).getImm());

Expand Down Expand Up @@ -955,7 +962,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
else
InstrInfo.setAVLImm(Imm);
} else {
InstrInfo.setAVLReg(VLOp.getReg());
InstrInfo.setAVLRegDef(MRI->getVRegDef(VLOp.getReg()), VLOp.getReg());
}
} else {
assert(isScalarExtractInstr(MI));
Expand All @@ -976,10 +983,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);
if (isVectorConfigInstr(*DefMI)) {
VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(*DefMI);
const MachineInstr &DefMI = InstrInfo.getAVLDefMI();
if (isVectorConfigInstr(DefMI)) {
VSETVLIInfo DefInstrInfo = getInfoForVSETVLI(DefMI, *MRI);
if (DefInstrInfo.hasSameVLMAX(InstrInfo) &&
(DefInstrInfo.hasAVLImm() || DefInstrInfo.hasAVLVLMAX()))
InstrInfo.setAVL(DefInstrInfo);
Expand Down Expand Up @@ -1017,10 +1023,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()) {
MachineInstr *DefMI = MRI->getUniqueVRegDef(Info.getAVLReg());
assert(DefMI);
if (isVectorConfigInstr(*DefMI)) {
VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
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)
Expand Down Expand Up @@ -1136,10 +1141,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)) {
MachineInstr *DefMI = MRI->getUniqueVRegDef(Require.getAVLReg());
assert(DefMI);
if (isVectorConfigInstr(*DefMI)) {
VSETVLIInfo DefInfo = getInfoForVSETVLI(*DefMI);
const MachineInstr &DefMI = Require.getAVLDefMI();
if (isVectorConfigInstr(DefMI)) {
VSETVLIInfo DefInfo = getInfoForVSETVLI(DefMI, *MRI);
if (DefInfo.hasSameAVL(CurInfo) && DefInfo.hasSameVLMAX(CurInfo))
return false;
}
Expand Down Expand Up @@ -1194,7 +1198,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);
Expand Down Expand Up @@ -1225,13 +1229,14 @@ 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());
Info.setAVLRegDef(MRI->getVRegDef(MI.getOperand(1).getReg()),
MI.getOperand(1).getReg());
return;
}

Expand Down Expand Up @@ -1325,11 +1330,8 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
if (!Require.hasAVLReg())
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;

Expand All @@ -1346,7 +1348,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;

Expand Down Expand Up @@ -1500,8 +1502,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());
assert(AVLDefMI);
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)
Expand Down Expand Up @@ -1580,8 +1581,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)))
return false;
}

Expand Down