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