blob: 02e63f0258e6562293ec54410914b4775a2c6fe8 [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
Matt Arsenault8623e8d2017-08-03 23:00:29 +000017#include "AMDGPUArgumentUsageInfo.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000018#include "AMDGPUMachineFunction.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"
David Blaikie3f833ed2017-11-08 01:01:31 +000025#include "llvm/CodeGen/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;
Matt Arsenault905f3512017-12-29 17:18:14 +000037class SIInstrInfo;
Eugene Zelenko59e12822017-08-08 00:47:13 +000038class TargetRegisterClass;
39
Tom Stellard244891d2016-12-20 15:52:17 +000040class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
41public:
Matt Arsenault905f3512017-12-29 17:18:14 +000042 // TODO: Is the img rsrc useful?
Jan Sjodin312ccf72017-09-14 20:53:51 +000043 explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII) :
Matt Arsenault905f3512017-12-29 17:18:14 +000044 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) {}
Tom Stellard244891d2016-12-20 15:52:17 +000045
46 bool isConstant(const MachineFrameInfo *) const override {
47 // This should probably be true for most images, but we will start by being
48 // conservative.
49 return false;
50 }
51
52 bool isAliased(const MachineFrameInfo *) const override {
53 // FIXME: If we ever change image intrinsics to accept fat pointers, then
54 // this could be true for some cases.
55 return false;
56 }
57
Eugene Zelenko59e12822017-08-08 00:47:13 +000058 bool mayAlias(const MachineFrameInfo *) const override {
Tom Stellard244891d2016-12-20 15:52:17 +000059 // FIXME: If we ever change image intrinsics to accept fat pointers, then
60 // this could be true for some cases.
61 return false;
62 }
63};
64
Tom Stellard6f9ef142016-12-20 17:19:44 +000065class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
66public:
Jan Sjodin312ccf72017-09-14 20:53:51 +000067 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) :
68 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
Tom Stellard6f9ef142016-12-20 17:19:44 +000069
70 bool isConstant(const MachineFrameInfo *) const override {
71 // This should probably be true for most images, but we will start by being
72 // conservative.
73 return false;
74 }
75
76 bool isAliased(const MachineFrameInfo *) const override {
77 // FIXME: If we ever change image intrinsics to accept fat pointers, then
78 // this could be true for some cases.
79 return false;
80 }
81
Eugene Zelenko59e12822017-08-08 00:47:13 +000082 bool mayAlias(const MachineFrameInfo *) const override {
Tom Stellard6f9ef142016-12-20 17:19:44 +000083 // FIXME: If we ever change image intrinsics to accept fat pointers, then
84 // this could be true for some cases.
85 return false;
86 }
87};
Tom Stellard244891d2016-12-20 15:52:17 +000088
Tom Stellard75aadc22012-12-11 21:25:42 +000089/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
90/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000091class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
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
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000140 DenseMap<const Value *,
141 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
Matt Arsenault905f3512017-12-29 17:18:14 +0000142 DenseMap<const Value *,
143 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
144
Matt Arsenault161e2b42017-04-18 20:59:40 +0000145private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000146 unsigned LDSWaveSpillSize = 0;
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
Tim Renouf13229152017-09-29 09:49:35 +0000188 // The hard-wired high half of the address of the global information table
189 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
190 // current hardware only allows a 16 bit value.
191 unsigned GITPtrHigh;
192
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000193 MCPhysReg getNextUserSGPR() const {
194 assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
195 return AMDGPU::SGPR0 + NumUserSGPRs;
196 }
197
198 MCPhysReg getNextSystemSGPR() const {
199 return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
200 }
201
Matt Arsenault49affb82015-11-25 20:55:12 +0000202public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000203 struct SpilledReg {
Eugene Zelenko66203762017-01-21 00:53:49 +0000204 unsigned VGPR = AMDGPU::NoRegister;
205 int Lane = -1;
206
207 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000208 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000209
Tom Stellardc149dc02013-11-27 21:23:35 +0000210 bool hasLane() { return Lane != -1;}
Tom Stellard649b5db2016-03-04 18:31:18 +0000211 bool hasReg() { return VGPR != AMDGPU::NoRegister;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000212 };
213
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000214 struct SGPRSpillVGPRCSR {
215 // VGPR used for SGPR spills
216 unsigned VGPR;
217
218 // If the VGPR is a CSR, the stack slot used to save/restore it in the
219 // prolog/epilog.
220 Optional<int> FI;
221
Eugene Zelenko59e12822017-08-08 00:47:13 +0000222 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000223 };
224
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000225private:
226 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000227 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000228
229 // Track VGPR + wave index for each subregister of the SGPR spilled to
230 // frameindex key.
231 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
232 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000233 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000234
235public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000236 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000237
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000238 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
239 auto I = SGPRToVGPRSpills.find(FrameIndex);
240 return (I == SGPRToVGPRSpills.end()) ?
241 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
242 }
243
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000244 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
245 return SpillVGPRs;
246 }
247
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000248 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
249 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
250
Eugene Zelenko59e12822017-08-08 00:47:13 +0000251 bool hasCalculatedTID() const { return TIDReg != AMDGPU::NoRegister; }
252 unsigned getTIDReg() const { return TIDReg; }
Tom Stellard96468902014-09-24 01:33:17 +0000253 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000254
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000255 unsigned getBytesInStackArgArea() const {
256 return BytesInStackArgArea;
257 }
258
259 void setBytesInStackArgArea(unsigned Bytes) {
260 BytesInStackArgArea = Bytes;
261 }
262
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000263 // Add user SGPRs.
264 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
265 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
266 unsigned addQueuePtr(const SIRegisterInfo &TRI);
267 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000268 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000269 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000270 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000271
272 // Add system SGPRs.
273 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000274 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000275 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000276 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000277 }
278
279 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000280 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000281 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000282 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000283 }
284
285 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000286 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000287 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000288 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000289 }
290
291 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000292 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000293 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000294 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000295 }
296
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000297 // Add special VGPR inputs
298 void setWorkItemIDX(ArgDescriptor Arg) {
299 ArgInfo.WorkItemIDX = Arg;
300 }
301
302 void setWorkItemIDY(ArgDescriptor Arg) {
303 ArgInfo.WorkItemIDY = Arg;
304 }
305
306 void setWorkItemIDZ(ArgDescriptor Arg) {
307 ArgInfo.WorkItemIDZ = Arg;
308 }
309
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000310 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000311 ArgInfo.PrivateSegmentWaveByteOffset
312 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000313 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000314 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000315 }
316
Tom Stellardf110f8f2016-04-14 16:27:03 +0000317 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000318 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000319 }
320
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000321 bool hasPrivateSegmentBuffer() const {
322 return PrivateSegmentBuffer;
323 }
324
Matt Arsenault49affb82015-11-25 20:55:12 +0000325 bool hasDispatchPtr() const {
326 return DispatchPtr;
327 }
328
329 bool hasQueuePtr() const {
330 return QueuePtr;
331 }
332
Matt Arsenault49affb82015-11-25 20:55:12 +0000333 bool hasKernargSegmentPtr() const {
334 return KernargSegmentPtr;
335 }
336
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000337 bool hasDispatchID() const {
338 return DispatchID;
339 }
340
Matt Arsenault49affb82015-11-25 20:55:12 +0000341 bool hasFlatScratchInit() const {
342 return FlatScratchInit;
343 }
344
345 bool hasGridWorkgroupCountX() const {
346 return GridWorkgroupCountX;
347 }
348
349 bool hasGridWorkgroupCountY() const {
350 return GridWorkgroupCountY;
351 }
352
353 bool hasGridWorkgroupCountZ() const {
354 return GridWorkgroupCountZ;
355 }
356
357 bool hasWorkGroupIDX() const {
358 return WorkGroupIDX;
359 }
360
361 bool hasWorkGroupIDY() const {
362 return WorkGroupIDY;
363 }
364
365 bool hasWorkGroupIDZ() const {
366 return WorkGroupIDZ;
367 }
368
369 bool hasWorkGroupInfo() const {
370 return WorkGroupInfo;
371 }
372
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000373 bool hasPrivateSegmentWaveByteOffset() const {
374 return PrivateSegmentWaveByteOffset;
375 }
376
Matt Arsenault49affb82015-11-25 20:55:12 +0000377 bool hasWorkItemIDX() const {
378 return WorkItemIDX;
379 }
380
381 bool hasWorkItemIDY() const {
382 return WorkItemIDY;
383 }
384
385 bool hasWorkItemIDZ() const {
386 return WorkItemIDZ;
387 }
388
Matt Arsenault9166ce82017-07-28 15:52:08 +0000389 bool hasImplicitArgPtr() const {
390 return ImplicitArgPtr;
391 }
392
Matt Arsenault10fc0622017-06-26 03:01:31 +0000393 bool hasImplicitBufferPtr() const {
394 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000395 }
396
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000397 AMDGPUFunctionArgInfo &getArgInfo() {
398 return ArgInfo;
399 }
400
401 const AMDGPUFunctionArgInfo &getArgInfo() const {
402 return ArgInfo;
403 }
404
405 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
406 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
407 return ArgInfo.getPreloadedValue(Value);
408 }
409
410 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
411 return ArgInfo.getPreloadedValue(Value).first->getRegister();
412 }
413
Tim Renouf13229152017-09-29 09:49:35 +0000414 unsigned getGITPtrHigh() const {
415 return GITPtrHigh;
416 }
417
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000418 unsigned getNumUserSGPRs() const {
419 return NumUserSGPRs;
420 }
421
422 unsigned getNumPreloadedSGPRs() const {
423 return NumUserSGPRs + NumSystemSGPRs;
424 }
425
426 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000427 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000428 }
429
Matt Arsenault49affb82015-11-25 20:55:12 +0000430 /// \brief Returns the physical register reserved for use as the resource
431 /// descriptor for scratch accesses.
432 unsigned getScratchRSrcReg() const {
433 return ScratchRSrcReg;
434 }
435
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000436 void setScratchRSrcReg(unsigned Reg) {
437 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
438 ScratchRSrcReg = Reg;
439 }
440
441 unsigned getScratchWaveOffsetReg() const {
442 return ScratchWaveOffsetReg;
443 }
444
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000445 unsigned getFrameOffsetReg() const {
446 return FrameOffsetReg;
447 }
448
449 void setStackPtrOffsetReg(unsigned Reg) {
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000450 StackPtrOffsetReg = Reg;
451 }
452
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000453 // Note the unset value for this is AMDGPU::SP_REG rather than
454 // NoRegister. This is mostly a workaround for MIR tests where state that
455 // can't be directly computed from the function is not preserved in serialized
456 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000457 unsigned getStackPtrOffsetReg() const {
458 return StackPtrOffsetReg;
459 }
460
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000461 void setScratchWaveOffsetReg(unsigned Reg) {
462 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
463 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000464 if (isEntryFunction())
465 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000466 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000467
Matt Arsenault99c14522016-04-25 19:27:24 +0000468 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000469 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000470 }
471
Matt Arsenault10fc0622017-06-26 03:01:31 +0000472 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000473 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000474 }
475
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000476 bool hasSpilledSGPRs() const {
477 return HasSpilledSGPRs;
478 }
479
480 void setHasSpilledSGPRs(bool Spill = true) {
481 HasSpilledSGPRs = Spill;
482 }
483
484 bool hasSpilledVGPRs() const {
485 return HasSpilledVGPRs;
486 }
487
488 void setHasSpilledVGPRs(bool Spill = true) {
489 HasSpilledVGPRs = Spill;
490 }
Tom Stellard96468902014-09-24 01:33:17 +0000491
Matt Arsenault296b8492016-02-12 06:31:30 +0000492 bool hasNonSpillStackObjects() const {
493 return HasNonSpillStackObjects;
494 }
495
496 void setHasNonSpillStackObjects(bool StackObject = true) {
497 HasNonSpillStackObjects = StackObject;
498 }
499
Marek Olsak0532c192016-07-13 17:35:15 +0000500 unsigned getNumSpilledSGPRs() const {
501 return NumSpilledSGPRs;
502 }
503
504 unsigned getNumSpilledVGPRs() const {
505 return NumSpilledVGPRs;
506 }
507
508 void addToSpilledSGPRs(unsigned num) {
509 NumSpilledSGPRs += num;
510 }
511
512 void addToSpilledVGPRs(unsigned num) {
513 NumSpilledVGPRs += num;
514 }
515
Marek Olsakfccabaf2016-01-13 11:45:36 +0000516 unsigned getPSInputAddr() const {
517 return PSInputAddr;
518 }
519
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000520 unsigned getPSInputEnable() const {
521 return PSInputEnable;
522 }
523
Marek Olsakfccabaf2016-01-13 11:45:36 +0000524 bool isPSInputAllocated(unsigned Index) const {
525 return PSInputAddr & (1 << Index);
526 }
527
528 void markPSInputAllocated(unsigned Index) {
529 PSInputAddr |= 1 << Index;
530 }
531
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000532 void markPSInputEnabled(unsigned Index) {
533 PSInputEnable |= 1 << Index;
534 }
535
Marek Olsak8e9cc632016-01-13 17:23:09 +0000536 bool returnsVoid() const {
537 return ReturnsVoid;
538 }
539
540 void setIfReturnsVoid(bool Value) {
541 ReturnsVoid = Value;
542 }
543
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000544 /// \returns A pair of default/requested minimum/maximum flat work group sizes
545 /// for this function.
546 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
547 return FlatWorkGroupSizes;
548 }
549
550 /// \returns Default/requested minimum flat work group size for this function.
551 unsigned getMinFlatWorkGroupSize() const {
552 return FlatWorkGroupSizes.first;
553 }
554
555 /// \returns Default/requested maximum flat work group size for this function.
556 unsigned getMaxFlatWorkGroupSize() const {
557 return FlatWorkGroupSizes.second;
558 }
559
560 /// \returns A pair of default/requested minimum/maximum number of waves per
561 /// execution unit.
562 std::pair<unsigned, unsigned> getWavesPerEU() const {
563 return WavesPerEU;
564 }
565
566 /// \returns Default/requested minimum number of waves per execution unit.
567 unsigned getMinWavesPerEU() const {
568 return WavesPerEU.first;
569 }
570
571 /// \returns Default/requested maximum number of waves per execution unit.
572 unsigned getMaxWavesPerEU() const {
573 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000574 }
575
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000576 /// \returns Stack object index for \p Dim's work group ID.
577 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
578 assert(Dim < 3);
579 return DebuggerWorkGroupIDStackObjectIndices[Dim];
580 }
581
582 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
583 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
584 assert(Dim < 3);
585 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
586 }
587
588 /// \returns Stack object index for \p Dim's work item ID.
589 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
590 assert(Dim < 3);
591 return DebuggerWorkItemIDStackObjectIndices[Dim];
592 }
593
594 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
595 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
596 assert(Dim < 3);
597 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
598 }
599
600 /// \returns SGPR used for \p Dim's work group ID.
601 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
602 switch (Dim) {
603 case 0:
604 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000605 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000606 case 1:
607 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000608 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000609 case 2:
610 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000611 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000612 }
613 llvm_unreachable("unexpected dimension");
614 }
615
616 /// \returns VGPR used for \p Dim' work item ID.
617 unsigned getWorkItemIDVGPR(unsigned Dim) const {
618 switch (Dim) {
619 case 0:
620 assert(hasWorkItemIDX());
621 return AMDGPU::VGPR0;
622 case 1:
623 assert(hasWorkItemIDY());
624 return AMDGPU::VGPR1;
625 case 2:
626 assert(hasWorkItemIDZ());
627 return AMDGPU::VGPR2;
628 }
629 llvm_unreachable("unexpected dimension");
630 }
Tom Stellard244891d2016-12-20 15:52:17 +0000631
Matt Arsenault161e2b42017-04-18 20:59:40 +0000632 unsigned getLDSWaveSpillSize() const {
633 return LDSWaveSpillSize;
634 }
635
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000636 const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII,
637 const Value *BufferRsrc) {
638 assert(BufferRsrc);
639 auto PSV = BufferPSVs.try_emplace(
640 BufferRsrc,
641 llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII));
642 return PSV.first->second.get();
Tom Stellard6f9ef142016-12-20 17:19:44 +0000643 }
644
Matt Arsenault905f3512017-12-29 17:18:14 +0000645 const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII,
646 const Value *ImgRsrc) {
647 assert(ImgRsrc);
648 auto PSV = ImagePSVs.try_emplace(
649 ImgRsrc,
650 llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII));
651 return PSV.first->second.get();
Tom Stellard244891d2016-12-20 15:52:17 +0000652 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000653};
654
Eugene Zelenko66203762017-01-21 00:53:49 +0000655} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000656
Eugene Zelenko66203762017-01-21 00:53:49 +0000657#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H