blob: 3b4e233cd787d3746e7a0adb6c24381b0941388a [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 Stellard244891d2016-12-20 15:52:17 +000026class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
27public:
28 explicit AMDGPUImagePseudoSourceValue() :
29 PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
30
31 bool isConstant(const MachineFrameInfo *) const override {
32 // This should probably be true for most images, but we will start by being
33 // conservative.
34 return false;
35 }
36
37 bool isAliased(const MachineFrameInfo *) const override {
38 // FIXME: If we ever change image intrinsics to accept fat pointers, then
39 // this could be true for some cases.
40 return false;
41 }
42
43 bool mayAlias(const MachineFrameInfo*) const override {
44 // FIXME: If we ever change image intrinsics to accept fat pointers, then
45 // this could be true for some cases.
46 return false;
47 }
48};
49
Tom Stellard6f9ef142016-12-20 17:19:44 +000050class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
51public:
52 explicit AMDGPUBufferPseudoSourceValue() :
53 PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
54
55 bool isConstant(const MachineFrameInfo *) const override {
56 // This should probably be true for most images, but we will start by being
57 // conservative.
58 return false;
59 }
60
61 bool isAliased(const MachineFrameInfo *) const override {
62 // FIXME: If we ever change image intrinsics to accept fat pointers, then
63 // this could be true for some cases.
64 return false;
65 }
66
67 bool mayAlias(const MachineFrameInfo*) const override {
68 // FIXME: If we ever change image intrinsics to accept fat pointers, then
69 // this could be true for some cases.
70 return false;
71 }
72};
Tom Stellard244891d2016-12-20 15:52:17 +000073
Tom Stellard75aadc22012-12-11 21:25:42 +000074/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
75/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000076class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000077 // FIXME: This should be removed and getPreloadedValue moved here.
Saleem Abdulrasool43e5fe32016-08-29 20:42:07 +000078 friend class SIRegisterInfo;
Tom Stellard96468902014-09-24 01:33:17 +000079
80 unsigned TIDReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000081
82 // Registers that may be reserved for spilling purposes. These may be the same
83 // as the input registers.
Matt Arsenault49affb82015-11-25 20:55:12 +000084 unsigned ScratchRSrcReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000085 unsigned ScratchWaveOffsetReg;
86
87 // Input registers setup for the HSA ABI.
88 // User SGPRs in allocation order.
89 unsigned PrivateSegmentBufferUserSGPR;
90 unsigned DispatchPtrUserSGPR;
91 unsigned QueuePtrUserSGPR;
92 unsigned KernargSegmentPtrUserSGPR;
93 unsigned DispatchIDUserSGPR;
94 unsigned FlatScratchInitUserSGPR;
95 unsigned PrivateSegmentSizeUserSGPR;
96 unsigned GridWorkGroupCountXUserSGPR;
97 unsigned GridWorkGroupCountYUserSGPR;
98 unsigned GridWorkGroupCountZUserSGPR;
99
100 // System SGPRs in allocation order.
101 unsigned WorkGroupIDXSystemSGPR;
102 unsigned WorkGroupIDYSystemSGPR;
103 unsigned WorkGroupIDZSystemSGPR;
104 unsigned WorkGroupInfoSystemSGPR;
105 unsigned PrivateSegmentWaveByteOffsetSystemSGPR;
Matt Arsenault49affb82015-11-25 20:55:12 +0000106
Marek Olsakfccabaf2016-01-13 11:45:36 +0000107 // Graphics info.
108 unsigned PSInputAddr;
Marek Olsak8e9cc632016-01-13 17:23:09 +0000109 bool ReturnsVoid;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000110
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000111 // A pair of default/requested minimum/maximum flat work group sizes.
112 // Minimum - first, maximum - second.
113 std::pair<unsigned, unsigned> FlatWorkGroupSizes;
Tom Stellard79a1fd72016-04-14 16:27:07 +0000114
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000115 // A pair of default/requested minimum/maximum number of waves per execution
116 // unit. Minimum - first, maximum - second.
117 std::pair<unsigned, unsigned> WavesPerEU;
118
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000119 // Stack object indices for work group IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +0000120 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000121 // Stack object indices for work item IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +0000122 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000123
Tom Stellard6f9ef142016-12-20 17:19:44 +0000124 AMDGPUBufferPseudoSourceValue BufferPSV;
Tom Stellardbb138882016-12-20 17:26:34 +0000125 AMDGPUImagePseudoSourceValue ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000126
Matt Arsenault49affb82015-11-25 20:55:12 +0000127public:
128 // FIXME: Make private
129 unsigned LDSWaveSpillSize;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000130 unsigned PSInputEna;
Matt Arsenault49affb82015-11-25 20:55:12 +0000131 std::map<unsigned, unsigned> LaneVGPRs;
132 unsigned ScratchOffsetReg;
133 unsigned NumUserSGPRs;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000134 unsigned NumSystemSGPRs;
Matt Arsenault49affb82015-11-25 20:55:12 +0000135
136private:
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000137 bool HasSpilledSGPRs;
Tom Stellard42fb60e2015-01-14 15:42:31 +0000138 bool HasSpilledVGPRs;
Matt Arsenault296b8492016-02-12 06:31:30 +0000139 bool HasNonSpillStackObjects;
Tom Stellard96468902014-09-24 01:33:17 +0000140
Marek Olsak0532c192016-07-13 17:35:15 +0000141 unsigned NumSpilledSGPRs;
142 unsigned NumSpilledVGPRs;
143
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000144 // Feature bits required for inputs passed in user SGPRs.
145 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000146 bool DispatchPtr : 1;
147 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000148 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000149 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000150 bool FlatScratchInit : 1;
151 bool GridWorkgroupCountX : 1;
152 bool GridWorkgroupCountY : 1;
153 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000154
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000155 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000156 bool WorkGroupIDX : 1; // Always initialized.
157 bool WorkGroupIDY : 1;
158 bool WorkGroupIDZ : 1;
159 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000160 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000161
162 bool WorkItemIDX : 1; // Always initialized.
163 bool WorkItemIDY : 1;
164 bool WorkItemIDZ : 1;
165
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000166 MCPhysReg getNextUserSGPR() const {
167 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
168 return AMDGPU::SGPR0 + NumUserSGPRs;
169 }
170
171 MCPhysReg getNextSystemSGPR() const {
172 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
173 }
174
Matt Arsenault49affb82015-11-25 20:55:12 +0000175public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000176 struct SpilledReg {
177 unsigned VGPR;
178 int Lane;
179 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
Tom Stellard649b5db2016-03-04 18:31:18 +0000180 SpilledReg() : VGPR(AMDGPU::NoRegister), Lane(-1) { }
Tom Stellardc149dc02013-11-27 21:23:35 +0000181 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000182 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000183 };
184
Tom Stellardc149dc02013-11-27 21:23:35 +0000185 // SIMachineFunctionInfo definition
186
Tom Stellard75aadc22012-12-11 21:25:42 +0000187 SIMachineFunctionInfo(const MachineFunction &MF);
Tom Stellardc5cf2f02014-08-21 20:40:54 +0000188 SpilledReg getSpilledReg(MachineFunction *MF, unsigned FrameIndex,
189 unsigned SubIdx);
Tom Stellard96468902014-09-24 01:33:17 +0000190 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
191 unsigned getTIDReg() const { return TIDReg; };
192 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000193
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000194 // Add user SGPRs.
195 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
196 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
197 unsigned addQueuePtr(const SIRegisterInfo &TRI);
198 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000199 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000200 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000201
202 // Add system SGPRs.
203 unsigned addWorkGroupIDX() {
204 WorkGroupIDXSystemSGPR = getNextSystemSGPR();
205 NumSystemSGPRs += 1;
206 return WorkGroupIDXSystemSGPR;
207 }
208
209 unsigned addWorkGroupIDY() {
210 WorkGroupIDYSystemSGPR = getNextSystemSGPR();
211 NumSystemSGPRs += 1;
212 return WorkGroupIDYSystemSGPR;
213 }
214
215 unsigned addWorkGroupIDZ() {
216 WorkGroupIDZSystemSGPR = getNextSystemSGPR();
217 NumSystemSGPRs += 1;
218 return WorkGroupIDZSystemSGPR;
219 }
220
221 unsigned addWorkGroupInfo() {
222 WorkGroupInfoSystemSGPR = getNextSystemSGPR();
223 NumSystemSGPRs += 1;
224 return WorkGroupInfoSystemSGPR;
225 }
226
227 unsigned addPrivateSegmentWaveByteOffset() {
228 PrivateSegmentWaveByteOffsetSystemSGPR = getNextSystemSGPR();
229 NumSystemSGPRs += 1;
230 return PrivateSegmentWaveByteOffsetSystemSGPR;
231 }
232
Tom Stellardf110f8f2016-04-14 16:27:03 +0000233 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
234 PrivateSegmentWaveByteOffsetSystemSGPR = Reg;
235 }
236
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000237 bool hasPrivateSegmentBuffer() const {
238 return PrivateSegmentBuffer;
239 }
240
Matt Arsenault49affb82015-11-25 20:55:12 +0000241 bool hasDispatchPtr() const {
242 return DispatchPtr;
243 }
244
245 bool hasQueuePtr() const {
246 return QueuePtr;
247 }
248
Matt Arsenault49affb82015-11-25 20:55:12 +0000249 bool hasKernargSegmentPtr() const {
250 return KernargSegmentPtr;
251 }
252
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000253 bool hasDispatchID() const {
254 return DispatchID;
255 }
256
Matt Arsenault49affb82015-11-25 20:55:12 +0000257 bool hasFlatScratchInit() const {
258 return FlatScratchInit;
259 }
260
261 bool hasGridWorkgroupCountX() const {
262 return GridWorkgroupCountX;
263 }
264
265 bool hasGridWorkgroupCountY() const {
266 return GridWorkgroupCountY;
267 }
268
269 bool hasGridWorkgroupCountZ() const {
270 return GridWorkgroupCountZ;
271 }
272
273 bool hasWorkGroupIDX() const {
274 return WorkGroupIDX;
275 }
276
277 bool hasWorkGroupIDY() const {
278 return WorkGroupIDY;
279 }
280
281 bool hasWorkGroupIDZ() const {
282 return WorkGroupIDZ;
283 }
284
285 bool hasWorkGroupInfo() const {
286 return WorkGroupInfo;
287 }
288
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000289 bool hasPrivateSegmentWaveByteOffset() const {
290 return PrivateSegmentWaveByteOffset;
291 }
292
Matt Arsenault49affb82015-11-25 20:55:12 +0000293 bool hasWorkItemIDX() const {
294 return WorkItemIDX;
295 }
296
297 bool hasWorkItemIDY() const {
298 return WorkItemIDY;
299 }
300
301 bool hasWorkItemIDZ() const {
302 return WorkItemIDZ;
303 }
304
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000305 unsigned getNumUserSGPRs() const {
306 return NumUserSGPRs;
307 }
308
309 unsigned getNumPreloadedSGPRs() const {
310 return NumUserSGPRs + NumSystemSGPRs;
311 }
312
313 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
314 return PrivateSegmentWaveByteOffsetSystemSGPR;
315 }
316
Matt Arsenault49affb82015-11-25 20:55:12 +0000317 /// \brief Returns the physical register reserved for use as the resource
318 /// descriptor for scratch accesses.
319 unsigned getScratchRSrcReg() const {
320 return ScratchRSrcReg;
321 }
322
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000323 void setScratchRSrcReg(unsigned Reg) {
324 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
325 ScratchRSrcReg = Reg;
326 }
327
328 unsigned getScratchWaveOffsetReg() const {
329 return ScratchWaveOffsetReg;
330 }
331
332 void setScratchWaveOffsetReg(unsigned Reg) {
333 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
334 ScratchWaveOffsetReg = Reg;
335 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000336
Matt Arsenault99c14522016-04-25 19:27:24 +0000337 unsigned getQueuePtrUserSGPR() const {
338 return QueuePtrUserSGPR;
339 }
340
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000341 bool hasSpilledSGPRs() const {
342 return HasSpilledSGPRs;
343 }
344
345 void setHasSpilledSGPRs(bool Spill = true) {
346 HasSpilledSGPRs = Spill;
347 }
348
349 bool hasSpilledVGPRs() const {
350 return HasSpilledVGPRs;
351 }
352
353 void setHasSpilledVGPRs(bool Spill = true) {
354 HasSpilledVGPRs = Spill;
355 }
Tom Stellard96468902014-09-24 01:33:17 +0000356
Matt Arsenault296b8492016-02-12 06:31:30 +0000357 bool hasNonSpillStackObjects() const {
358 return HasNonSpillStackObjects;
359 }
360
361 void setHasNonSpillStackObjects(bool StackObject = true) {
362 HasNonSpillStackObjects = StackObject;
363 }
364
Marek Olsak0532c192016-07-13 17:35:15 +0000365 unsigned getNumSpilledSGPRs() const {
366 return NumSpilledSGPRs;
367 }
368
369 unsigned getNumSpilledVGPRs() const {
370 return NumSpilledVGPRs;
371 }
372
373 void addToSpilledSGPRs(unsigned num) {
374 NumSpilledSGPRs += num;
375 }
376
377 void addToSpilledVGPRs(unsigned num) {
378 NumSpilledVGPRs += num;
379 }
380
Marek Olsakfccabaf2016-01-13 11:45:36 +0000381 unsigned getPSInputAddr() const {
382 return PSInputAddr;
383 }
384
385 bool isPSInputAllocated(unsigned Index) const {
386 return PSInputAddr & (1 << Index);
387 }
388
389 void markPSInputAllocated(unsigned Index) {
390 PSInputAddr |= 1 << Index;
391 }
392
Marek Olsak8e9cc632016-01-13 17:23:09 +0000393 bool returnsVoid() const {
394 return ReturnsVoid;
395 }
396
397 void setIfReturnsVoid(bool Value) {
398 ReturnsVoid = Value;
399 }
400
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000401 /// \returns A pair of default/requested minimum/maximum flat work group sizes
402 /// for this function.
403 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
404 return FlatWorkGroupSizes;
405 }
406
407 /// \returns Default/requested minimum flat work group size for this function.
408 unsigned getMinFlatWorkGroupSize() const {
409 return FlatWorkGroupSizes.first;
410 }
411
412 /// \returns Default/requested maximum flat work group size for this function.
413 unsigned getMaxFlatWorkGroupSize() const {
414 return FlatWorkGroupSizes.second;
415 }
416
417 /// \returns A pair of default/requested minimum/maximum number of waves per
418 /// execution unit.
419 std::pair<unsigned, unsigned> getWavesPerEU() const {
420 return WavesPerEU;
421 }
422
423 /// \returns Default/requested minimum number of waves per execution unit.
424 unsigned getMinWavesPerEU() const {
425 return WavesPerEU.first;
426 }
427
428 /// \returns Default/requested maximum number of waves per execution unit.
429 unsigned getMaxWavesPerEU() const {
430 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000431 }
432
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000433 /// \returns Stack object index for \p Dim's work group ID.
434 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
435 assert(Dim < 3);
436 return DebuggerWorkGroupIDStackObjectIndices[Dim];
437 }
438
439 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
440 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
441 assert(Dim < 3);
442 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
443 }
444
445 /// \returns Stack object index for \p Dim's work item ID.
446 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
447 assert(Dim < 3);
448 return DebuggerWorkItemIDStackObjectIndices[Dim];
449 }
450
451 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
452 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
453 assert(Dim < 3);
454 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
455 }
456
457 /// \returns SGPR used for \p Dim's work group ID.
458 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
459 switch (Dim) {
460 case 0:
461 assert(hasWorkGroupIDX());
462 return WorkGroupIDXSystemSGPR;
463 case 1:
464 assert(hasWorkGroupIDY());
465 return WorkGroupIDYSystemSGPR;
466 case 2:
467 assert(hasWorkGroupIDZ());
468 return WorkGroupIDZSystemSGPR;
469 }
470 llvm_unreachable("unexpected dimension");
471 }
472
473 /// \returns VGPR used for \p Dim' work item ID.
474 unsigned getWorkItemIDVGPR(unsigned Dim) const {
475 switch (Dim) {
476 case 0:
477 assert(hasWorkItemIDX());
478 return AMDGPU::VGPR0;
479 case 1:
480 assert(hasWorkItemIDY());
481 return AMDGPU::VGPR1;
482 case 2:
483 assert(hasWorkItemIDZ());
484 return AMDGPU::VGPR2;
485 }
486 llvm_unreachable("unexpected dimension");
487 }
Tom Stellard244891d2016-12-20 15:52:17 +0000488
Tom Stellard6f9ef142016-12-20 17:19:44 +0000489 const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
490 return &BufferPSV;
491 }
492
Tom Stellardbb138882016-12-20 17:26:34 +0000493 const AMDGPUImagePseudoSourceValue *getImagePSV() const {
494 return &ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000495 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000496};
497
498} // End namespace llvm
499
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000500#endif