blob: 61b38c8e55fea1ce5e4dad7002c0d790979dce76 [file] [log] [blame]
Tom Stellard75aadc22012-12-11 21:25:42 +00001//===- 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
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000014#ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
15#define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
Tom Stellard75aadc22012-12-11 21:25:42 +000016
Vincent Lejeuneace6f732013-04-01 21:47:53 +000017#include "AMDGPUMachineFunction.h"
Tom Stellard96468902014-09-24 01:33:17 +000018#include "SIRegisterInfo.h"
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000019#include <array>
Tom Stellardc149dc02013-11-27 21:23:35 +000020#include <map>
Tom Stellard75aadc22012-12-11 21:25:42 +000021
22namespace llvm {
23
Tom Stellardc149dc02013-11-27 21:23:35 +000024class MachineRegisterInfo;
25
Tom Stellard75aadc22012-12-11 21:25:42 +000026/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
27/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000028class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000029 // FIXME: This should be removed and getPreloadedValue moved here.
30 friend struct SIRegisterInfo;
Tom Stellard96468902014-09-24 01:33:17 +000031
32 unsigned TIDReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000033
34 // Registers that may be reserved for spilling purposes. These may be the same
35 // as the input registers.
Matt Arsenault49affb82015-11-25 20:55:12 +000036 unsigned ScratchRSrcReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000037 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;
Matt Arsenault49affb82015-11-25 20:55:12 +000058
Marek Olsakfccabaf2016-01-13 11:45:36 +000059 // Graphics info.
60 unsigned PSInputAddr;
Marek Olsak8e9cc632016-01-13 17:23:09 +000061 bool ReturnsVoid;
Marek Olsakfccabaf2016-01-13 11:45:36 +000062
Tom Stellard79a1fd72016-04-14 16:27:07 +000063 unsigned MaximumWorkGroupSize;
64
Konstantin Zhuravlyov29ddd2b2016-05-24 18:37:18 +000065 // Number of reserved VGPRs for debugger usage.
66 unsigned DebuggerReservedVGPRCount;
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000067 // Stack object indices for work group IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000068 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000069 // Stack object indices for work item IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000070 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +000071
Matt Arsenault49affb82015-11-25 20:55:12 +000072public:
73 // FIXME: Make private
74 unsigned LDSWaveSpillSize;
Marek Olsakfccabaf2016-01-13 11:45:36 +000075 unsigned PSInputEna;
Matt Arsenault49affb82015-11-25 20:55:12 +000076 std::map<unsigned, unsigned> LaneVGPRs;
77 unsigned ScratchOffsetReg;
78 unsigned NumUserSGPRs;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000079 unsigned NumSystemSGPRs;
Matt Arsenault49affb82015-11-25 20:55:12 +000080
81private:
Matt Arsenault5b22dfa2015-11-05 05:27:10 +000082 bool HasSpilledSGPRs;
Tom Stellard42fb60e2015-01-14 15:42:31 +000083 bool HasSpilledVGPRs;
Matt Arsenault296b8492016-02-12 06:31:30 +000084 bool HasNonSpillStackObjects;
Tom Stellard96468902014-09-24 01:33:17 +000085
Marek Olsak0532c192016-07-13 17:35:15 +000086 unsigned NumSpilledSGPRs;
87 unsigned NumSpilledVGPRs;
88
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000089 // Feature bits required for inputs passed in user SGPRs.
90 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +000091 bool DispatchPtr : 1;
92 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +000093 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +000094 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +000095 bool FlatScratchInit : 1;
96 bool GridWorkgroupCountX : 1;
97 bool GridWorkgroupCountY : 1;
98 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +000099
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000100 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000101 bool WorkGroupIDX : 1; // Always initialized.
102 bool WorkGroupIDY : 1;
103 bool WorkGroupIDZ : 1;
104 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000105 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000106
107 bool WorkItemIDX : 1; // Always initialized.
108 bool WorkItemIDY : 1;
109 bool WorkItemIDZ : 1;
110
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000111 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
Matt Arsenault49affb82015-11-25 20:55:12 +0000120public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000121 struct SpilledReg {
122 unsigned VGPR;
123 int Lane;
124 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
Tom Stellard649b5db2016-03-04 18:31:18 +0000125 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
Tom Stellardc149dc02013-11-27 21:23:35 +0000126 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000127 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000128 };
129
Tom Stellardc149dc02013-11-27 21:23:35 +0000130 // SIMachineFunctionInfo definition
131
Tom Stellard75aadc22012-12-11 21:25:42 +0000132 SIMachineFunctionInfo(const MachineFunction &MF);
Tom Stellardc5cf2f02014-08-21 20:40:54 +0000133 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
134 unsigned SubIdx);
Tom Stellard96468902014-09-24 01:33:17 +0000135 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
136 unsigned getTIDReg() const { return TIDReg; };
137 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000138
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000139 // 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);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000144 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000145 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000146
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
Tom Stellardf110f8f2016-04-14 16:27:03 +0000178 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
179 PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
180 }
181
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000182 bool hasPrivateSegmentBuffer() const {
183 return PrivateSegmentBuffer;
184 }
185
Matt Arsenault49affb82015-11-25 20:55:12 +0000186 bool hasDispatchPtr() const {
187 return DispatchPtr;
188 }
189
190 bool hasQueuePtr() const {
191 return QueuePtr;
192 }
193
Matt Arsenault49affb82015-11-25 20:55:12 +0000194 bool hasKernargSegmentPtr() const {
195 return KernargSegmentPtr;
196 }
197
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000198 bool hasDispatchID() const {
199 return DispatchID;
200 }
201
Matt Arsenault49affb82015-11-25 20:55:12 +0000202 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
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000234 bool hasPrivateSegmentWaveByteOffset() const {
235 return PrivateSegmentWaveByteOffset;
236 }
237
Matt Arsenault49affb82015-11-25 20:55:12 +0000238 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
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000250 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
Matt Arsenault49affb82015-11-25 20:55:12 +0000262 /// \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
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000268 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 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000281
Matt Arsenault99c14522016-04-25 19:27:24 +0000282 unsigned getQueuePtrUserSGPR() const {
283 return QueuePtrUserSGPR;
284 }
285
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000286 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 }
Tom Stellard96468902014-09-24 01:33:17 +0000301
Matt Arsenault296b8492016-02-12 06:31:30 +0000302 bool hasNonSpillStackObjects() const {
303 return HasNonSpillStackObjects;
304 }
305
306 void setHasNonSpillStackObjects(bool StackObject = true) {
307 HasNonSpillStackObjects = StackObject;
308 }
309
Marek Olsak0532c192016-07-13 17:35:15 +0000310 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
Marek Olsakfccabaf2016-01-13 11:45:36 +0000326 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
Marek Olsak8e9cc632016-01-13 17:23:09 +0000338 bool returnsVoid() const {
339 return ReturnsVoid;
340 }
341
342 void setIfReturnsVoid(bool Value) {
343 ReturnsVoid = Value;
344 }
345
Konstantin Zhuravlyov29ddd2b2016-05-24 18:37:18 +0000346 /// \returns Number of reserved VGPRs for debugger usage.
347 unsigned getDebuggerReservedVGPRCount() const {
348 return DebuggerReservedVGPRCount;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000349 }
350
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000351 /// \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
Tom Stellard96468902014-09-24 01:33:17 +0000407 unsigned getMaximumWorkGroupSize(const MachineFunction &MF) const;
Tom Stellard75aadc22012-12-11 21:25:42 +0000408};
409
410} // End namespace llvm
411
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000412#endif