xref: /llvm-project/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h (revision 69fd2c11795f85e22b61fca7bc7b12d92418a6db)
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 <array>
20 #include <map>
21 
22 namespace llvm {
23 
24 class MachineRegisterInfo;
25 
26 /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
27 /// tells the hardware which interpolation parameters to load.
28 class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
29   // FIXME: This should be removed and getPreloadedValue moved here.
30   friend struct SIRegisterInfo;
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   // Number of reserved VGPRs for debugger usage.
66   unsigned DebuggerReservedVGPRCount;
67   // Stack object indices for work group IDs.
68   std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
69   // Stack object indices for work item IDs.
70   std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
71 
72 public:
73   // FIXME: Make private
74   unsigned LDSWaveSpillSize;
75   unsigned PSInputEna;
76   std::map<unsigned, unsigned> LaneVGPRs;
77   unsigned ScratchOffsetReg;
78   unsigned NumUserSGPRs;
79   unsigned NumSystemSGPRs;
80 
81 private:
82   bool HasSpilledSGPRs;
83   bool HasSpilledVGPRs;
84   bool HasNonSpillStackObjects;
85 
86   unsigned NumSpilledSGPRs;
87   unsigned NumSpilledVGPRs;
88 
89   // Feature bits required for inputs passed in user SGPRs.
90   bool PrivateSegmentBuffer : 1;
91   bool DispatchPtr : 1;
92   bool QueuePtr : 1;
93   bool KernargSegmentPtr : 1;
94   bool DispatchID : 1;
95   bool FlatScratchInit : 1;
96   bool GridWorkgroupCountX : 1;
97   bool GridWorkgroupCountY : 1;
98   bool GridWorkgroupCountZ : 1;
99 
100   // Feature bits required for inputs passed in system SGPRs.
101   bool WorkGroupIDX : 1; // Always initialized.
102   bool WorkGroupIDY : 1;
103   bool WorkGroupIDZ : 1;
104   bool WorkGroupInfo : 1;
105   bool PrivateSegmentWaveByteOffset : 1;
106 
107   bool WorkItemIDX : 1; // Always initialized.
108   bool WorkItemIDY : 1;
109   bool WorkItemIDZ : 1;
110 
111   MCPhysReg getNextUserSGPR() const {
112     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
113     return AMDGPU::SGPR0 + NumUserSGPRs;
114   }
115 
116   MCPhysReg getNextSystemSGPR() const {
117     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
118   }
119 
120 public:
121   struct SpilledReg {
122     unsigned VGPR;
123     int Lane;
124     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
125     SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
126     bool hasLane() { return Lane != -1;}
127     bool hasReg() { return VGPR != AMDGPU::NoRegister;}
128   };
129 
130   // SIMachineFunctionInfo definition
131 
132   SIMachineFunctionInfo(const MachineFunction &MF);
133   SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
134                            unsigned SubIdx);
135   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
136   unsigned getTIDReg() const { return TIDReg; };
137   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
138 
139   // Add user SGPRs.
140   unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
141   unsigned addDispatchPtr(const SIRegisterInfo &TRI);
142   unsigned addQueuePtr(const SIRegisterInfo &TRI);
143   unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
144   unsigned addDispatchID(const SIRegisterInfo &TRI);
145   unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
146 
147   // Add system SGPRs.
148   unsigned addWorkGroupIDX() {
149     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
150     NumSystemSGPRs += 1;
151     return WorkGroupIDXSystemSGPR;
152   }
153 
154   unsigned addWorkGroupIDY() {
155     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
156     NumSystemSGPRs += 1;
157     return WorkGroupIDYSystemSGPR;
158   }
159 
160   unsigned addWorkGroupIDZ() {
161     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
162     NumSystemSGPRs += 1;
163     return WorkGroupIDZSystemSGPR;
164   }
165 
166   unsigned addWorkGroupInfo() {
167     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
168     NumSystemSGPRs += 1;
169     return WorkGroupInfoSystemSGPR;
170   }
171 
172   unsigned addPrivateSegmentWaveByteOffset() {
173     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
174     NumSystemSGPRs += 1;
175     return PrivateSegmentWaveByteOffsetSystemSGPR;
176   }
177 
178   void setPrivateSegmentWaveByteOffset(unsigned Reg) {
179     PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
180   }
181 
182   bool hasPrivateSegmentBuffer() const {
183     return PrivateSegmentBuffer;
184   }
185 
186   bool hasDispatchPtr() const {
187     return DispatchPtr;
188   }
189 
190   bool hasQueuePtr() const {
191     return QueuePtr;
192   }
193 
194   bool hasKernargSegmentPtr() const {
195     return KernargSegmentPtr;
196   }
197 
198   bool hasDispatchID() const {
199     return DispatchID;
200   }
201 
202   bool hasFlatScratchInit() const {
203     return FlatScratchInit;
204   }
205 
206   bool hasGridWorkgroupCountX() const {
207     return GridWorkgroupCountX;
208   }
209 
210   bool hasGridWorkgroupCountY() const {
211     return GridWorkgroupCountY;
212   }
213 
214   bool hasGridWorkgroupCountZ() const {
215     return GridWorkgroupCountZ;
216   }
217 
218   bool hasWorkGroupIDX() const {
219     return WorkGroupIDX;
220   }
221 
222   bool hasWorkGroupIDY() const {
223     return WorkGroupIDY;
224   }
225 
226   bool hasWorkGroupIDZ() const {
227     return WorkGroupIDZ;
228   }
229 
230   bool hasWorkGroupInfo() const {
231     return WorkGroupInfo;
232   }
233 
234   bool hasPrivateSegmentWaveByteOffset() const {
235     return PrivateSegmentWaveByteOffset;
236   }
237 
238   bool hasWorkItemIDX() const {
239     return WorkItemIDX;
240   }
241 
242   bool hasWorkItemIDY() const {
243     return WorkItemIDY;
244   }
245 
246   bool hasWorkItemIDZ() const {
247     return WorkItemIDZ;
248   }
249 
250   unsigned getNumUserSGPRs() const {
251     return NumUserSGPRs;
252   }
253 
254   unsigned getNumPreloadedSGPRs() const {
255     return NumUserSGPRs + NumSystemSGPRs;
256   }
257 
258   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
259     return PrivateSegmentWaveByteOffsetSystemSGPR;
260   }
261 
262   /// \brief Returns the physical register reserved for use as the resource
263   /// descriptor for scratch accesses.
264   unsigned getScratchRSrcReg() const {
265     return ScratchRSrcReg;
266   }
267 
268   void setScratchRSrcReg(unsigned Reg) {
269     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
270     ScratchRSrcReg = Reg;
271   }
272 
273   unsigned getScratchWaveOffsetReg() const {
274     return ScratchWaveOffsetReg;
275   }
276 
277   void setScratchWaveOffsetReg(unsigned Reg) {
278     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
279     ScratchWaveOffsetReg = Reg;
280   }
281 
282   unsigned getQueuePtrUserSGPR() const {
283     return QueuePtrUserSGPR;
284   }
285 
286   bool hasSpilledSGPRs() const {
287     return HasSpilledSGPRs;
288   }
289 
290   void setHasSpilledSGPRs(bool Spill = true) {
291     HasSpilledSGPRs = Spill;
292   }
293 
294   bool hasSpilledVGPRs() const {
295     return HasSpilledVGPRs;
296   }
297 
298   void setHasSpilledVGPRs(bool Spill = true) {
299     HasSpilledVGPRs = Spill;
300   }
301 
302   bool hasNonSpillStackObjects() const {
303     return HasNonSpillStackObjects;
304   }
305 
306   void setHasNonSpillStackObjects(bool StackObject = true) {
307     HasNonSpillStackObjects = StackObject;
308   }
309 
310   unsigned getNumSpilledSGPRs() const {
311     return NumSpilledSGPRs;
312   }
313 
314   unsigned getNumSpilledVGPRs() const {
315     return NumSpilledVGPRs;
316   }
317 
318   void addToSpilledSGPRs(unsigned num) {
319     NumSpilledSGPRs += num;
320   }
321 
322   void addToSpilledVGPRs(unsigned num) {
323     NumSpilledVGPRs += num;
324   }
325 
326   unsigned getPSInputAddr() const {
327     return PSInputAddr;
328   }
329 
330   bool isPSInputAllocated(unsigned Index) const {
331     return PSInputAddr & (1 << Index);
332   }
333 
334   void markPSInputAllocated(unsigned Index) {
335     PSInputAddr |= 1 << Index;
336   }
337 
338   bool returnsVoid() const {
339     return ReturnsVoid;
340   }
341 
342   void setIfReturnsVoid(bool Value) {
343     ReturnsVoid = Value;
344   }
345 
346   /// \returns Number of reserved VGPRs for debugger usage.
347   unsigned getDebuggerReservedVGPRCount() const {
348     return DebuggerReservedVGPRCount;
349   }
350 
351   /// \returns Stack object index for \p Dim's work group ID.
352   int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
353     assert(Dim < 3);
354     return DebuggerWorkGroupIDStackObjectIndices[Dim];
355   }
356 
357   /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
358   void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
359     assert(Dim < 3);
360     DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
361   }
362 
363   /// \returns Stack object index for \p Dim's work item ID.
364   int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
365     assert(Dim < 3);
366     return DebuggerWorkItemIDStackObjectIndices[Dim];
367   }
368 
369   /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
370   void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
371     assert(Dim < 3);
372     DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
373   }
374 
375   /// \returns SGPR used for \p Dim's work group ID.
376   unsigned getWorkGroupIDSGPR(unsigned Dim) const {
377     switch (Dim) {
378     case 0:
379       assert(hasWorkGroupIDX());
380       return WorkGroupIDXSystemSGPR;
381     case 1:
382       assert(hasWorkGroupIDY());
383       return WorkGroupIDYSystemSGPR;
384     case 2:
385       assert(hasWorkGroupIDZ());
386       return WorkGroupIDZSystemSGPR;
387     }
388     llvm_unreachable("unexpected dimension");
389   }
390 
391   /// \returns VGPR used for \p Dim' work item ID.
392   unsigned getWorkItemIDVGPR(unsigned Dim) const {
393     switch (Dim) {
394     case 0:
395       assert(hasWorkItemIDX());
396       return AMDGPU::VGPR0;
397     case 1:
398       assert(hasWorkItemIDY());
399       return AMDGPU::VGPR1;
400     case 2:
401       assert(hasWorkItemIDZ());
402       return AMDGPU::VGPR2;
403     }
404     llvm_unreachable("unexpected dimension");
405   }
406 
407   unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
408 };
409 
410 } // End namespace llvm
411 
412 #endif
413