blob: 5581fe4c55e4d8b4370536dcfee4948c86679b4b [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"
Matt Arsenault678e1112017-04-10 17:58:06 +000018#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
Matt Arsenault8623e8d2017-08-03 23:00:29 +000019#include "AMDGPUArgumentUsageInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000020#include "SIRegisterInfo.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000021#include "llvm/CodeGen/PseudoSourceValue.h"
22#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/Support/ErrorHandling.h"
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000024#include <array>
Eugene Zelenko66203762017-01-21 00:53:49 +000025#include <cassert>
Tom Stellardc149dc02013-11-27 21:23:35 +000026#include <map>
Eugene Zelenko66203762017-01-21 00:53:49 +000027#include <utility>
Tom Stellard75aadc22012-12-11 21:25:42 +000028
29namespace llvm {
30
Tom Stellard244891d2016-12-20 15:52:17 +000031class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
32public:
33 explicit AMDGPUImagePseudoSourceValue() :
34 PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
35
36 bool isConstant(const MachineFrameInfo *) const override {
37 // This should probably be true for most images, but we will start by being
38 // conservative.
39 return false;
40 }
41
42 bool isAliased(const MachineFrameInfo *) const override {
43 // FIXME: If we ever change image intrinsics to accept fat pointers, then
44 // this could be true for some cases.
45 return false;
46 }
47
48 bool mayAlias(const MachineFrameInfo*) const override {
49 // FIXME: If we ever change image intrinsics to accept fat pointers, then
50 // this could be true for some cases.
51 return false;
52 }
53};
54
Tom Stellard6f9ef142016-12-20 17:19:44 +000055class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
56public:
57 explicit AMDGPUBufferPseudoSourceValue() :
58 PseudoSourceValue(PseudoSourceValue::TargetCustom) { }
59
60 bool isConstant(const MachineFrameInfo *) const override {
61 // This should probably be true for most images, but we will start by being
62 // conservative.
63 return false;
64 }
65
66 bool isAliased(const MachineFrameInfo *) const override {
67 // FIXME: If we ever change image intrinsics to accept fat pointers, then
68 // this could be true for some cases.
69 return false;
70 }
71
72 bool mayAlias(const MachineFrameInfo*) const override {
73 // FIXME: If we ever change image intrinsics to accept fat pointers, then
74 // this could be true for some cases.
75 return false;
76 }
77};
Tom Stellard244891d2016-12-20 15:52:17 +000078
Tom Stellard75aadc22012-12-11 21:25:42 +000079/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
80/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000081class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000082 // FIXME: This should be removed and getPreloadedValue moved here.
Saleem Abdulrasool43e5fe32016-08-29 20:42:07 +000083 friend class SIRegisterInfo;
Tom Stellard96468902014-09-24 01:33:17 +000084
85 unsigned TIDReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000086
87 // Registers that may be reserved for spilling purposes. These may be the same
88 // as the input registers.
Matt Arsenault49affb82015-11-25 20:55:12 +000089 unsigned ScratchRSrcReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000090 unsigned ScratchWaveOffsetReg;
91
Matt Arsenault1c0ae392017-04-24 18:05:16 +000092 // This is the current function's incremented size from the kernel's scratch
93 // wave offset register. For an entry function, this is exactly the same as
94 // the ScratchWaveOffsetReg.
95 unsigned FrameOffsetReg;
96
97 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
98 unsigned StackPtrOffsetReg;
99
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000100 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000101
Marek Olsakfccabaf2016-01-13 11:45:36 +0000102 // Graphics info.
103 unsigned PSInputAddr;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000104 unsigned PSInputEnable;
105
Marek Olsak8e9cc632016-01-13 17:23:09 +0000106 bool ReturnsVoid;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000107
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000108 // A pair of default/requested minimum/maximum flat work group sizes.
109 // Minimum - first, maximum - second.
110 std::pair<unsigned, unsigned> FlatWorkGroupSizes;
Tom Stellard79a1fd72016-04-14 16:27:07 +0000111
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000112 // A pair of default/requested minimum/maximum number of waves per execution
113 // unit. Minimum - first, maximum - second.
114 std::pair<unsigned, unsigned> WavesPerEU;
115
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000116 // Stack object indices for work group IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +0000117 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices;
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000118 // Stack object indices for work item IDs.
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +0000119 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000120
Tom Stellard6f9ef142016-12-20 17:19:44 +0000121 AMDGPUBufferPseudoSourceValue BufferPSV;
Tom Stellardbb138882016-12-20 17:26:34 +0000122 AMDGPUImagePseudoSourceValue ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000123
Matt Arsenault161e2b42017-04-18 20:59:40 +0000124private:
Matt Arsenault49affb82015-11-25 20:55:12 +0000125 unsigned LDSWaveSpillSize;
Matt Arsenault49affb82015-11-25 20:55:12 +0000126 unsigned ScratchOffsetReg;
127 unsigned NumUserSGPRs;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000128 unsigned NumSystemSGPRs;
Matt Arsenault49affb82015-11-25 20:55:12 +0000129
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000130 bool HasSpilledSGPRs;
Tom Stellard42fb60e2015-01-14 15:42:31 +0000131 bool HasSpilledVGPRs;
Matt Arsenault296b8492016-02-12 06:31:30 +0000132 bool HasNonSpillStackObjects;
Tom Stellard96468902014-09-24 01:33:17 +0000133
Marek Olsak0532c192016-07-13 17:35:15 +0000134 unsigned NumSpilledSGPRs;
135 unsigned NumSpilledVGPRs;
136
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000137 // Feature bits required for inputs passed in user SGPRs.
138 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000139 bool DispatchPtr : 1;
140 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000141 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000142 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000143 bool FlatScratchInit : 1;
144 bool GridWorkgroupCountX : 1;
145 bool GridWorkgroupCountY : 1;
146 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000147
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000148 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000149 bool WorkGroupIDX : 1; // Always initialized.
150 bool WorkGroupIDY : 1;
151 bool WorkGroupIDZ : 1;
152 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000153 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000154
155 bool WorkItemIDX : 1; // Always initialized.
156 bool WorkItemIDY : 1;
157 bool WorkItemIDZ : 1;
158
Tom Stellard2f3f9852017-01-25 01:25:13 +0000159 // Private memory buffer
160 // Compute directly in sgpr[0:1]
161 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000162 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000163
Matt Arsenault9166ce82017-07-28 15:52:08 +0000164 // Pointer to where the ABI inserts special kernel arguments separate from the
165 // user arguments. This is an offset from the KernargSegmentPtr.
166 bool ImplicitArgPtr : 1;
167
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000168 MCPhysReg getNextUserSGPR() const {
169 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
170 return AMDGPU::SGPR0 + NumUserSGPRs;
171 }
172
173 MCPhysReg getNextSystemSGPR() const {
174 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
175 }
176
Matt Arsenault49affb82015-11-25 20:55:12 +0000177public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000178 struct SpilledReg {
Eugene Zelenko66203762017-01-21 00:53:49 +0000179 unsigned VGPR = AMDGPU::NoRegister;
180 int Lane = -1;
181
182 SpilledReg() = default;
Tom Stellardc149dc02013-11-27 21:23:35 +0000183 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) { }
Eugene Zelenko66203762017-01-21 00:53:49 +0000184
Tom Stellardc149dc02013-11-27 21:23:35 +0000185 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000186 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000187 };
188
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000189 struct SGPRSpillVGPRCSR {
190 // VGPR used for SGPR spills
191 unsigned VGPR;
192
193 // If the VGPR is a CSR, the stack slot used to save/restore it in the
194 // prolog/epilog.
195 Optional<int> FI;
196
197 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) :
198 VGPR(V),
199 FI(F) {}
200 };
201
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000202private:
203 // SGPR->VGPR spilling support.
204 typedef std::pair<unsigned, unsigned> SpillRegMask;
205
206 // Track VGPR + wave index for each subregister of the SGPR spilled to
207 // frameindex key.
208 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
209 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000210 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000211
212public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000213 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000214
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000215 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
216 auto I = SGPRToVGPRSpills.find(FrameIndex);
217 return (I == SGPRToVGPRSpills.end()) ?
218 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
219 }
220
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000221 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
222 return SpillVGPRs;
223 }
224
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000225 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
226 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
227
Tom Stellard96468902014-09-24 01:33:17 +0000228 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; };
229 unsigned getTIDReg() const { return TIDReg; };
230 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000231
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000232 // Add user SGPRs.
233 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
234 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
235 unsigned addQueuePtr(const SIRegisterInfo &TRI);
236 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000237 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000238 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000239 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000240
241 // Add system SGPRs.
242 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000243 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000244 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000245 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000246 }
247
248 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000249 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000250 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000251 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000252 }
253
254 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000255 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000256 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000257 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000258 }
259
260 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000261 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000262 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000263 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000264 }
265
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000266 // Add special VGPR inputs
267 void setWorkItemIDX(ArgDescriptor Arg) {
268 ArgInfo.WorkItemIDX = Arg;
269 }
270
271 void setWorkItemIDY(ArgDescriptor Arg) {
272 ArgInfo.WorkItemIDY = Arg;
273 }
274
275 void setWorkItemIDZ(ArgDescriptor Arg) {
276 ArgInfo.WorkItemIDZ = Arg;
277 }
278
279
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000280 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000281 ArgInfo.PrivateSegmentWaveByteOffset
282 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000283 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000284 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000285 }
286
Tom Stellardf110f8f2016-04-14 16:27:03 +0000287 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000288 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000289 }
290
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000291 bool hasPrivateSegmentBuffer() const {
292 return PrivateSegmentBuffer;
293 }
294
Matt Arsenault49affb82015-11-25 20:55:12 +0000295 bool hasDispatchPtr() const {
296 return DispatchPtr;
297 }
298
299 bool hasQueuePtr() const {
300 return QueuePtr;
301 }
302
Matt Arsenault49affb82015-11-25 20:55:12 +0000303 bool hasKernargSegmentPtr() const {
304 return KernargSegmentPtr;
305 }
306
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000307 bool hasDispatchID() const {
308 return DispatchID;
309 }
310
Matt Arsenault49affb82015-11-25 20:55:12 +0000311 bool hasFlatScratchInit() const {
312 return FlatScratchInit;
313 }
314
315 bool hasGridWorkgroupCountX() const {
316 return GridWorkgroupCountX;
317 }
318
319 bool hasGridWorkgroupCountY() const {
320 return GridWorkgroupCountY;
321 }
322
323 bool hasGridWorkgroupCountZ() const {
324 return GridWorkgroupCountZ;
325 }
326
327 bool hasWorkGroupIDX() const {
328 return WorkGroupIDX;
329 }
330
331 bool hasWorkGroupIDY() const {
332 return WorkGroupIDY;
333 }
334
335 bool hasWorkGroupIDZ() const {
336 return WorkGroupIDZ;
337 }
338
339 bool hasWorkGroupInfo() const {
340 return WorkGroupInfo;
341 }
342
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000343 bool hasPrivateSegmentWaveByteOffset() const {
344 return PrivateSegmentWaveByteOffset;
345 }
346
Matt Arsenault49affb82015-11-25 20:55:12 +0000347 bool hasWorkItemIDX() const {
348 return WorkItemIDX;
349 }
350
351 bool hasWorkItemIDY() const {
352 return WorkItemIDY;
353 }
354
355 bool hasWorkItemIDZ() const {
356 return WorkItemIDZ;
357 }
358
Matt Arsenault9166ce82017-07-28 15:52:08 +0000359 bool hasImplicitArgPtr() const {
360 return ImplicitArgPtr;
361 }
362
Matt Arsenault10fc0622017-06-26 03:01:31 +0000363 bool hasImplicitBufferPtr() const {
364 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000365 }
366
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000367 AMDGPUFunctionArgInfo &getArgInfo() {
368 return ArgInfo;
369 }
370
371 const AMDGPUFunctionArgInfo &getArgInfo() const {
372 return ArgInfo;
373 }
374
375 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
376 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
377 return ArgInfo.getPreloadedValue(Value);
378 }
379
380 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
381 return ArgInfo.getPreloadedValue(Value).first->getRegister();
382 }
383
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000384 unsigned getNumUserSGPRs() const {
385 return NumUserSGPRs;
386 }
387
388 unsigned getNumPreloadedSGPRs() const {
389 return NumUserSGPRs + NumSystemSGPRs;
390 }
391
392 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000393 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000394 }
395
Matt Arsenault49affb82015-11-25 20:55:12 +0000396 /// \brief Returns the physical register reserved for use as the resource
397 /// descriptor for scratch accesses.
398 unsigned getScratchRSrcReg() const {
399 return ScratchRSrcReg;
400 }
401
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000402 void setScratchRSrcReg(unsigned Reg) {
403 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
404 ScratchRSrcReg = Reg;
405 }
406
407 unsigned getScratchWaveOffsetReg() const {
408 return ScratchWaveOffsetReg;
409 }
410
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000411 unsigned getFrameOffsetReg() const {
412 return FrameOffsetReg;
413 }
414
415 void setStackPtrOffsetReg(unsigned Reg) {
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000416 StackPtrOffsetReg = Reg;
417 }
418
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000419 // Note the unset value for this is AMDGPU::SP_REG rather than
420 // NoRegister. This is mostly a workaround for MIR tests where state that
421 // can't be directly computed from the function is not preserved in serialized
422 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000423 unsigned getStackPtrOffsetReg() const {
424 return StackPtrOffsetReg;
425 }
426
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000427 void setScratchWaveOffsetReg(unsigned Reg) {
428 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
429 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000430 if (isEntryFunction())
431 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000432 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000433
Matt Arsenault99c14522016-04-25 19:27:24 +0000434 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000435 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000436 }
437
Matt Arsenault10fc0622017-06-26 03:01:31 +0000438 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000439 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000440 }
441
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000442 bool hasSpilledSGPRs() const {
443 return HasSpilledSGPRs;
444 }
445
446 void setHasSpilledSGPRs(bool Spill = true) {
447 HasSpilledSGPRs = Spill;
448 }
449
450 bool hasSpilledVGPRs() const {
451 return HasSpilledVGPRs;
452 }
453
454 void setHasSpilledVGPRs(bool Spill = true) {
455 HasSpilledVGPRs = Spill;
456 }
Tom Stellard96468902014-09-24 01:33:17 +0000457
Matt Arsenault296b8492016-02-12 06:31:30 +0000458 bool hasNonSpillStackObjects() const {
459 return HasNonSpillStackObjects;
460 }
461
462 void setHasNonSpillStackObjects(bool StackObject = true) {
463 HasNonSpillStackObjects = StackObject;
464 }
465
Marek Olsak0532c192016-07-13 17:35:15 +0000466 unsigned getNumSpilledSGPRs() const {
467 return NumSpilledSGPRs;
468 }
469
470 unsigned getNumSpilledVGPRs() const {
471 return NumSpilledVGPRs;
472 }
473
474 void addToSpilledSGPRs(unsigned num) {
475 NumSpilledSGPRs += num;
476 }
477
478 void addToSpilledVGPRs(unsigned num) {
479 NumSpilledVGPRs += num;
480 }
481
Marek Olsakfccabaf2016-01-13 11:45:36 +0000482 unsigned getPSInputAddr() const {
483 return PSInputAddr;
484 }
485
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000486 unsigned getPSInputEnable() const {
487 return PSInputEnable;
488 }
489
Marek Olsakfccabaf2016-01-13 11:45:36 +0000490 bool isPSInputAllocated(unsigned Index) const {
491 return PSInputAddr & (1 << Index);
492 }
493
494 void markPSInputAllocated(unsigned Index) {
495 PSInputAddr |= 1 << Index;
496 }
497
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000498 void markPSInputEnabled(unsigned Index) {
499 PSInputEnable |= 1 << Index;
500 }
501
Marek Olsak8e9cc632016-01-13 17:23:09 +0000502 bool returnsVoid() const {
503 return ReturnsVoid;
504 }
505
506 void setIfReturnsVoid(bool Value) {
507 ReturnsVoid = Value;
508 }
509
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000510 /// \returns A pair of default/requested minimum/maximum flat work group sizes
511 /// for this function.
512 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
513 return FlatWorkGroupSizes;
514 }
515
516 /// \returns Default/requested minimum flat work group size for this function.
517 unsigned getMinFlatWorkGroupSize() const {
518 return FlatWorkGroupSizes.first;
519 }
520
521 /// \returns Default/requested maximum flat work group size for this function.
522 unsigned getMaxFlatWorkGroupSize() const {
523 return FlatWorkGroupSizes.second;
524 }
525
526 /// \returns A pair of default/requested minimum/maximum number of waves per
527 /// execution unit.
528 std::pair<unsigned, unsigned> getWavesPerEU() const {
529 return WavesPerEU;
530 }
531
532 /// \returns Default/requested minimum number of waves per execution unit.
533 unsigned getMinWavesPerEU() const {
534 return WavesPerEU.first;
535 }
536
537 /// \returns Default/requested maximum number of waves per execution unit.
538 unsigned getMaxWavesPerEU() const {
539 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000540 }
541
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000542 /// \returns Stack object index for \p Dim's work group ID.
543 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
544 assert(Dim < 3);
545 return DebuggerWorkGroupIDStackObjectIndices[Dim];
546 }
547
548 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
549 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
550 assert(Dim < 3);
551 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
552 }
553
554 /// \returns Stack object index for \p Dim's work item ID.
555 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
556 assert(Dim < 3);
557 return DebuggerWorkItemIDStackObjectIndices[Dim];
558 }
559
560 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
561 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
562 assert(Dim < 3);
563 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
564 }
565
566 /// \returns SGPR used for \p Dim's work group ID.
567 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
568 switch (Dim) {
569 case 0:
570 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000571 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000572 case 1:
573 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000574 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000575 case 2:
576 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000577 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000578 }
579 llvm_unreachable("unexpected dimension");
580 }
581
582 /// \returns VGPR used for \p Dim' work item ID.
583 unsigned getWorkItemIDVGPR(unsigned Dim) const {
584 switch (Dim) {
585 case 0:
586 assert(hasWorkItemIDX());
587 return AMDGPU::VGPR0;
588 case 1:
589 assert(hasWorkItemIDY());
590 return AMDGPU::VGPR1;
591 case 2:
592 assert(hasWorkItemIDZ());
593 return AMDGPU::VGPR2;
594 }
595 llvm_unreachable("unexpected dimension");
596 }
Tom Stellard244891d2016-12-20 15:52:17 +0000597
Matt Arsenault161e2b42017-04-18 20:59:40 +0000598 unsigned getLDSWaveSpillSize() const {
599 return LDSWaveSpillSize;
600 }
601
Tom Stellard6f9ef142016-12-20 17:19:44 +0000602 const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
603 return &BufferPSV;
604 }
605
Tom Stellardbb138882016-12-20 17:26:34 +0000606 const AMDGPUImagePseudoSourceValue *getImagePSV() const {
607 return &ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000608 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000609};
610
Eugene Zelenko66203762017-01-21 00:53:49 +0000611} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000612
Eugene Zelenko66203762017-01-21 00:53:49 +0000613#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H