aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2025-12-06 19:56:45 +0000
committerDimitry Andric <dim@FreeBSD.org>2025-12-06 20:08:43 +0000
commit3f709e42e3be0f28a88ca3e77663a02b52c914f4 (patch)
tree948796bf3bf7e164373caf6c31f9f128ca85fd8c /llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
parent32a711e1c447004eb1fd015925f305ed1d8426de (diff)
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp83
1 files changed, 27 insertions, 56 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
index c5efb89d8b2d..67ad28661da4 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
@@ -48,6 +48,12 @@ SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
MaxNumWorkGroups = ST.getMaxNumWorkGroups(F);
assert(MaxNumWorkGroups.size() == 3);
+ // Temporarily check both the attribute and the subtarget feature, until the
+ // latter is completely removed.
+ DynamicVGPRBlockSize = AMDGPU::getDynamicVGPRBlockSize(F);
+ if (DynamicVGPRBlockSize == 0 && ST.isDynamicVGPREnabled())
+ DynamicVGPRBlockSize = ST.getDynamicVGPRBlockSize();
+
Occupancy = ST.computeOccupancy(F, getLDSSize()).second;
CallingConv::ID CC = F.getCallingConv();
@@ -64,6 +70,10 @@ SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
}
MayNeedAGPRs = ST.hasMAIInsts();
+ if (ST.hasGFX90AInsts() &&
+ ST.getMaxNumVGPRs(F) <= AMDGPU::VGPR_32RegClass.getNumRegs() &&
+ !mayUseAGPRs(F))
+ MayNeedAGPRs = false; // We will select all MAI with VGPR operands.
if (AMDGPU::isChainCC(CC)) {
// Chain functions don't receive an SP from their caller, but are free to
@@ -98,13 +108,8 @@ SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
ImplicitArgPtr = true;
} else {
ImplicitArgPtr = false;
- MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),
- MaxKernArgAlign);
-
- if (ST.hasGFX90AInsts() &&
- ST.getMaxNumVGPRs(F) <= AMDGPU::VGPR_32RegClass.getNumRegs() &&
- !mayUseAGPRs(F))
- MayNeedAGPRs = false; // We will select all MAI with VGPR operands.
+ MaxKernArgAlign =
+ std::max(ST.getAlignmentForImplicitArgPtr(), MaxKernArgAlign);
}
if (!AMDGPU::isGraphics(CC) ||
@@ -255,8 +260,8 @@ Register SIMachineFunctionInfo::addLDSKernelId() {
SmallVectorImpl<MCRegister> *SIMachineFunctionInfo::addPreloadedKernArg(
const SIRegisterInfo &TRI, const TargetRegisterClass *RC,
unsigned AllocSizeDWord, int KernArgIdx, int PaddingSGPRs) {
- assert(!ArgInfo.PreloadKernArgs.count(KernArgIdx) &&
- "Preload kernel argument allocated twice.");
+ auto [It, Inserted] = ArgInfo.PreloadKernArgs.try_emplace(KernArgIdx);
+ assert(Inserted && "Preload kernel argument allocated twice.");
NumUserSGPRs += PaddingSGPRs;
// If the available register tuples are aligned with the kernarg to be
// preloaded use that register, otherwise we need to use a set of SGPRs and
@@ -265,20 +270,22 @@ SmallVectorImpl<MCRegister> *SIMachineFunctionInfo::addPreloadedKernArg(
ArgInfo.FirstKernArgPreloadReg = getNextUserSGPR();
Register PreloadReg =
TRI.getMatchingSuperReg(getNextUserSGPR(), AMDGPU::sub0, RC);
+ auto &Regs = It->second.Regs;
if (PreloadReg &&
(RC == &AMDGPU::SReg_32RegClass || RC == &AMDGPU::SReg_64RegClass)) {
- ArgInfo.PreloadKernArgs[KernArgIdx].Regs.push_back(PreloadReg);
+ Regs.push_back(PreloadReg);
NumUserSGPRs += AllocSizeDWord;
} else {
+ Regs.reserve(AllocSizeDWord);
for (unsigned I = 0; I < AllocSizeDWord; ++I) {
- ArgInfo.PreloadKernArgs[KernArgIdx].Regs.push_back(getNextUserSGPR());
+ Regs.push_back(getNextUserSGPR());
NumUserSGPRs++;
}
}
// Track the actual number of SGPRs that HW will preload to.
UserSGPRInfo.allocKernargPreloadSGPRs(AllocSizeDWord + PaddingSGPRs);
- return &ArgInfo.PreloadKernArgs[KernArgIdx].Regs;
+ return &Regs;
}
void SIMachineFunctionInfo::allocateWWMSpill(MachineFunction &MF, Register VGPR,
@@ -351,7 +358,7 @@ void SIMachineFunctionInfo::shiftWwmVGPRsToLowestRange(
// Replace the register in SpillPhysVGPRs. This is needed to look for free
// lanes while spilling special SGPRs like FP, BP, etc. during PEI.
- auto *RegItr = std::find(SpillPhysVGPRs.begin(), SpillPhysVGPRs.end(), Reg);
+ auto *RegItr = llvm::find(SpillPhysVGPRs, Reg);
if (RegItr != SpillPhysVGPRs.end()) {
unsigned Idx = std::distance(SpillPhysVGPRs.begin(), RegItr);
SpillPhysVGPRs[Idx] = NewReg;
@@ -714,7 +721,9 @@ yaml::SIMachineFunctionInfo::SIMachineFunctionInfo(
ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)),
PSInputAddr(MFI.getPSInputAddr()), PSInputEnable(MFI.getPSInputEnable()),
MaxMemoryClusterDWords(MFI.getMaxMemoryClusterDWords()),
- Mode(MFI.getMode()), HasInitWholeWave(MFI.hasInitWholeWave()) {
+ Mode(MFI.getMode()), HasInitWholeWave(MFI.hasInitWholeWave()),
+ DynamicVGPRBlockSize(MFI.getDynamicVGPRBlockSize()),
+ ScratchReservedForDynamicVGPRs(MFI.getScratchReservedForDynamicVGPRs()) {
for (Register Reg : MFI.getSGPRSpillPhysVGPRs())
SpillPhysVGPRS.push_back(regToString(Reg, TRI));
@@ -781,46 +790,8 @@ bool SIMachineFunctionInfo::initializeBaseYamlFields(
}
bool SIMachineFunctionInfo::mayUseAGPRs(const Function &F) const {
- return !F.hasFnAttribute("amdgpu-no-agpr");
-}
-
-bool SIMachineFunctionInfo::usesAGPRs(const MachineFunction &MF) const {
- if (UsesAGPRs)
- return *UsesAGPRs;
-
- if (!mayNeedAGPRs()) {
- UsesAGPRs = false;
- return false;
- }
-
- if (!AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv()) ||
- MF.getFrameInfo().hasCalls()) {
- UsesAGPRs = true;
- return true;
- }
-
- const MachineRegisterInfo &MRI = MF.getRegInfo();
-
- for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
- const Register Reg = Register::index2VirtReg(I);
- const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
- if (RC && SIRegisterInfo::isAGPRClass(RC)) {
- UsesAGPRs = true;
- return true;
- }
- if (!RC && !MRI.use_empty(Reg) && MRI.getType(Reg).isValid()) {
- // Defer caching UsesAGPRs, function might not yet been regbank selected.
- return true;
- }
- }
-
- for (MCRegister Reg : AMDGPU::AGPR_32RegClass) {
- if (MRI.isPhysRegUsed(Reg)) {
- UsesAGPRs = true;
- return true;
- }
- }
-
- UsesAGPRs = false;
- return false;
+ auto [MinNumAGPR, MaxNumAGPR] =
+ AMDGPU::getIntegerPairAttribute(F, "amdgpu-agpr-alloc", {~0u, ~0u},
+ /*OnlyFirstRequired=*/true);
+ return MinNumAGPR != 0u;
}