blob: 7edac8950ec42aa2cb017575c13424b827820e69 [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.
Saleem Abdulrasool43e5fe32016-08-29 20:42:07 +000030 friend class 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
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000063 // A pair of default/requested minimum/maximum flat work group sizes.
64 // Minimum - first, maximum - second.
65 std::pair<unsigned, unsigned> FlatWorkGroupSizes;
Tom Stellard79a1fd72016-04-14 16:27:07 +000066
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +000067 // A pair of default/requested minimum/maximum number of waves per execution
68 // unit. Minimum - first, maximum - second.
69 std::pair<unsigned, unsigned> WavesPerEU;
70
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000071 // Stack object indices for work group IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000072 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000073 // Stack object indices for work item IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000074 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +000075
Matt Arsenault49affb82015-11-25 20:55:12 +000076public:
77 // FIXME: Make private
78 unsigned LDSWaveSpillSize;
Marek Olsakfccabaf2016-01-13 11:45:36 +000079 unsigned PSInputEna;
Matt Arsenault49affb82015-11-25 20:55:12 +000080 std::map<unsigned, unsigned> LaneVGPRs;
81 unsigned ScratchOffsetReg;
82 unsigned NumUserSGPRs;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000083 unsigned NumSystemSGPRs;
Matt Arsenault49affb82015-11-25 20:55:12 +000084
85private:
Matt Arsenault5b22dfa2015-11-05 05:27:10 +000086 bool HasSpilledSGPRs;
Tom Stellard42fb60e2015-01-14 15:42:31 +000087 bool HasSpilledVGPRs;
Matt Arsenault296b8492016-02-12 06:31:30 +000088 bool HasNonSpillStackObjects;
Tom Stellard96468902014-09-24 01:33:17 +000089
Marek Olsak0532c192016-07-13 17:35:15 +000090 unsigned NumSpilledSGPRs;
91 unsigned NumSpilledVGPRs;
92
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000093 // Feature bits required for inputs passed in user SGPRs.
94 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +000095 bool DispatchPtr : 1;
96 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +000097 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +000098 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +000099 bool FlatScratchInit : 1;
100 bool GridWorkgroupCountX : 1;
101 bool GridWorkgroupCountY : 1;
102 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000103
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000104 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000105 bool WorkGroupIDX : 1; // Always initialized.
106 bool WorkGroupIDY : 1;
107 bool WorkGroupIDZ : 1;
108 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000109 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000110
111 bool WorkItemIDX : 1; // Always initialized.
112 bool WorkItemIDY : 1;
113 bool WorkItemIDZ : 1;
114
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000115 MCPhysReg getNextUserSGPR() const {
116 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
117 return AMDGPU::SGPR0 + NumUserSGPRs;
118 }
119
120 MCPhysReg getNextSystemSGPR() const {
121 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
122 }
123
Matt Arsenault49affb82015-11-25 20:55:12 +0000124public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000125 struct SpilledReg {
126 unsigned VGPR;
127 int Lane;
128 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
Tom Stellard649b5db2016-03-04 18:31:18 +0000129 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
Tom Stellardc149dc02013-11-27 21:23:35 +0000130 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000131 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000132 };
133
Tom Stellardc149dc02013-11-27 21:23:35 +0000134 // SIMachineFunctionInfo definition
135
Tom Stellard75aadc22012-12-11 21:25:42 +0000136 SIMachineFunctionInfo(const MachineFunction &MF);
Tom Stellardc5cf2f02014-08-21 20:40:54 +0000137 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
138 unsigned SubIdx);
Tom Stellard96468902014-09-24 01:33:17 +0000139 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
140 unsigned getTIDReg() const { return TIDReg; };
141 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000142
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000143 // Add user SGPRs.
144 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
145 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
146 unsigned addQueuePtr(const SIRegisterInfo &TRI);
147 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000148 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000149 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000150
151 // Add system SGPRs.
152 unsigned addWorkGroupIDX() {
153 WorkGroupIDXSystemSGPR = getNextSystemSGPR();
154 NumSystemSGPRs += 1;
155 return WorkGroupIDXSystemSGPR;
156 }
157
158 unsigned addWorkGroupIDY() {
159 WorkGroupIDYSystemSGPR = getNextSystemSGPR();
160 NumSystemSGPRs += 1;
161 return WorkGroupIDYSystemSGPR;
162 }
163
164 unsigned addWorkGroupIDZ() {
165 WorkGroupIDZSystemSGPR = getNextSystemSGPR();
166 NumSystemSGPRs += 1;
167 return WorkGroupIDZSystemSGPR;
168 }
169
170 unsigned addWorkGroupInfo() {
171 WorkGroupInfoSystemSGPR = getNextSystemSGPR();
172 NumSystemSGPRs += 1;
173 return WorkGroupInfoSystemSGPR;
174 }
175
176 unsigned addPrivateSegmentWaveByteOffset() {
177 PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
178 NumSystemSGPRs += 1;
179 return PrivateSegmentWaveByteOffsetSystemSGPR;
180 }
181
Tom Stellardf110f8f2016-04-14 16:27:03 +0000182 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
183 PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
184 }
185
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000186 bool hasPrivateSegmentBuffer() const {
187 return PrivateSegmentBuffer;
188 }
189
Matt Arsenault49affb82015-11-25 20:55:12 +0000190 bool hasDispatchPtr() const {
191 return DispatchPtr;
192 }
193
194 bool hasQueuePtr() const {
195 return QueuePtr;
196 }
197
Matt Arsenault49affb82015-11-25 20:55:12 +0000198 bool hasKernargSegmentPtr() const {
199 return KernargSegmentPtr;
200 }
201
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000202 bool hasDispatchID() const {
203 return DispatchID;
204 }
205
Matt Arsenault49affb82015-11-25 20:55:12 +0000206 bool hasFlatScratchInit() const {
207 return FlatScratchInit;
208 }
209
210 bool hasGridWorkgroupCountX() const {
211 return GridWorkgroupCountX;
212 }
213
214 bool hasGridWorkgroupCountY() const {
215 return GridWorkgroupCountY;
216 }
217
218 bool hasGridWorkgroupCountZ() const {
219 return GridWorkgroupCountZ;
220 }
221
222 bool hasWorkGroupIDX() const {
223 return WorkGroupIDX;
224 }
225
226 bool hasWorkGroupIDY() const {
227 return WorkGroupIDY;
228 }
229
230 bool hasWorkGroupIDZ() const {
231 return WorkGroupIDZ;
232 }
233
234 bool hasWorkGroupInfo() const {
235 return WorkGroupInfo;
236 }
237
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000238 bool hasPrivateSegmentWaveByteOffset() const {
239 return PrivateSegmentWaveByteOffset;
240 }
241
Matt Arsenault49affb82015-11-25 20:55:12 +0000242 bool hasWorkItemIDX() const {
243 return WorkItemIDX;
244 }
245
246 bool hasWorkItemIDY() const {
247 return WorkItemIDY;
248 }
249
250 bool hasWorkItemIDZ() const {
251 return WorkItemIDZ;
252 }
253
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000254 unsigned getNumUserSGPRs() const {
255 return NumUserSGPRs;
256 }
257
258 unsigned getNumPreloadedSGPRs() const {
259 return NumUserSGPRs + NumSystemSGPRs;
260 }
261
262 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
263 return PrivateSegmentWaveByteOffsetSystemSGPR;
264 }
265
Matt Arsenault49affb82015-11-25 20:55:12 +0000266 /// \brief Returns the physical register reserved for use as the resource
267 /// descriptor for scratch accesses.
268 unsigned getScratchRSrcReg() const {
269 return ScratchRSrcReg;
270 }
271
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000272 void setScratchRSrcReg(unsigned Reg) {
273 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
274 ScratchRSrcReg = Reg;
275 }
276
277 unsigned getScratchWaveOffsetReg() const {
278 return ScratchWaveOffsetReg;
279 }
280
281 void setScratchWaveOffsetReg(unsigned Reg) {
282 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
283 ScratchWaveOffsetReg = Reg;
284 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000285
Matt Arsenault99c14522016-04-25 19:27:24 +0000286 unsigned getQueuePtrUserSGPR() const {
287 return QueuePtrUserSGPR;
288 }
289
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000290 bool hasSpilledSGPRs() const {
291 return HasSpilledSGPRs;
292 }
293
294 void setHasSpilledSGPRs(bool Spill = true) {
295 HasSpilledSGPRs = Spill;
296 }
297
298 bool hasSpilledVGPRs() const {
299 return HasSpilledVGPRs;
300 }
301
302 void setHasSpilledVGPRs(bool Spill = true) {
303 HasSpilledVGPRs = Spill;
304 }
Tom Stellard96468902014-09-24 01:33:17 +0000305
Matt Arsenault296b8492016-02-12 06:31:30 +0000306 bool hasNonSpillStackObjects() const {
307 return HasNonSpillStackObjects;
308 }
309
310 void setHasNonSpillStackObjects(bool StackObject = true) {
311 HasNonSpillStackObjects = StackObject;
312 }
313
Marek Olsak0532c192016-07-13 17:35:15 +0000314 unsigned getNumSpilledSGPRs() const {
315 return NumSpilledSGPRs;
316 }
317
318 unsigned getNumSpilledVGPRs() const {
319 return NumSpilledVGPRs;
320 }
321
322 void addToSpilledSGPRs(unsigned num) {
323 NumSpilledSGPRs += num;
324 }
325
326 void addToSpilledVGPRs(unsigned num) {
327 NumSpilledVGPRs += num;
328 }
329
Marek Olsakfccabaf2016-01-13 11:45:36 +0000330 unsigned getPSInputAddr() const {
331 return PSInputAddr;
332 }
333
334 bool isPSInputAllocated(unsigned Index) const {
335 return PSInputAddr & (1 << Index);
336 }
337
338 void markPSInputAllocated(unsigned Index) {
339 PSInputAddr |= 1 << Index;
340 }
341
Marek Olsak8e9cc632016-01-13 17:23:09 +0000342 bool returnsVoid() const {
343 return ReturnsVoid;
344 }
345
346 void setIfReturnsVoid(bool Value) {
347 ReturnsVoid = Value;
348 }
349
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000350 /// \returns A pair of default/requested minimum/maximum flat work group sizes
351 /// for this function.
352 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
353 return FlatWorkGroupSizes;
354 }
355
356 /// \returns Default/requested minimum flat work group size for this function.
357 unsigned getMinFlatWorkGroupSize() const {
358 return FlatWorkGroupSizes.first;
359 }
360
361 /// \returns Default/requested maximum flat work group size for this function.
362 unsigned getMaxFlatWorkGroupSize() const {
363 return FlatWorkGroupSizes.second;
364 }
365
366 /// \returns A pair of default/requested minimum/maximum number of waves per
367 /// execution unit.
368 std::pair<unsigned, unsigned> getWavesPerEU() const {
369 return WavesPerEU;
370 }
371
372 /// \returns Default/requested minimum number of waves per execution unit.
373 unsigned getMinWavesPerEU() const {
374 return WavesPerEU.first;
375 }
376
377 /// \returns Default/requested maximum number of waves per execution unit.
378 unsigned getMaxWavesPerEU() const {
379 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000380 }
381
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000382 /// \returns Stack object index for \p Dim's work group ID.
383 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
384 assert(Dim < 3);
385 return DebuggerWorkGroupIDStackObjectIndices[Dim];
386 }
387
388 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
389 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
390 assert(Dim < 3);
391 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
392 }
393
394 /// \returns Stack object index for \p Dim's work item ID.
395 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
396 assert(Dim < 3);
397 return DebuggerWorkItemIDStackObjectIndices[Dim];
398 }
399
400 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
401 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
402 assert(Dim < 3);
403 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
404 }
405
406 /// \returns SGPR used for \p Dim's work group ID.
407 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
408 switch (Dim) {
409 case 0:
410 assert(hasWorkGroupIDX());
411 return WorkGroupIDXSystemSGPR;
412 case 1:
413 assert(hasWorkGroupIDY());
414 return WorkGroupIDYSystemSGPR;
415 case 2:
416 assert(hasWorkGroupIDZ());
417 return WorkGroupIDZSystemSGPR;
418 }
419 llvm_unreachable("unexpected dimension");
420 }
421
422 /// \returns VGPR used for \p Dim' work item ID.
423 unsigned getWorkItemIDVGPR(unsigned Dim) const {
424 switch (Dim) {
425 case 0:
426 assert(hasWorkItemIDX());
427 return AMDGPU::VGPR0;
428 case 1:
429 assert(hasWorkItemIDY());
430 return AMDGPU::VGPR1;
431 case 2:
432 assert(hasWorkItemIDZ());
433 return AMDGPU::VGPR2;
434 }
435 llvm_unreachable("unexpected dimension");
436 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000437};
438
439} // End namespace llvm
440
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000441#endif