blob: 242b41a590852d85246573d1e4a2b3cfd7743c5e [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"
Jan Sjodin312ccf72017-09-14 20:53:51 +000025#include "llvm/Target/TargetInstrInfo.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000026#include "llvm/MC/MCRegisterInfo.h"
27#include "llvm/Support/ErrorHandling.h"
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000028#include <array>
Eugene Zelenko66203762017-01-21 00:53:49 +000029#include <cassert>
Eugene Zelenko66203762017-01-21 00:53:49 +000030#include <utility>
Eugene Zelenko59e12822017-08-08 00:47:13 +000031#include <vector>
Tom Stellard75aadc22012-12-11 21:25:42 +000032
33namespace llvm {
34
Eugene Zelenko59e12822017-08-08 00:47:13 +000035class MachineFrameInfo;
36class MachineFunction;
37class TargetRegisterClass;
38
Tom Stellard244891d2016-12-20 15:52:17 +000039class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
40public:
Jan Sjodin312ccf72017-09-14 20:53:51 +000041 explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII) :
42 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
Tom Stellard244891d2016-12-20 15:52:17 +000043
44 bool isConstant(const MachineFrameInfo *) const override {
45 // This should probably be true for most images, but we will start by being
46 // conservative.
47 return false;
48 }
49
50 bool isAliased(const MachineFrameInfo *) const override {
51 // FIXME: If we ever change image intrinsics to accept fat pointers, then
52 // this could be true for some cases.
53 return false;
54 }
55
Eugene Zelenko59e12822017-08-08 00:47:13 +000056 bool mayAlias(const MachineFrameInfo *) const override {
Tom Stellard244891d2016-12-20 15:52:17 +000057 // FIXME: If we ever change image intrinsics to accept fat pointers, then
58 // this could be true for some cases.
59 return false;
60 }
61};
62
Tom Stellard6f9ef142016-12-20 17:19:44 +000063class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
64public:
Jan Sjodin312ccf72017-09-14 20:53:51 +000065 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) :
66 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
Tom Stellard6f9ef142016-12-20 17:19:44 +000067
68 bool isConstant(const MachineFrameInfo *) const override {
69 // This should probably be true for most images, but we will start by being
70 // conservative.
71 return false;
72 }
73
74 bool isAliased(const MachineFrameInfo *) const override {
75 // FIXME: If we ever change image intrinsics to accept fat pointers, then
76 // this could be true for some cases.
77 return false;
78 }
79
Eugene Zelenko59e12822017-08-08 00:47:13 +000080 bool mayAlias(const MachineFrameInfo *) const override {
Tom Stellard6f9ef142016-12-20 17:19:44 +000081 // FIXME: If we ever change image intrinsics to accept fat pointers, then
82 // this could be true for some cases.
83 return false;
84 }
85};
Tom Stellard244891d2016-12-20 15:52:17 +000086
Tom Stellard75aadc22012-12-11 21:25:42 +000087/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
88/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000089class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000090 // FIXME: This should be removed and getPreloadedValue moved here.
Saleem Abdulrasool43e5fe32016-08-29 20:42:07 +000091 friend class SIRegisterInfo;
Tom Stellard96468902014-09-24 01:33:17 +000092
Eugene Zelenko59e12822017-08-08 00:47:13 +000093 unsigned TIDReg = AMDGPU::NoRegister;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000094
95 // Registers that may be reserved for spilling purposes. These may be the same
96 // as the input registers.
Eugene Zelenko59e12822017-08-08 00:47:13 +000097 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
98 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000099
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000100 // This is the current function's incremented size from the kernel's scratch
101 // wave offset register. For an entry function, this is exactly the same as
102 // the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000103 unsigned FrameOffsetReg = AMDGPU::FP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000104
105 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000106 unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000107
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000108 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000109
Marek Olsakfccabaf2016-01-13 11:45:36 +0000110 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000111 unsigned PSInputAddr = 0;
112 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000113
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000114 /// Number of bytes of arguments this function has on the stack. If the callee
115 /// is expected to restore the argument stack this should be a multiple of 16,
116 /// all usable during a tail call.
117 ///
118 /// The alternative would forbid tail call optimisation in some cases: if we
119 /// want to transfer control from a function with 8-bytes of stack-argument
120 /// space to a function with 16-bytes then misalignment of this value would
121 /// make a stack adjustment necessary, which could not be undone by the
122 /// callee.
123 unsigned BytesInStackArgArea = 0;
124
Eugene Zelenko59e12822017-08-08 00:47:13 +0000125 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000126
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000127 // A pair of default/requested minimum/maximum flat work group sizes.
128 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000129 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000130
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000131 // A pair of default/requested minimum/maximum number of waves per execution
132 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000133 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000134
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000135 // Stack object indices for work group IDs.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000136 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices = {{0, 0, 0}};
137
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000138 // Stack object indices for work item IDs.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000139 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices = {{0, 0, 0}};
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000140
Tom Stellard6f9ef142016-12-20 17:19:44 +0000141 AMDGPUBufferPseudoSourceValue BufferPSV;
Tom Stellardbb138882016-12-20 17:26:34 +0000142 AMDGPUImagePseudoSourceValue ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000143
Matt Arsenault161e2b42017-04-18 20:59:40 +0000144private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000145 unsigned LDSWaveSpillSize = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000146 unsigned ScratchOffsetReg;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000147 unsigned NumUserSGPRs = 0;
148 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000149
Eugene Zelenko59e12822017-08-08 00:47:13 +0000150 bool HasSpilledSGPRs = false;
151 bool HasSpilledVGPRs = false;
152 bool HasNonSpillStackObjects = false;
Tom Stellard96468902014-09-24 01:33:17 +0000153
Eugene Zelenko59e12822017-08-08 00:47:13 +0000154 unsigned NumSpilledSGPRs = 0;
155 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000156
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000157 // Feature bits required for inputs passed in user SGPRs.
158 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000159 bool DispatchPtr : 1;
160 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000161 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000162 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000163 bool FlatScratchInit : 1;
164 bool GridWorkgroupCountX : 1;
165 bool GridWorkgroupCountY : 1;
166 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000167
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000168 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000169 bool WorkGroupIDX : 1; // Always initialized.
170 bool WorkGroupIDY : 1;
171 bool WorkGroupIDZ : 1;
172 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000173 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000174
175 bool WorkItemIDX : 1; // Always initialized.
176 bool WorkItemIDY : 1;
177 bool WorkItemIDZ : 1;
178
Tom Stellard2f3f9852017-01-25 01:25:13 +0000179 // Private memory buffer
180 // Compute directly in sgpr[0:1]
181 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000182 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000183
Matt Arsenault9166ce82017-07-28 15:52:08 +0000184 // Pointer to where the ABI inserts special kernel arguments separate from the
185 // user arguments. This is an offset from the KernargSegmentPtr.
186 bool ImplicitArgPtr : 1;
187
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000188 MCPhysReg getNextUserSGPR() const {
189 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
190 return AMDGPU::SGPR0 + NumUserSGPRs;
191 }
192
193 MCPhysReg getNextSystemSGPR() const {
194 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
195 }
196
Matt Arsenault49affb82015-11-25 20:55:12 +0000197public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000198 struct SpilledReg {
Eugene Zelenko66203762017-01-21 00:53:49 +0000199 unsigned VGPR = AMDGPU::NoRegister;
200 int Lane = -1;
201
202 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000203 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000204
Tom Stellardc149dc02013-11-27 21:23:35 +0000205 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000206 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000207 };
208
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000209 struct SGPRSpillVGPRCSR {
210 // VGPR used for SGPR spills
211 unsigned VGPR;
212
213 // If the VGPR is a CSR, the stack slot used to save/restore it in the
214 // prolog/epilog.
215 Optional<int> FI;
216
Eugene Zelenko59e12822017-08-08 00:47:13 +0000217 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000218 };
219
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000220private:
221 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000222 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000223
224 // Track VGPR + wave index for each subregister of the SGPR spilled to
225 // frameindex key.
226 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
227 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000228 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000229
230public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000231 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000232
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000233 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
234 auto I = SGPRToVGPRSpills.find(FrameIndex);
235 return (I == SGPRToVGPRSpills.end()) ?
236 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
237 }
238
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000239 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
240 return SpillVGPRs;
241 }
242
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000243 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
244 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
245
Eugene Zelenko59e12822017-08-08 00:47:13 +0000246 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; }
247 unsigned getTIDReg() const { return TIDReg; }
Tom Stellard96468902014-09-24 01:33:17 +0000248 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000249
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000250 unsigned getBytesInStackArgArea() const {
251 return BytesInStackArgArea;
252 }
253
254 void setBytesInStackArgArea(unsigned Bytes) {
255 BytesInStackArgArea = Bytes;
256 }
257
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000258 // Add user SGPRs.
259 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
260 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
261 unsigned addQueuePtr(const SIRegisterInfo &TRI);
262 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000263 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000264 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000265 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000266
267 // Add system SGPRs.
268 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000269 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000270 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000271 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000272 }
273
274 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000275 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000276 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000277 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000278 }
279
280 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000281 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000282 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000283 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000284 }
285
286 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000287 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000288 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000289 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000290 }
291
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000292 // Add special VGPR inputs
293 void setWorkItemIDX(ArgDescriptor Arg) {
294 ArgInfo.WorkItemIDX = Arg;
295 }
296
297 void setWorkItemIDY(ArgDescriptor Arg) {
298 ArgInfo.WorkItemIDY = Arg;
299 }
300
301 void setWorkItemIDZ(ArgDescriptor Arg) {
302 ArgInfo.WorkItemIDZ = Arg;
303 }
304
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000305 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000306 ArgInfo.PrivateSegmentWaveByteOffset
307 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000308 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000309 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000310 }
311
Tom Stellardf110f8f2016-04-14 16:27:03 +0000312 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000313 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000314 }
315
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000316 bool hasPrivateSegmentBuffer() const {
317 return PrivateSegmentBuffer;
318 }
319
Matt Arsenault49affb82015-11-25 20:55:12 +0000320 bool hasDispatchPtr() const {
321 return DispatchPtr;
322 }
323
324 bool hasQueuePtr() const {
325 return QueuePtr;
326 }
327
Matt Arsenault49affb82015-11-25 20:55:12 +0000328 bool hasKernargSegmentPtr() const {
329 return KernargSegmentPtr;
330 }
331
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000332 bool hasDispatchID() const {
333 return DispatchID;
334 }
335
Matt Arsenault49affb82015-11-25 20:55:12 +0000336 bool hasFlatScratchInit() const {
337 return FlatScratchInit;
338 }
339
340 bool hasGridWorkgroupCountX() const {
341 return GridWorkgroupCountX;
342 }
343
344 bool hasGridWorkgroupCountY() const {
345 return GridWorkgroupCountY;
346 }
347
348 bool hasGridWorkgroupCountZ() const {
349 return GridWorkgroupCountZ;
350 }
351
352 bool hasWorkGroupIDX() const {
353 return WorkGroupIDX;
354 }
355
356 bool hasWorkGroupIDY() const {
357 return WorkGroupIDY;
358 }
359
360 bool hasWorkGroupIDZ() const {
361 return WorkGroupIDZ;
362 }
363
364 bool hasWorkGroupInfo() const {
365 return WorkGroupInfo;
366 }
367
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000368 bool hasPrivateSegmentWaveByteOffset() const {
369 return PrivateSegmentWaveByteOffset;
370 }
371
Matt Arsenault49affb82015-11-25 20:55:12 +0000372 bool hasWorkItemIDX() const {
373 return WorkItemIDX;
374 }
375
376 bool hasWorkItemIDY() const {
377 return WorkItemIDY;
378 }
379
380 bool hasWorkItemIDZ() const {
381 return WorkItemIDZ;
382 }
383
Matt Arsenault9166ce82017-07-28 15:52:08 +0000384 bool hasImplicitArgPtr() const {
385 return ImplicitArgPtr;
386 }
387
Matt Arsenault10fc0622017-06-26 03:01:31 +0000388 bool hasImplicitBufferPtr() const {
389 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000390 }
391
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000392 AMDGPUFunctionArgInfo &getArgInfo() {
393 return ArgInfo;
394 }
395
396 const AMDGPUFunctionArgInfo &getArgInfo() const {
397 return ArgInfo;
398 }
399
400 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
401 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
402 return ArgInfo.getPreloadedValue(Value);
403 }
404
405 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
406 return ArgInfo.getPreloadedValue(Value).first->getRegister();
407 }
408
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000409 unsigned getNumUserSGPRs() const {
410 return NumUserSGPRs;
411 }
412
413 unsigned getNumPreloadedSGPRs() const {
414 return NumUserSGPRs + NumSystemSGPRs;
415 }
416
417 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000418 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000419 }
420
Matt Arsenault49affb82015-11-25 20:55:12 +0000421 /// \brief Returns the physical register reserved for use as the resource
422 /// descriptor for scratch accesses.
423 unsigned getScratchRSrcReg() const {
424 return ScratchRSrcReg;
425 }
426
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000427 void setScratchRSrcReg(unsigned Reg) {
428 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
429 ScratchRSrcReg = Reg;
430 }
431
432 unsigned getScratchWaveOffsetReg() const {
433 return ScratchWaveOffsetReg;
434 }
435
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000436 unsigned getFrameOffsetReg() const {
437 return FrameOffsetReg;
438 }
439
440 void setStackPtrOffsetReg(unsigned Reg) {
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000441 StackPtrOffsetReg = Reg;
442 }
443
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000444 // Note the unset value for this is AMDGPU::SP_REG rather than
445 // NoRegister. This is mostly a workaround for MIR tests where state that
446 // can't be directly computed from the function is not preserved in serialized
447 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000448 unsigned getStackPtrOffsetReg() const {
449 return StackPtrOffsetReg;
450 }
451
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000452 void setScratchWaveOffsetReg(unsigned Reg) {
453 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
454 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000455 if (isEntryFunction())
456 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000457 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000458
Matt Arsenault99c14522016-04-25 19:27:24 +0000459 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000460 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000461 }
462
Matt Arsenault10fc0622017-06-26 03:01:31 +0000463 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000464 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000465 }
466
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000467 bool hasSpilledSGPRs() const {
468 return HasSpilledSGPRs;
469 }
470
471 void setHasSpilledSGPRs(bool Spill = true) {
472 HasSpilledSGPRs = Spill;
473 }
474
475 bool hasSpilledVGPRs() const {
476 return HasSpilledVGPRs;
477 }
478
479 void setHasSpilledVGPRs(bool Spill = true) {
480 HasSpilledVGPRs = Spill;
481 }
Tom Stellard96468902014-09-24 01:33:17 +0000482
Matt Arsenault296b8492016-02-12 06:31:30 +0000483 bool hasNonSpillStackObjects() const {
484 return HasNonSpillStackObjects;
485 }
486
487 void setHasNonSpillStackObjects(bool StackObject = true) {
488 HasNonSpillStackObjects = StackObject;
489 }
490
Marek Olsak0532c192016-07-13 17:35:15 +0000491 unsigned getNumSpilledSGPRs() const {
492 return NumSpilledSGPRs;
493 }
494
495 unsigned getNumSpilledVGPRs() const {
496 return NumSpilledVGPRs;
497 }
498
499 void addToSpilledSGPRs(unsigned num) {
500 NumSpilledSGPRs += num;
501 }
502
503 void addToSpilledVGPRs(unsigned num) {
504 NumSpilledVGPRs += num;
505 }
506
Marek Olsakfccabaf2016-01-13 11:45:36 +0000507 unsigned getPSInputAddr() const {
508 return PSInputAddr;
509 }
510
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000511 unsigned getPSInputEnable() const {
512 return PSInputEnable;
513 }
514
Marek Olsakfccabaf2016-01-13 11:45:36 +0000515 bool isPSInputAllocated(unsigned Index) const {
516 return PSInputAddr & (1 << Index);
517 }
518
519 void markPSInputAllocated(unsigned Index) {
520 PSInputAddr |= 1 << Index;
521 }
522
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000523 void markPSInputEnabled(unsigned Index) {
524 PSInputEnable |= 1 << Index;
525 }
526
Marek Olsak8e9cc632016-01-13 17:23:09 +0000527 bool returnsVoid() const {
528 return ReturnsVoid;
529 }
530
531 void setIfReturnsVoid(bool Value) {
532 ReturnsVoid = Value;
533 }
534
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000535 /// \returns A pair of default/requested minimum/maximum flat work group sizes
536 /// for this function.
537 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
538 return FlatWorkGroupSizes;
539 }
540
541 /// \returns Default/requested minimum flat work group size for this function.
542 unsigned getMinFlatWorkGroupSize() const {
543 return FlatWorkGroupSizes.first;
544 }
545
546 /// \returns Default/requested maximum flat work group size for this function.
547 unsigned getMaxFlatWorkGroupSize() const {
548 return FlatWorkGroupSizes.second;
549 }
550
551 /// \returns A pair of default/requested minimum/maximum number of waves per
552 /// execution unit.
553 std::pair<unsigned, unsigned> getWavesPerEU() const {
554 return WavesPerEU;
555 }
556
557 /// \returns Default/requested minimum number of waves per execution unit.
558 unsigned getMinWavesPerEU() const {
559 return WavesPerEU.first;
560 }
561
562 /// \returns Default/requested maximum number of waves per execution unit.
563 unsigned getMaxWavesPerEU() const {
564 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000565 }
566
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000567 /// \returns Stack object index for \p Dim's work group ID.
568 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
569 assert(Dim < 3);
570 return DebuggerWorkGroupIDStackObjectIndices[Dim];
571 }
572
573 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
574 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
575 assert(Dim < 3);
576 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
577 }
578
579 /// \returns Stack object index for \p Dim's work item ID.
580 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
581 assert(Dim < 3);
582 return DebuggerWorkItemIDStackObjectIndices[Dim];
583 }
584
585 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
586 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
587 assert(Dim < 3);
588 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
589 }
590
591 /// \returns SGPR used for \p Dim's work group ID.
592 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
593 switch (Dim) {
594 case 0:
595 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000596 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000597 case 1:
598 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000599 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000600 case 2:
601 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000602 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000603 }
604 llvm_unreachable("unexpected dimension");
605 }
606
607 /// \returns VGPR used for \p Dim' work item ID.
608 unsigned getWorkItemIDVGPR(unsigned Dim) const {
609 switch (Dim) {
610 case 0:
611 assert(hasWorkItemIDX());
612 return AMDGPU::VGPR0;
613 case 1:
614 assert(hasWorkItemIDY());
615 return AMDGPU::VGPR1;
616 case 2:
617 assert(hasWorkItemIDZ());
618 return AMDGPU::VGPR2;
619 }
620 llvm_unreachable("unexpected dimension");
621 }
Tom Stellard244891d2016-12-20 15:52:17 +0000622
Matt Arsenault161e2b42017-04-18 20:59:40 +0000623 unsigned getLDSWaveSpillSize() const {
624 return LDSWaveSpillSize;
625 }
626
Tom Stellard6f9ef142016-12-20 17:19:44 +0000627 const AMDGPUBufferPseudoSourceValue *getBufferPSV() const {
628 return &BufferPSV;
629 }
630
Tom Stellardbb138882016-12-20 17:26:34 +0000631 const AMDGPUImagePseudoSourceValue *getImagePSV() const {
632 return &ImagePSV;
Tom Stellard244891d2016-12-20 15:52:17 +0000633 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000634};
635
Eugene Zelenko66203762017-01-21 00:53:49 +0000636} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000637
Eugene Zelenko66203762017-01-21 00:53:49 +0000638#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H