AMDGPU/SI: Add s_waitcnt at the end of non-void functions
[oota-llvm.git] / lib / Target / AMDGPU / SIMachineFunctionInfo.h
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