xref: /llvm-project/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h (revision 99c14524ec6bb67b1ccdf9f100d01dab8afa2bf0)
1 //===- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface -*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
15 #define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
16 
17 #include "AMDGPUMachineFunction.h"
18 #include "SIRegisterInfo.h"
19 #include <map>
20 
21 namespace llvm {
22 
23 class MachineRegisterInfo;
24 
25 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
26 /// tells the hardware which interpolation parameters to load.
27 class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
28   // FIXME: This should be removed and getPreloadedValue moved here.
29   friend struct SIRegisterInfo;
30   void anchor() override;
31 
32   unsigned TIDReg;
33 
34   // Registers that may be reserved for spilling purposes. These may be the same
35   // as the input registers.
36   unsigned ScratchRSrcReg;
37   unsigned ScratchWaveOffsetReg;
38 
39   // Input registers setup for the HSA ABI.
40   // User SGPRs in allocation order.
41   unsigned PrivateSegmentBufferUserSGPR;
42   unsigned DispatchPtrUserSGPR;
43   unsigned QueuePtrUserSGPR;
44   unsigned KernargSegmentPtrUserSGPR;
45   unsigned DispatchIDUserSGPR;
46   unsigned FlatScratchInitUserSGPR;
47   unsigned PrivateSegmentSizeUserSGPR;
48   unsigned GridWorkGroupCountXUserSGPR;
49   unsigned GridWorkGroupCountYUserSGPR;
50   unsigned GridWorkGroupCountZUserSGPR;
51 
52   // System SGPRs in allocation order.
53   unsigned WorkGroupIDXSystemSGPR;
54   unsigned WorkGroupIDYSystemSGPR;
55   unsigned WorkGroupIDZSystemSGPR;
56   unsigned WorkGroupInfoSystemSGPR;
57   unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
58 
59   // Graphics info.
60   unsigned PSInputAddr;
61   bool ReturnsVoid;
62 
63   unsigned MaximumWorkGroupSize;
64 
65 public:
66   // FIXME: Make private
67   unsigned LDSWaveSpillSize;
68   unsigned PSInputEna;
69   std::map<unsigned, unsigned> LaneVGPRs;
70   unsigned ScratchOffsetReg;
71   unsigned NumUserSGPRs;
72   unsigned NumSystemSGPRs;
73 
74 private:
75   bool HasSpilledSGPRs;
76   bool HasSpilledVGPRs;
77   bool HasNonSpillStackObjects;
78   bool HasFlatInstructions;
79 
80   // Feature bits required for inputs passed in user SGPRs.
81   bool PrivateSegmentBuffer : 1;
82   bool DispatchPtr : 1;
83   bool QueuePtr : 1;
84   bool DispatchID : 1;
85   bool KernargSegmentPtr : 1;
86   bool FlatScratchInit : 1;
87   bool GridWorkgroupCountX : 1;
88   bool GridWorkgroupCountY : 1;
89   bool GridWorkgroupCountZ : 1;
90 
91   // Feature bits required for inputs passed in system SGPRs.
92   bool WorkGroupIDX : 1; // Always initialized.
93   bool WorkGroupIDY : 1;
94   bool WorkGroupIDZ : 1;
95   bool WorkGroupInfo : 1;
96   bool PrivateSegmentWaveByteOffset : 1;
97 
98   bool WorkItemIDX : 1; // Always initialized.
99   bool WorkItemIDY : 1;
100   bool WorkItemIDZ : 1;
101 
102 
103   MCPhysReg getNextUserSGPR() const {
104     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
105     return AMDGPU::SGPR0 + NumUserSGPRs;
106   }
107 
108   MCPhysReg getNextSystemSGPR() const {
109     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
110   }
111 
112 public:
113   struct SpilledReg {
114     unsigned VGPR;
115     int Lane;
116     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
117     SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
118     bool hasLane() { return Lane != -1;}
119     bool hasReg() { return VGPR != AMDGPU::NoRegister;}
120   };
121 
122   // SIMachineFunctionInfo definition
123 
124   SIMachineFunctionInfo(const MachineFunction &MF);
125   SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
126                            unsigned SubIdx);
127   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
128   unsigned getTIDReg() const { return TIDReg; };
129   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
130 
131   // Add user SGPRs.
132   unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
133   unsigned addDispatchPtr(const SIRegisterInfo &TRI);
134   unsigned addQueuePtr(const SIRegisterInfo &TRI);
135   unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
136   unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
137 
138   // Add system SGPRs.
139   unsigned addWorkGroupIDX() {
140     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
141     NumSystemSGPRs += 1;
142     return WorkGroupIDXSystemSGPR;
143   }
144 
145   unsigned addWorkGroupIDY() {
146     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
147     NumSystemSGPRs += 1;
148     return WorkGroupIDYSystemSGPR;
149   }
150 
151   unsigned addWorkGroupIDZ() {
152     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
153     NumSystemSGPRs += 1;
154     return WorkGroupIDZSystemSGPR;
155   }
156 
157   unsigned addWorkGroupInfo() {
158     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
159     NumSystemSGPRs += 1;
160     return WorkGroupInfoSystemSGPR;
161   }
162 
163   unsigned addPrivateSegmentWaveByteOffset() {
164     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
165     NumSystemSGPRs += 1;
166     return PrivateSegmentWaveByteOffsetSystemSGPR;
167   }
168 
169   void setPrivateSegmentWaveByteOffset(unsigned Reg) {
170     PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
171   }
172 
173   bool hasPrivateSegmentBuffer() const {
174     return PrivateSegmentBuffer;
175   }
176 
177   bool hasDispatchPtr() const {
178     return DispatchPtr;
179   }
180 
181   bool hasQueuePtr() const {
182     return QueuePtr;
183   }
184 
185   bool hasDispatchID() const {
186     return DispatchID;
187   }
188 
189   bool hasKernargSegmentPtr() const {
190     return KernargSegmentPtr;
191   }
192 
193   bool hasFlatScratchInit() const {
194     return FlatScratchInit;
195   }
196 
197   bool hasGridWorkgroupCountX() const {
198     return GridWorkgroupCountX;
199   }
200 
201   bool hasGridWorkgroupCountY() const {
202     return GridWorkgroupCountY;
203   }
204 
205   bool hasGridWorkgroupCountZ() const {
206     return GridWorkgroupCountZ;
207   }
208 
209   bool hasWorkGroupIDX() const {
210     return WorkGroupIDX;
211   }
212 
213   bool hasWorkGroupIDY() const {
214     return WorkGroupIDY;
215   }
216 
217   bool hasWorkGroupIDZ() const {
218     return WorkGroupIDZ;
219   }
220 
221   bool hasWorkGroupInfo() const {
222     return WorkGroupInfo;
223   }
224 
225   bool hasPrivateSegmentWaveByteOffset() const {
226     return PrivateSegmentWaveByteOffset;
227   }
228 
229   bool hasWorkItemIDX() const {
230     return WorkItemIDX;
231   }
232 
233   bool hasWorkItemIDY() const {
234     return WorkItemIDY;
235   }
236 
237   bool hasWorkItemIDZ() const {
238     return WorkItemIDZ;
239   }
240 
241   unsigned getNumUserSGPRs() const {
242     return NumUserSGPRs;
243   }
244 
245   unsigned getNumPreloadedSGPRs() const {
246     return NumUserSGPRs + NumSystemSGPRs;
247   }
248 
249   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
250     return PrivateSegmentWaveByteOffsetSystemSGPR;
251   }
252 
253   /// \brief Returns the physical register reserved for use as the resource
254   /// descriptor for scratch accesses.
255   unsigned getScratchRSrcReg() const {
256     return ScratchRSrcReg;
257   }
258 
259   void setScratchRSrcReg(unsigned Reg) {
260     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
261     ScratchRSrcReg = Reg;
262   }
263 
264   unsigned getScratchWaveOffsetReg() const {
265     return ScratchWaveOffsetReg;
266   }
267 
268   void setScratchWaveOffsetReg(unsigned Reg) {
269     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
270     ScratchWaveOffsetReg = Reg;
271   }
272 
273   unsigned getQueuePtrUserSGPR() const {
274     return QueuePtrUserSGPR;
275   }
276 
277   bool hasSpilledSGPRs() const {
278     return HasSpilledSGPRs;
279   }
280 
281   void setHasSpilledSGPRs(bool Spill = true) {
282     HasSpilledSGPRs = Spill;
283   }
284 
285   bool hasSpilledVGPRs() const {
286     return HasSpilledVGPRs;
287   }
288 
289   void setHasSpilledVGPRs(bool Spill = true) {
290     HasSpilledVGPRs = Spill;
291   }
292 
293   bool hasNonSpillStackObjects() const {
294     return HasNonSpillStackObjects;
295   }
296 
297   void setHasNonSpillStackObjects(bool StackObject = true) {
298     HasNonSpillStackObjects = StackObject;
299   }
300 
301   bool hasFlatInstructions() const {
302     return HasFlatInstructions;
303   }
304 
305   void setHasFlatInstructions(bool UseFlat = true) {
306     HasFlatInstructions = UseFlat;
307   }
308 
309   unsigned getPSInputAddr() const {
310     return PSInputAddr;
311   }
312 
313   bool isPSInputAllocated(unsigned Index) const {
314     return PSInputAddr & (1 << Index);
315   }
316 
317   void markPSInputAllocated(unsigned Index) {
318     PSInputAddr |= 1 << Index;
319   }
320 
321   bool returnsVoid() const {
322     return ReturnsVoid;
323   }
324 
325   void setIfReturnsVoid(bool Value) {
326     ReturnsVoid = Value;
327   }
328 
329   unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
330 };
331 
332 } // End namespace llvm
333 
334 #endif
335