[llvm] [AMDGPU] Support partial and empty WWM pools for SGPR spills (PR #213491)
Shilei Tian via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 3 21:10:47 PDT 2026
================
@@ -372,42 +375,64 @@ void SILowerSGPRSpills::updateLaneVGPRDomInstr(
}
}
-void SILowerSGPRSpills::determineRegsForWWMAllocation(MachineFunction &MF,
- BitVector &RegMask) {
- // Determine an optimal number of VGPRs for WWM allocation. The complement
- // list will be available for allocating other VGPR virtual registers.
- SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
+SmallVector<MCRegister>
+SILowerSGPRSpills::determineRegsForWWMAllocation(MachineFunction &MF) {
+ SmallVector<MCRegister> WWMRegCandidates;
+ if (!MaxNumVGPRsForWwmAllocation)
+ return WWMRegCandidates;
+
MachineRegisterInfo &MRI = MF.getRegInfo();
BitVector ReservedRegs = TRI->getReservedRegs(MF);
- BitVector NonWwmAllocMask(TRI->getNumRegs());
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
+ unsigned MaxNumVGPRs = ST.getMaxNumVectorRegs(MF.getFunction()).first;
- // FIXME: MaxNumVGPRsForWwmAllocation might need to be adjusted in the future
- // to have a balanced allocation between WWM values and per-thread vector
- // register operands.
- unsigned NumRegs = MaxNumVGPRsForWwmAllocation;
- NumRegs =
- std::min(static_cast<unsigned>(MFI->getSGPRSpillVGPRs().size()), NumRegs);
-
- auto [MaxNumVGPRs, MaxNumAGPRs] = ST.getMaxNumVectorRegs(MF.getFunction());
// Try to use the highest available registers for now. Later after
// vgpr-regalloc, they can be shifted to the lowest range.
- unsigned I = 0;
for (unsigned Reg = AMDGPU::VGPR0 + MaxNumVGPRs - 1;
- (I < NumRegs) && (Reg >= AMDGPU::VGPR0); --Reg) {
+ WWMRegCandidates.size() < MaxNumVGPRsForWwmAllocation &&
+ Reg >= AMDGPU::VGPR0;
+ --Reg) {
if (!ReservedRegs.test(Reg) &&
- !MRI.isPhysRegUsed(Reg, /*SkipRegMaskTest=*/true)) {
- TRI->markSuperRegs(RegMask, Reg);
- ++I;
- }
+ !MRI.isPhysRegUsed(Reg, /*SkipRegMaskTest=*/true))
+ WWMRegCandidates.push_back(Reg);
}
- if (I != NumRegs) {
+ return WWMRegCandidates;
+}
+
+void SILowerSGPRSpills::assignWWMRegs(MachineFunction &MF,
+ ArrayRef<MCRegister> WWMRegCandidates,
+ bool RequiresFullWWMPool) {
+ SIMachineFunctionInfo *FuncInfo = MF.getInfo<SIMachineFunctionInfo>();
+ if (FuncInfo->getSGPRSpillVGPRs().empty())
+ return;
+
+ BitVector WwmRegMask(TRI->getNumRegs());
+
+ unsigned DesiredPoolSize =
+ std::min(static_cast<unsigned>(FuncInfo->getSGPRSpillVGPRs().size()),
+ static_cast<unsigned>(MaxNumVGPRsForWwmAllocation));
+ unsigned SelectedPoolSize =
+ std::min<unsigned>(DesiredPoolSize, WWMRegCandidates.size());
+ // WWM register candidates are ordered high-to-low, so take the highest
+ // available registers when the desired pool is smaller than the candidate
+ // list.
+ for (MCRegister Reg : WWMRegCandidates.take_front(SelectedPoolSize))
+ TRI->markSuperRegs(WwmRegMask, Reg);
+
+ if (RequiresFullWWMPool && SelectedPoolSize != DesiredPoolSize) {
// Reserve an arbitrary register and report the error.
- TRI->markSuperRegs(RegMask, AMDGPU::VGPR0);
+ TRI->markSuperRegs(WwmRegMask, AMDGPU::VGPR0);
MF.getFunction().getContext().emitError(
"cannot find enough VGPRs for wwm-regalloc");
}
+
+ BitVector NonWwmRegMask(WwmRegMask);
----------------
shiltian wrote:
https://github.com/llvm/llvm-project/pull/213827
https://github.com/llvm/llvm-project/pull/213491
More information about the llvm-commits
mailing list