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   bool HasNonSpillStackObjects;
77   bool HasFlatInstructions;
78 
79   // Feature bits required for inputs passed in user SGPRs.
80   bool PrivateSegmentBuffer : 1;
81   bool DispatchPtr : 1;
82   bool QueuePtr : 1;
83   bool DispatchID : 1;
84   bool KernargSegmentPtr : 1;
85   bool FlatScratchInit : 1;
86   bool GridWorkgroupCountX : 1;
87   bool GridWorkgroupCountY : 1;
88   bool GridWorkgroupCountZ : 1;
89 
90   // Feature bits required for inputs passed in system SGPRs.
91   bool WorkGroupIDX : 1; // Always initialized.
92   bool WorkGroupIDY : 1;
93   bool WorkGroupIDZ : 1;
94   bool WorkGroupInfo : 1;
95   bool PrivateSegmentWaveByteOffset : 1;
96 
97   bool WorkItemIDX : 1; // Always initialized.
98   bool WorkItemIDY : 1;
99   bool WorkItemIDZ : 1;
100 
101 
102   MCPhysReg getNextUserSGPR() const {
103     assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
104     return AMDGPU::SGPR0 + NumUserSGPRs;
105   }
106 
107   MCPhysReg getNextSystemSGPR() const {
108     return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
109   }
110 
111 public:
112   struct SpilledReg {
113     unsigned VGPR;
114     int Lane;
115     SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
116     SpilledReg() : VGPR(0), Lane(-1) { }
117     bool hasLane() { return Lane != -1;}
118   };
119 
120   // SIMachineFunctionInfo definition
121 
122   SIMachineFunctionInfo(const MachineFunction &MF);
123   SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
124                            unsigned SubIdx);
125   bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
126   unsigned getTIDReg() const { return TIDReg; };
127   void setTIDReg(unsigned Reg) { TIDReg = Reg; }
128 
129   // Add user SGPRs.
130   unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
131   unsigned addDispatchPtr(const SIRegisterInfo &TRI);
132   unsigned addQueuePtr(const SIRegisterInfo &TRI);
133   unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
134   unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
135 
136   // Add system SGPRs.
137   unsigned addWorkGroupIDX() {
138     WorkGroupIDXSystemSGPR = getNextSystemSGPR();
139     NumSystemSGPRs += 1;
140     return WorkGroupIDXSystemSGPR;
141   }
142 
143   unsigned addWorkGroupIDY() {
144     WorkGroupIDYSystemSGPR = getNextSystemSGPR();
145     NumSystemSGPRs += 1;
146     return WorkGroupIDYSystemSGPR;
147   }
148 
149   unsigned addWorkGroupIDZ() {
150     WorkGroupIDZSystemSGPR = getNextSystemSGPR();
151     NumSystemSGPRs += 1;
152     return WorkGroupIDZSystemSGPR;
153   }
154 
155   unsigned addWorkGroupInfo() {
156     WorkGroupInfoSystemSGPR = getNextSystemSGPR();
157     NumSystemSGPRs += 1;
158     return WorkGroupInfoSystemSGPR;
159   }
160 
161   unsigned addPrivateSegmentWaveByteOffset() {
162     PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
163     NumSystemSGPRs += 1;
164     return PrivateSegmentWaveByteOffsetSystemSGPR;
165   }
166 
167   bool hasPrivateSegmentBuffer() const {
168     return PrivateSegmentBuffer;
169   }
170 
171   bool hasDispatchPtr() const {
172     return DispatchPtr;
173   }
174 
175   bool hasQueuePtr() const {
176     return QueuePtr;
177   }
178 
179   bool hasDispatchID() const {
180     return DispatchID;
181   }
182 
183   bool hasKernargSegmentPtr() const {
184     return KernargSegmentPtr;
185   }
186 
187   bool hasFlatScratchInit() const {
188     return FlatScratchInit;
189   }
190 
191   bool hasGridWorkgroupCountX() const {
192     return GridWorkgroupCountX;
193   }
194 
195   bool hasGridWorkgroupCountY() const {
196     return GridWorkgroupCountY;
197   }
198 
199   bool hasGridWorkgroupCountZ() const {
200     return GridWorkgroupCountZ;
201   }
202 
203   bool hasWorkGroupIDX() const {
204     return WorkGroupIDX;
205   }
206 
207   bool hasWorkGroupIDY() const {
208     return WorkGroupIDY;
209   }
210 
211   bool hasWorkGroupIDZ() const {
212     return WorkGroupIDZ;
213   }
214 
215   bool hasWorkGroupInfo() const {
216     return WorkGroupInfo;
217   }
218 
219   bool hasPrivateSegmentWaveByteOffset() const {
220     return PrivateSegmentWaveByteOffset;
221   }
222 
223   bool hasWorkItemIDX() const {
224     return WorkItemIDX;
225   }
226 
227   bool hasWorkItemIDY() const {
228     return WorkItemIDY;
229   }
230 
231   bool hasWorkItemIDZ() const {
232     return WorkItemIDZ;
233   }
234 
235   unsigned getNumUserSGPRs() const {
236     return NumUserSGPRs;
237   }
238 
239   unsigned getNumPreloadedSGPRs() const {
240     return NumUserSGPRs + NumSystemSGPRs;
241   }
242 
243   unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
244     return PrivateSegmentWaveByteOffsetSystemSGPR;
245   }
246 
247   /// \brief Returns the physical register reserved for use as the resource
248   /// descriptor for scratch accesses.
249   unsigned getScratchRSrcReg() const {
250     return ScratchRSrcReg;
251   }
252 
253   void setScratchRSrcReg(unsigned Reg) {
254     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
255     ScratchRSrcReg = Reg;
256   }
257 
258   unsigned getScratchWaveOffsetReg() const {
259     return ScratchWaveOffsetReg;
260   }
261 
262   void setScratchWaveOffsetReg(unsigned Reg) {
263     assert(Reg != AMDGPU::NoRegister && "Should never be unset");
264     ScratchWaveOffsetReg = Reg;
265   }
266 
267   bool hasSpilledSGPRs() const {
268     return HasSpilledSGPRs;
269   }
270 
271   void setHasSpilledSGPRs(bool Spill = true) {
272     HasSpilledSGPRs = Spill;
273   }
274 
275   bool hasSpilledVGPRs() const {
276     return HasSpilledVGPRs;
277   }
278 
279   void setHasSpilledVGPRs(bool Spill = true) {
280     HasSpilledVGPRs = Spill;
281   }
282 
283   bool hasNonSpillStackObjects() const {
284     return HasNonSpillStackObjects;
285   }
286 
287   void setHasNonSpillStackObjects(bool StackObject = true) {
288     HasNonSpillStackObjects = StackObject;
289   }
290 
291   bool hasFlatInstructions() const {
292     return HasFlatInstructions;
293   }
294 
295   void setHasFlatInstructions(bool UseFlat = true) {
296     HasFlatInstructions = UseFlat;
297   }
298 
299   unsigned getPSInputAddr() const {
300     return PSInputAddr;
301   }
302 
303   bool isPSInputAllocated(unsigned Index) const {
304     return PSInputAddr & (1 << Index);
305   }
306 
307   void markPSInputAllocated(unsigned Index) {
308     PSInputAddr |= 1 << Index;
309   }
310 
311   bool returnsVoid() const {
312     return ReturnsVoid;
313   }
314 
315   void setIfReturnsVoid(bool Value) {
316     ReturnsVoid = Value;
317   }
318 
319   unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
320 };
321 
322 } // End namespace llvm
323 
324 
325 #endif
326