xref: /aosp_15_r20/external/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SIMachineFunctionInfo.cpp -------- SI Machine Function Info -------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "SIMachineFunctionInfo.h"
11*9880d681SAndroid Build Coastguard Worker #include "AMDGPUSubtarget.h"
12*9880d681SAndroid Build Coastguard Worker #include "SIInstrInfo.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker #define MAX_LANES 64
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EnableSpillSGPRToVGPR(
24*9880d681SAndroid Build Coastguard Worker   "amdgpu-spill-sgpr-to-vgpr",
25*9880d681SAndroid Build Coastguard Worker   cl::desc("Enable spilling VGPRs to SGPRs"),
26*9880d681SAndroid Build Coastguard Worker   cl::ReallyHidden,
27*9880d681SAndroid Build Coastguard Worker   cl::init(true));
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker // Pin the vtable to this file.
anchor()30*9880d681SAndroid Build Coastguard Worker void SIMachineFunctionInfo::anchor() {}
31*9880d681SAndroid Build Coastguard Worker 
SIMachineFunctionInfo(const MachineFunction & MF)32*9880d681SAndroid Build Coastguard Worker SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
33*9880d681SAndroid Build Coastguard Worker   : AMDGPUMachineFunction(MF),
34*9880d681SAndroid Build Coastguard Worker     TIDReg(AMDGPU::NoRegister),
35*9880d681SAndroid Build Coastguard Worker     ScratchRSrcReg(AMDGPU::NoRegister),
36*9880d681SAndroid Build Coastguard Worker     ScratchWaveOffsetReg(AMDGPU::NoRegister),
37*9880d681SAndroid Build Coastguard Worker     PrivateSegmentBufferUserSGPR(AMDGPU::NoRegister),
38*9880d681SAndroid Build Coastguard Worker     DispatchPtrUserSGPR(AMDGPU::NoRegister),
39*9880d681SAndroid Build Coastguard Worker     QueuePtrUserSGPR(AMDGPU::NoRegister),
40*9880d681SAndroid Build Coastguard Worker     KernargSegmentPtrUserSGPR(AMDGPU::NoRegister),
41*9880d681SAndroid Build Coastguard Worker     DispatchIDUserSGPR(AMDGPU::NoRegister),
42*9880d681SAndroid Build Coastguard Worker     FlatScratchInitUserSGPR(AMDGPU::NoRegister),
43*9880d681SAndroid Build Coastguard Worker     PrivateSegmentSizeUserSGPR(AMDGPU::NoRegister),
44*9880d681SAndroid Build Coastguard Worker     GridWorkGroupCountXUserSGPR(AMDGPU::NoRegister),
45*9880d681SAndroid Build Coastguard Worker     GridWorkGroupCountYUserSGPR(AMDGPU::NoRegister),
46*9880d681SAndroid Build Coastguard Worker     GridWorkGroupCountZUserSGPR(AMDGPU::NoRegister),
47*9880d681SAndroid Build Coastguard Worker     WorkGroupIDXSystemSGPR(AMDGPU::NoRegister),
48*9880d681SAndroid Build Coastguard Worker     WorkGroupIDYSystemSGPR(AMDGPU::NoRegister),
49*9880d681SAndroid Build Coastguard Worker     WorkGroupIDZSystemSGPR(AMDGPU::NoRegister),
50*9880d681SAndroid Build Coastguard Worker     WorkGroupInfoSystemSGPR(AMDGPU::NoRegister),
51*9880d681SAndroid Build Coastguard Worker     PrivateSegmentWaveByteOffsetSystemSGPR(AMDGPU::NoRegister),
52*9880d681SAndroid Build Coastguard Worker     PSInputAddr(0),
53*9880d681SAndroid Build Coastguard Worker     ReturnsVoid(true),
54*9880d681SAndroid Build Coastguard Worker     MaximumWorkGroupSize(0),
55*9880d681SAndroid Build Coastguard Worker     DebuggerReservedVGPRCount(0),
56*9880d681SAndroid Build Coastguard Worker     DebuggerWorkGroupIDStackObjectIndices({{0, 0, 0}}),
57*9880d681SAndroid Build Coastguard Worker     DebuggerWorkItemIDStackObjectIndices({{0, 0, 0}}),
58*9880d681SAndroid Build Coastguard Worker     LDSWaveSpillSize(0),
59*9880d681SAndroid Build Coastguard Worker     PSInputEna(0),
60*9880d681SAndroid Build Coastguard Worker     NumUserSGPRs(0),
61*9880d681SAndroid Build Coastguard Worker     NumSystemSGPRs(0),
62*9880d681SAndroid Build Coastguard Worker     HasSpilledSGPRs(false),
63*9880d681SAndroid Build Coastguard Worker     HasSpilledVGPRs(false),
64*9880d681SAndroid Build Coastguard Worker     HasNonSpillStackObjects(false),
65*9880d681SAndroid Build Coastguard Worker     HasFlatInstructions(false),
66*9880d681SAndroid Build Coastguard Worker     NumSpilledSGPRs(0),
67*9880d681SAndroid Build Coastguard Worker     NumSpilledVGPRs(0),
68*9880d681SAndroid Build Coastguard Worker     PrivateSegmentBuffer(false),
69*9880d681SAndroid Build Coastguard Worker     DispatchPtr(false),
70*9880d681SAndroid Build Coastguard Worker     QueuePtr(false),
71*9880d681SAndroid Build Coastguard Worker     DispatchID(false),
72*9880d681SAndroid Build Coastguard Worker     KernargSegmentPtr(false),
73*9880d681SAndroid Build Coastguard Worker     FlatScratchInit(false),
74*9880d681SAndroid Build Coastguard Worker     GridWorkgroupCountX(false),
75*9880d681SAndroid Build Coastguard Worker     GridWorkgroupCountY(false),
76*9880d681SAndroid Build Coastguard Worker     GridWorkgroupCountZ(false),
77*9880d681SAndroid Build Coastguard Worker     WorkGroupIDX(false),
78*9880d681SAndroid Build Coastguard Worker     WorkGroupIDY(false),
79*9880d681SAndroid Build Coastguard Worker     WorkGroupIDZ(false),
80*9880d681SAndroid Build Coastguard Worker     WorkGroupInfo(false),
81*9880d681SAndroid Build Coastguard Worker     PrivateSegmentWaveByteOffset(false),
82*9880d681SAndroid Build Coastguard Worker     WorkItemIDX(false),
83*9880d681SAndroid Build Coastguard Worker     WorkItemIDY(false),
84*9880d681SAndroid Build Coastguard Worker     WorkItemIDZ(false) {
85*9880d681SAndroid Build Coastguard Worker   const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
86*9880d681SAndroid Build Coastguard Worker   const Function *F = MF.getFunction();
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   PSInputAddr = AMDGPU::getInitialPSInputAddr(*F);
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker   const MachineFrameInfo *FrameInfo = MF.getFrameInfo();
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker   if (!AMDGPU::isShader(F->getCallingConv())) {
93*9880d681SAndroid Build Coastguard Worker     KernargSegmentPtr = true;
94*9880d681SAndroid Build Coastguard Worker     WorkGroupIDX = true;
95*9880d681SAndroid Build Coastguard Worker     WorkItemIDX = true;
96*9880d681SAndroid Build Coastguard Worker   }
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   if (F->hasFnAttribute("amdgpu-work-group-id-y") || ST.debuggerEmitPrologue())
99*9880d681SAndroid Build Coastguard Worker     WorkGroupIDY = true;
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   if (F->hasFnAttribute("amdgpu-work-group-id-z") || ST.debuggerEmitPrologue())
102*9880d681SAndroid Build Coastguard Worker     WorkGroupIDZ = true;
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker   if (F->hasFnAttribute("amdgpu-work-item-id-y") || ST.debuggerEmitPrologue())
105*9880d681SAndroid Build Coastguard Worker     WorkItemIDY = true;
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   if (F->hasFnAttribute("amdgpu-work-item-id-z") || ST.debuggerEmitPrologue())
108*9880d681SAndroid Build Coastguard Worker     WorkItemIDZ = true;
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   // X, XY, and XYZ are the only supported combinations, so make sure Y is
111*9880d681SAndroid Build Coastguard Worker   // enabled if Z is.
112*9880d681SAndroid Build Coastguard Worker   if (WorkItemIDZ)
113*9880d681SAndroid Build Coastguard Worker     WorkItemIDY = true;
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker   bool MaySpill = ST.isVGPRSpillingEnabled(*F);
116*9880d681SAndroid Build Coastguard Worker   bool HasStackObjects = FrameInfo->hasStackObjects();
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker   if (HasStackObjects || MaySpill)
119*9880d681SAndroid Build Coastguard Worker     PrivateSegmentWaveByteOffset = true;
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   if (ST.isAmdHsaOS()) {
122*9880d681SAndroid Build Coastguard Worker     if (HasStackObjects || MaySpill)
123*9880d681SAndroid Build Coastguard Worker       PrivateSegmentBuffer = true;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker     if (F->hasFnAttribute("amdgpu-dispatch-ptr"))
126*9880d681SAndroid Build Coastguard Worker       DispatchPtr = true;
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker     if (F->hasFnAttribute("amdgpu-queue-ptr"))
129*9880d681SAndroid Build Coastguard Worker       QueuePtr = true;
130*9880d681SAndroid Build Coastguard Worker   }
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker   // We don't need to worry about accessing spills with flat instructions.
133*9880d681SAndroid Build Coastguard Worker   // TODO: On VI where we must use flat for global, we should be able to omit
134*9880d681SAndroid Build Coastguard Worker   // this if it is never used for generic access.
135*9880d681SAndroid Build Coastguard Worker   if (HasStackObjects && ST.getGeneration() >= SISubtarget::SEA_ISLANDS &&
136*9880d681SAndroid Build Coastguard Worker       ST.isAmdHsaOS())
137*9880d681SAndroid Build Coastguard Worker     FlatScratchInit = true;
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   if (AMDGPU::isCompute(F->getCallingConv()))
140*9880d681SAndroid Build Coastguard Worker     MaximumWorkGroupSize = AMDGPU::getMaximumWorkGroupSize(*F);
141*9880d681SAndroid Build Coastguard Worker   else
142*9880d681SAndroid Build Coastguard Worker     MaximumWorkGroupSize = ST.getWavefrontSize();
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker   if (ST.debuggerReserveRegs())
145*9880d681SAndroid Build Coastguard Worker     DebuggerReservedVGPRCount = 4;
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker 
addPrivateSegmentBuffer(const SIRegisterInfo & TRI)148*9880d681SAndroid Build Coastguard Worker unsigned SIMachineFunctionInfo::addPrivateSegmentBuffer(
149*9880d681SAndroid Build Coastguard Worker   const SIRegisterInfo &TRI) {
150*9880d681SAndroid Build Coastguard Worker   PrivateSegmentBufferUserSGPR = TRI.getMatchingSuperReg(
151*9880d681SAndroid Build Coastguard Worker     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_128RegClass);
152*9880d681SAndroid Build Coastguard Worker   NumUserSGPRs += 4;
153*9880d681SAndroid Build Coastguard Worker   return PrivateSegmentBufferUserSGPR;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker 
addDispatchPtr(const SIRegisterInfo & TRI)156*9880d681SAndroid Build Coastguard Worker unsigned SIMachineFunctionInfo::addDispatchPtr(const SIRegisterInfo &TRI) {
157*9880d681SAndroid Build Coastguard Worker   DispatchPtrUserSGPR = TRI.getMatchingSuperReg(
158*9880d681SAndroid Build Coastguard Worker     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass);
159*9880d681SAndroid Build Coastguard Worker   NumUserSGPRs += 2;
160*9880d681SAndroid Build Coastguard Worker   return DispatchPtrUserSGPR;
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker 
addQueuePtr(const SIRegisterInfo & TRI)163*9880d681SAndroid Build Coastguard Worker unsigned SIMachineFunctionInfo::addQueuePtr(const SIRegisterInfo &TRI) {
164*9880d681SAndroid Build Coastguard Worker   QueuePtrUserSGPR = TRI.getMatchingSuperReg(
165*9880d681SAndroid Build Coastguard Worker     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass);
166*9880d681SAndroid Build Coastguard Worker   NumUserSGPRs += 2;
167*9880d681SAndroid Build Coastguard Worker   return QueuePtrUserSGPR;
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker 
addKernargSegmentPtr(const SIRegisterInfo & TRI)170*9880d681SAndroid Build Coastguard Worker unsigned SIMachineFunctionInfo::addKernargSegmentPtr(const SIRegisterInfo &TRI) {
171*9880d681SAndroid Build Coastguard Worker   KernargSegmentPtrUserSGPR = TRI.getMatchingSuperReg(
172*9880d681SAndroid Build Coastguard Worker     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass);
173*9880d681SAndroid Build Coastguard Worker   NumUserSGPRs += 2;
174*9880d681SAndroid Build Coastguard Worker   return KernargSegmentPtrUserSGPR;
175*9880d681SAndroid Build Coastguard Worker }
176*9880d681SAndroid Build Coastguard Worker 
addFlatScratchInit(const SIRegisterInfo & TRI)177*9880d681SAndroid Build Coastguard Worker unsigned SIMachineFunctionInfo::addFlatScratchInit(const SIRegisterInfo &TRI) {
178*9880d681SAndroid Build Coastguard Worker   FlatScratchInitUserSGPR = TRI.getMatchingSuperReg(
179*9880d681SAndroid Build Coastguard Worker     getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass);
180*9880d681SAndroid Build Coastguard Worker   NumUserSGPRs += 2;
181*9880d681SAndroid Build Coastguard Worker   return FlatScratchInitUserSGPR;
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker 
getSpilledReg(MachineFunction * MF,unsigned FrameIndex,unsigned SubIdx)184*9880d681SAndroid Build Coastguard Worker SIMachineFunctionInfo::SpilledReg SIMachineFunctionInfo::getSpilledReg (
185*9880d681SAndroid Build Coastguard Worker                                                        MachineFunction *MF,
186*9880d681SAndroid Build Coastguard Worker                                                        unsigned FrameIndex,
187*9880d681SAndroid Build Coastguard Worker                                                        unsigned SubIdx) {
188*9880d681SAndroid Build Coastguard Worker   if (!EnableSpillSGPRToVGPR)
189*9880d681SAndroid Build Coastguard Worker     return SpilledReg();
190*9880d681SAndroid Build Coastguard Worker 
191*9880d681SAndroid Build Coastguard Worker   const SISubtarget &ST = MF->getSubtarget<SISubtarget>();
192*9880d681SAndroid Build Coastguard Worker   const SIRegisterInfo *TRI = ST.getRegisterInfo();
193*9880d681SAndroid Build Coastguard Worker 
194*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *FrameInfo = MF->getFrameInfo();
195*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF->getRegInfo();
196*9880d681SAndroid Build Coastguard Worker   int64_t Offset = FrameInfo->getObjectOffset(FrameIndex);
197*9880d681SAndroid Build Coastguard Worker   Offset += SubIdx * 4;
198*9880d681SAndroid Build Coastguard Worker 
199*9880d681SAndroid Build Coastguard Worker   unsigned LaneVGPRIdx = Offset / (64 * 4);
200*9880d681SAndroid Build Coastguard Worker   unsigned Lane = (Offset / 4) % 64;
201*9880d681SAndroid Build Coastguard Worker 
202*9880d681SAndroid Build Coastguard Worker   struct SpilledReg Spill;
203*9880d681SAndroid Build Coastguard Worker   Spill.Lane = Lane;
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker   if (!LaneVGPRs.count(LaneVGPRIdx)) {
206*9880d681SAndroid Build Coastguard Worker     unsigned LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass);
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker     if (LaneVGPR == AMDGPU::NoRegister)
209*9880d681SAndroid Build Coastguard Worker       // We have no VGPRs left for spilling SGPRs.
210*9880d681SAndroid Build Coastguard Worker       return Spill;
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker     LaneVGPRs[LaneVGPRIdx] = LaneVGPR;
213*9880d681SAndroid Build Coastguard Worker 
214*9880d681SAndroid Build Coastguard Worker     // Add this register as live-in to all blocks to avoid machine verifer
215*9880d681SAndroid Build Coastguard Worker     // complaining about use of an undefined physical register.
216*9880d681SAndroid Build Coastguard Worker     for (MachineFunction::iterator BI = MF->begin(), BE = MF->end();
217*9880d681SAndroid Build Coastguard Worker          BI != BE; ++BI) {
218*9880d681SAndroid Build Coastguard Worker       BI->addLiveIn(LaneVGPR);
219*9880d681SAndroid Build Coastguard Worker     }
220*9880d681SAndroid Build Coastguard Worker   }
221*9880d681SAndroid Build Coastguard Worker 
222*9880d681SAndroid Build Coastguard Worker   Spill.VGPR = LaneVGPRs[LaneVGPRIdx];
223*9880d681SAndroid Build Coastguard Worker   return Spill;
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker 
getMaximumWorkGroupSize(const MachineFunction & MF) const226*9880d681SAndroid Build Coastguard Worker unsigned SIMachineFunctionInfo::getMaximumWorkGroupSize(
227*9880d681SAndroid Build Coastguard Worker                                               const MachineFunction &MF) const {
228*9880d681SAndroid Build Coastguard Worker   return MaximumWorkGroupSize;
229*9880d681SAndroid Build Coastguard Worker }
230