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