blob: 25139b2d373d3080d06b44898116b79bfac2cb74 [file] [log] [blame]
Eugene Zelenko59e12822017-08-08 00:47:13 +00001//==- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface --*- C++ -*-==//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
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 Arsenault8623e8d2017-08-03 23:00:29 +000018#include "AMDGPUArgumentUsageInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000019#include "SIRegisterInfo.h"
Eugene Zelenko59e12822017-08-08 00:47:13 +000020#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/Optional.h"
23#include "llvm/ADT/SmallVector.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000024#include "llvm/CodeGen/PseudoSourceValue.h"
25#include "llvm/MC/MCRegisterInfo.h"
26#include "llvm/Support/ErrorHandling.h"
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000027#include <array>
Eugene Zelenko66203762017-01-21 00:53:49 +000028#include <cassert>
Eugene Zelenko66203762017-01-21 00:53:49 +000029#include <utility>
Eugene Zelenko59e12822017-08-08 00:47:13 +000030#include <vector>
Tom Stellard75aadc22012-12-11 21:25:42 +000031
32namespace llvm {
33
Eugene Zelenko59e12822017-08-08 00:47:13 +000034class MachineFrameInfo;
35class MachineFunction;
36class TargetRegisterClass;
37
Tom Stellard244891d2016-12-20 15:52:17 +000038class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
39public:
40 explicit AMDGPUImagePseudoSourceValue() :
Eugene Zelenko59e12822017-08-08 00:47:13 +000041 PseudoSourceValue(PseudoSourceValue::TargetCustom) {}
Tom Stellard244891d2016-12-20 15:52:17 +000042
43 bool isConstant(const MachineFrameInfo *) const override {
44 // This should probably be true for most images, but we will start by being
45 // conservative.
46 return false;
47 }
48
49 bool isAliased(const MachineFrameInfo *) const override {
50 // FIXME: If we ever change image intrinsics to accept fat pointers, then
51 // this could be true for some cases.
52 return false;
53 }
54
Eugene Zelenko59e12822017-08-08 00:47:13 +000055 bool mayAlias(const MachineFrameInfo *) const override {
Tom Stellard244891d2016-12-20 15:52:17 +000056 // FIXME: If we ever change image intrinsics to accept fat pointers, then
57 // this could be true for some cases.
58 return false;
59 }
60};
61
Tom Stellard6f9ef142016-12-20 17:19:44 +000062class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
63public:
64 explicit AMDGPUBufferPseudoSourceValue() :
Eugene Zelenko59e12822017-08-08 00:47:13 +000065 PseudoSourceValue(PseudoSourceValue::TargetCustom) {}
Tom Stellard6f9ef142016-12-20 17:19:44 +000066
67 bool isConstant(const MachineFrameInfo *) const override {
68 // This should probably be true for most images, but we will start by being
69 // conservative.
70 return false;
71 }
72
73 bool isAliased(const MachineFrameInfo *) const override {
74 // FIXME: If we ever change image intrinsics to accept fat pointers, then
75 // this could be true for some cases.
76 return false;
77 }
78
Eugene Zelenko59e12822017-08-08 00:47:13 +000079 bool mayAlias(const MachineFrameInfo *) const override {
Tom Stellard6f9ef142016-12-20 17:19:44 +000080 // FIXME: If we ever change image intrinsics to accept fat pointers, then
81 // this could be true for some cases.
82 return false;
83 }
84};
Tom Stellard244891d2016-12-20 15:52:17 +000085
Tom Stellard75aadc22012-12-11 21:25:42 +000086/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
87/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000088class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000089 // FIXME: This should be removed and getPreloadedValue moved here.
Saleem Abdulrasool43e5fe32016-08-29 20:42:07 +000090 friend class SIRegisterInfo;
Tom Stellard96468902014-09-24 01:33:17 +000091
Eugene Zelenko59e12822017-08-08 00:47:13 +000092 unsigned TIDReg = AMDGPU::NoRegister;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000093
94 // Registers that may be reserved for spilling purposes. These may be the same
95 // as the input registers.
Eugene Zelenko59e12822017-08-08 00:47:13 +000096 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
97 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000098
Matt Arsenault1c0ae392017-04-24 18:05:16 +000099 // This is the current function's incremented size from the kernel's scratch
100 // wave offset register. For an entry function, this is exactly the same as
101 // the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000102 unsigned FrameOffsetReg = AMDGPU::FP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000103
104 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000105 unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000106
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000107 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000108
Marek Olsakfccabaf2016-01-13 11:45:36 +0000109 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000110 unsigned PSInputAddr = 0;
111 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000112
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000113 /// Number of bytes of arguments this function has on the stack. If the callee
114 /// is expected to restore the argument stack this should be a multiple of 16,
115 /// all usable during a tail call.
116 ///
117 /// The alternative would forbid tail call optimisation in some cases: if we
118 /// want to transfer control from a function with 8-bytes of stack-argument
119 /// space to a function with 16-bytes then misalignment of this value would
120 /// make a stack adjustment necessary, which could not be undone by the
121 /// callee.
122 unsigned BytesInStackArgArea = 0;
123
Eugene Zelenko59e12822017-08-08 00:47:13 +0000124 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000125
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000126 // A pair of default/requested minimum/maximum flat work group sizes.
127 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000128 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000129
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000130 // A pair of default/requested minimum/maximum number of waves per execution
131 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000132 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000133
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000134 // Stack object indices for work group IDs.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000135 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices = {{0, 0, 0}};
136
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000137 // Stack object indices for work item IDs.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000138 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices = {{0, 0, 0}};
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000139
Tom Stellard6f9ef142016-12-20 17:19:44 +0000140 AMDGPUBufferPseudoSourceValue BufferPSV;
Tom Stellardbb138882016-12-20 17:26:34 +0000141 AMDGPUImagePseudoSourceValue ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000142
Matt Arsenault161e2b42017-04-18 20:59:40 +0000143private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000144 unsigned LDSWaveSpillSize = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000145 unsigned ScratchOffsetReg;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000146 unsigned NumUserSGPRs = 0;
147 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000148
Eugene Zelenko59e12822017-08-08 00:47:13 +0000149 bool HasSpilledSGPRs = false;
150 bool HasSpilledVGPRs = false;
151 bool HasNonSpillStackObjects = false;
Tom Stellard96468902014-09-24 01:33:17 +0000152
Eugene Zelenko59e12822017-08-08 00:47:13 +0000153 unsigned NumSpilledSGPRs = 0;
154 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000155
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000156 // Feature bits required for inputs passed in user SGPRs.
157 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000158 bool DispatchPtr : 1;
159 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000160 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000161 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000162 bool FlatScratchInit : 1;
163 bool GridWorkgroupCountX : 1;
164 bool GridWorkgroupCountY : 1;
165 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000166
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000167 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000168 bool WorkGroupIDX : 1; // Always initialized.
169 bool WorkGroupIDY : 1;
170 bool WorkGroupIDZ : 1;
171 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000172 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000173
174 bool WorkItemIDX : 1; // Always initialized.
175 bool WorkItemIDY : 1;
176 bool WorkItemIDZ : 1;
177
Tom Stellard2f3f9852017-01-25 01:25:13 +0000178 // Private memory buffer
179 // Compute directly in sgpr[0:1]
180 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000181 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000182
Matt Arsenault9166ce82017-07-28 15:52:08 +0000183 // Pointer to where the ABI inserts special kernel arguments separate from the
184 // user arguments. This is an offset from the KernargSegmentPtr.
185 bool ImplicitArgPtr : 1;
186
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000187 MCPhysReg getNextUserSGPR() const {
188 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
189 return AMDGPU::SGPR0 + NumUserSGPRs;
190 }
191
192 MCPhysReg getNextSystemSGPR() const {
193 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
194 }
195
Matt Arsenault49affb82015-11-25 20:55:12 +0000196public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000197 struct SpilledReg {
Eugene Zelenko66203762017-01-21 00:53:49 +0000198 unsigned VGPR = AMDGPU::NoRegister;
199 int Lane = -1;
200
201 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000202 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000203
Tom Stellardc149dc02013-11-27 21:23:35 +0000204 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000205 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000206 };
207
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000208 struct SGPRSpillVGPRCSR {
209 // VGPR used for SGPR spills
210 unsigned VGPR;
211
212 // If the VGPR is a CSR, the stack slot used to save/restore it in the
213 // prolog/epilog.
214 Optional<int> FI;
215
Eugene Zelenko59e12822017-08-08 00:47:13 +0000216 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000217 };
218
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000219private:
220 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000221 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000222
223 // Track VGPR + wave index for each subregister of the SGPR spilled to
224 // frameindex key.
225 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
226 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000227 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000228
229public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000230 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000231
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000232 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
233 auto I = SGPRToVGPRSpills.find(FrameIndex);
234 return (I == SGPRToVGPRSpills.end()) ?
235 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
236 }
237
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000238 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
239 return SpillVGPRs;
240 }
241
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000242 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
243 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
244
Eugene Zelenko59e12822017-08-08 00:47:13 +0000245 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; }
246 unsigned getTIDReg() const { return TIDReg; }
Tom Stellard96468902014-09-24 01:33:17 +0000247 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000248
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000249 unsigned getBytesInStackArgArea() const {
250 return BytesInStackArgArea;
251 }
252
253 void setBytesInStackArgArea(unsigned Bytes) {
254 BytesInStackArgArea = Bytes;
255 }
256
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000257 // Add user SGPRs.
258 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
259 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
260 unsigned addQueuePtr(const SIRegisterInfo &TRI);
261 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000262 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000263 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000264 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000265
266 // Add system SGPRs.
267 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000268 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000269 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000270 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000271 }
272
273 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000274 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000275 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000276 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000277 }
278
279 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000280 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000281 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000282 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000283 }
284
285 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000286 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000287 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000288 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000289 }
290
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000291 // Add special VGPR inputs
292 void setWorkItemIDX(ArgDescriptor Arg) {
293 ArgInfo.WorkItemIDX = Arg;
294 }
295
296 void setWorkItemIDY(ArgDescriptor Arg) {
297 ArgInfo.WorkItemIDY = Arg;
298 }
299
300 void setWorkItemIDZ(ArgDescriptor Arg) {
301 ArgInfo.WorkItemIDZ = Arg;
302 }
303
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000304 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000305 ArgInfo.PrivateSegmentWaveByteOffset
306 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000307 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000308 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000309 }
310
Tom Stellardf110f8f2016-04-14 16:27:03 +0000311 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000312 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000313 }
314
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000315 bool hasPrivateSegmentBuffer() const {
316 return PrivateSegmentBuffer;
317 }
318
Matt Arsenault49affb82015-11-25 20:55:12 +0000319 bool hasDispatchPtr() const {
320 return DispatchPtr;
321 }
322
323 bool hasQueuePtr() const {
324 return QueuePtr;
325 }
326
Matt Arsenault49affb82015-11-25 20:55:12 +0000327 bool hasKernargSegmentPtr() const {
328 return KernargSegmentPtr;
329 }
330
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000331 bool hasDispatchID() const {
332 return DispatchID;
333 }
334
Matt Arsenault49affb82015-11-25 20:55:12 +0000335 bool hasFlatScratchInit() const {
336 return FlatScratchInit;
337 }
338
339 bool hasGridWorkgroupCountX() const {
340 return GridWorkgroupCountX;
341 }
342
343 bool hasGridWorkgroupCountY() const {
344 return GridWorkgroupCountY;
345 }
346
347 bool hasGridWorkgroupCountZ() const {
348 return GridWorkgroupCountZ;
349 }
350
351 bool hasWorkGroupIDX() const {
352 return WorkGroupIDX;
353 }
354
355 bool hasWorkGroupIDY() const {
356 return WorkGroupIDY;
357 }
358
359 bool hasWorkGroupIDZ() const {
360 return WorkGroupIDZ;
361 }
362
363 bool hasWorkGroupInfo() const {
364 return WorkGroupInfo;
365 }
366
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000367 bool hasPrivateSegmentWaveByteOffset() const {
368 return PrivateSegmentWaveByteOffset;
369 }
370
Matt Arsenault49affb82015-11-25 20:55:12 +0000371 bool hasWorkItemIDX() const {
372 return WorkItemIDX;
373 }
374
375 bool hasWorkItemIDY() const {
376 return WorkItemIDY;
377 }
378
379 bool hasWorkItemIDZ() const {
380 return WorkItemIDZ;
381 }
382
Matt Arsenault9166ce82017-07-28 15:52:08 +0000383 bool hasImplicitArgPtr() const {
384 return ImplicitArgPtr;
385 }
386
Matt Arsenault10fc0622017-06-26 03:01:31 +0000387 bool hasImplicitBufferPtr() const {
388 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000389 }
390
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000391 AMDGPUFunctionArgInfo &getArgInfo() {
392 return ArgInfo;
393 }
394
395 const AMDGPUFunctionArgInfo &getArgInfo() const {
396 return ArgInfo;
397 }
398
399 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
400 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
401 return ArgInfo.getPreloadedValue(Value);
402 }
403
404 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
405 return ArgInfo.getPreloadedValue(Value).first->getRegister();
406 }
407
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000408 unsigned getNumUserSGPRs() const {
409 return NumUserSGPRs;
410 }
411
412 unsigned getNumPreloadedSGPRs() const {
413 return NumUserSGPRs + NumSystemSGPRs;
414 }
415
416 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000417 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000418 }
419
Matt Arsenault49affb82015-11-25 20:55:12 +0000420 /// \brief Returns the physical register reserved for use as the resource
421 /// descriptor for scratch accesses.
422 unsigned getScratchRSrcReg() const {
423 return ScratchRSrcReg;
424 }
425
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000426 void setScratchRSrcReg(unsigned Reg) {
427 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
428 ScratchRSrcReg = Reg;
429 }
430
431 unsigned getScratchWaveOffsetReg() const {
432 return ScratchWaveOffsetReg;
433 }
434
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000435 unsigned getFrameOffsetReg() const {
436 return FrameOffsetReg;
437 }
438
439 void setStackPtrOffsetReg(unsigned Reg) {
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000440 StackPtrOffsetReg = Reg;
441 }
442
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000443 // Note the unset value for this is AMDGPU::SP_REG rather than
444 // NoRegister. This is mostly a workaround for MIR tests where state that
445 // can't be directly computed from the function is not preserved in serialized
446 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000447 unsigned getStackPtrOffsetReg() const {
448 return StackPtrOffsetReg;
449 }
450
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000451 void setScratchWaveOffsetReg(unsigned Reg) {
452 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
453 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000454 if (isEntryFunction())
455 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000456 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000457
Matt Arsenault99c14522016-04-25 19:27:24 +0000458 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000459 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000460 }
461
Matt Arsenault10fc0622017-06-26 03:01:31 +0000462 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000463 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000464 }
465
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000466 bool hasSpilledSGPRs() const {
467 return HasSpilledSGPRs;
468 }
469
470 void setHasSpilledSGPRs(bool Spill = true) {
471 HasSpilledSGPRs = Spill;
472 }
473
474 bool hasSpilledVGPRs() const {
475 return HasSpilledVGPRs;
476 }
477
478 void setHasSpilledVGPRs(bool Spill = true) {
479 HasSpilledVGPRs = Spill;
480 }
Tom Stellard96468902014-09-24 01:33:17 +0000481
Matt Arsenault296b8492016-02-12 06:31:30 +0000482 bool hasNonSpillStackObjects() const {
483 return HasNonSpillStackObjects;
484 }
485
486 void setHasNonSpillStackObjects(bool StackObject = true) {
487 HasNonSpillStackObjects = StackObject;
488 }
489
Marek Olsak0532c192016-07-13 17:35:15 +0000490 unsigned getNumSpilledSGPRs() const {
491 return NumSpilledSGPRs;
492 }
493
494 unsigned getNumSpilledVGPRs() const {
495 return NumSpilledVGPRs;
496 }
497
498 void addToSpilledSGPRs(unsigned num) {
499 NumSpilledSGPRs += num;
500 }
501
502 void addToSpilledVGPRs(unsigned num) {
503 NumSpilledVGPRs += num;
504 }
505
Marek Olsakfccabaf2016-01-13 11:45:36 +0000506 unsigned getPSInputAddr() const {
507 return PSInputAddr;
508 }
509
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000510 unsigned getPSInputEnable() const {
511 return PSInputEnable;
512 }
513
Marek Olsakfccabaf2016-01-13 11:45:36 +0000514 bool isPSInputAllocated(unsigned Index) const {
515 return PSInputAddr & (1 << Index);
516 }
517
518 void markPSInputAllocated(unsigned Index) {
519 PSInputAddr |= 1 << Index;
520 }
521
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000522 void markPSInputEnabled(unsigned Index) {
523 PSInputEnable |= 1 << Index;
524 }
525
Marek Olsak8e9cc632016-01-13 17:23:09 +0000526 bool returnsVoid() const {
527 return ReturnsVoid;
528 }
529
530 void setIfReturnsVoid(bool Value) {
531 ReturnsVoid = Value;
532 }
533
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000534 /// \returns A pair of default/requested minimum/maximum flat work group sizes
535 /// for this function.
536 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
537 return FlatWorkGroupSizes;
538 }
539
540 /// \returns Default/requested minimum flat work group size for this function.
541 unsigned getMinFlatWorkGroupSize() const {
542 return FlatWorkGroupSizes.first;
543 }
544
545 /// \returns Default/requested maximum flat work group size for this function.
546 unsigned getMaxFlatWorkGroupSize() const {
547 return FlatWorkGroupSizes.second;
548 }
549
550 /// \returns A pair of default/requested minimum/maximum number of waves per
551 /// execution unit.
552 std::pair<unsigned, unsigned> getWavesPerEU() const {
553 return WavesPerEU;
554 }
555
556 /// \returns Default/requested minimum number of waves per execution unit.
557 unsigned getMinWavesPerEU() const {
558 return WavesPerEU.first;
559 }
560
561 /// \returns Default/requested maximum number of waves per execution unit.
562 unsigned getMaxWavesPerEU() const {
563 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000564 }
565
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000566 /// \returns Stack object index for \p Dim's work group ID.
567 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
568 assert(Dim < 3);
569 return DebuggerWorkGroupIDStackObjectIndices[Dim];
570 }
571
572 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
573 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
574 assert(Dim < 3);
575 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
576 }
577
578 /// \returns Stack object index for \p Dim's work item ID.
579 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
580 assert(Dim < 3);
581 return DebuggerWorkItemIDStackObjectIndices[Dim];
582 }
583
584 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
585 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
586 assert(Dim < 3);
587 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
588 }
589
590 /// \returns SGPR used for \p Dim's work group ID.
591 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
592 switch (Dim) {
593 case 0:
594 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000595 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000596 case 1:
597 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000598 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000599 case 2:
600 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000601 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000602 }
603 llvm_unreachable("unexpected dimension");
604 }
605
606 /// \returns VGPR used for \p Dim' work item ID.
607 unsigned getWorkItemIDVGPR(unsigned Dim) const {
608 switch (Dim) {
609 case 0:
610 assert(hasWorkItemIDX());
611 return AMDGPU::VGPR0;
612 case 1:
613 assert(hasWorkItemIDY());
614 return AMDGPU::VGPR1;
615 case 2:
616 assert(hasWorkItemIDZ());
617 return AMDGPU::VGPR2;
618 }
619 llvm_unreachable("unexpected dimension");
620 }
Tom Stellard244891d2016-12-20 15:52:17 +0000621
Matt Arsenault161e2b42017-04-18 20:59:40 +0000622 unsigned getLDSWaveSpillSize() const {
623 return LDSWaveSpillSize;
624 }
625
Tom Stellard6f9ef142016-12-20 17:19:44 +0000626 const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
627 return &BufferPSV;
628 }
629
Tom Stellardbb138882016-12-20 17:26:34 +0000630 const AMDGPUImagePseudoSourceValue *getImagePSV() const {
631 return &ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000632 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000633};
634
Eugene Zelenko66203762017-01-21 00:53:49 +0000635} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000636
Eugene Zelenko66203762017-01-21 00:53:49 +0000637#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H