blob: 781eea0f94b41819b7fa786458680f6f894cd37a [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 {
Tim Renouf75ced9d2018-01-12 22:57:24 +000053 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000054 }
55
Eugene Zelenko59e12822017-08-08 00:47:13 +000056 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000057 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000058 }
59};
60
Tom Stellard6f9ef142016-12-20 17:19:44 +000061class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
62public:
Jan Sjodin312ccf72017-09-14 20:53:51 +000063 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) :
64 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
Tom Stellard6f9ef142016-12-20 17:19:44 +000065
66 bool isConstant(const MachineFrameInfo *) const override {
67 // This should probably be true for most images, but we will start by being
68 // conservative.
69 return false;
70 }
71
72 bool isAliased(const MachineFrameInfo *) const override {
Tim Renouf8234b482018-02-20 10:03:38 +000073 return true;
Tom Stellard6f9ef142016-12-20 17:19:44 +000074 }
75
Eugene Zelenko59e12822017-08-08 00:47:13 +000076 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf8234b482018-02-20 10:03:38 +000077 return true;
Tom Stellard6f9ef142016-12-20 17:19:44 +000078 }
79};
Tom Stellard244891d2016-12-20 15:52:17 +000080
Tom Stellard75aadc22012-12-11 21:25:42 +000081/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
82/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000083class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Eugene Zelenko59e12822017-08-08 00:47:13 +000084 unsigned TIDReg = AMDGPU::NoRegister;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000085
86 // Registers that may be reserved for spilling purposes. These may be the same
87 // as the input registers.
Eugene Zelenko59e12822017-08-08 00:47:13 +000088 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
89 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +000090
Matt Arsenault1c0ae392017-04-24 18:05:16 +000091 // This is the current function's incremented size from the kernel's scratch
92 // wave offset register. For an entry function, this is exactly the same as
93 // the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +000094 unsigned FrameOffsetReg = AMDGPU::FP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +000095
96 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +000097 unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +000098
Matt Arsenault8623e8d2017-08-03 23:00:29 +000099 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000100
Marek Olsakfccabaf2016-01-13 11:45:36 +0000101 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000102 unsigned PSInputAddr = 0;
103 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000104
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000105 /// Number of bytes of arguments this function has on the stack. If the callee
106 /// is expected to restore the argument stack this should be a multiple of 16,
107 /// all usable during a tail call.
108 ///
109 /// The alternative would forbid tail call optimisation in some cases: if we
110 /// want to transfer control from a function with 8-bytes of stack-argument
111 /// space to a function with 16-bytes then misalignment of this value would
112 /// make a stack adjustment necessary, which could not be undone by the
113 /// callee.
114 unsigned BytesInStackArgArea = 0;
115
Eugene Zelenko59e12822017-08-08 00:47:13 +0000116 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000117
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000118 // A pair of default/requested minimum/maximum flat work group sizes.
119 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000120 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000121
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000122 // A pair of default/requested minimum/maximum number of waves per execution
123 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000124 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000125
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000126 // Stack object indices for work group IDs.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000127 std::array<int, 3> DebuggerWorkGroupIDStackObjectIndices = {{0, 0, 0}};
128
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000129 // Stack object indices for work item IDs.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000130 std::array<int, 3> DebuggerWorkItemIDStackObjectIndices = {{0, 0, 0}};
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000131
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000132 DenseMap<const Value *,
133 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
Matt Arsenault905f3512017-12-29 17:18:14 +0000134 DenseMap<const Value *,
135 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
136
Matt Arsenault161e2b42017-04-18 20:59:40 +0000137private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000138 unsigned LDSWaveSpillSize = 0;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000139 unsigned NumUserSGPRs = 0;
140 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000141
Eugene Zelenko59e12822017-08-08 00:47:13 +0000142 bool HasSpilledSGPRs = false;
143 bool HasSpilledVGPRs = false;
144 bool HasNonSpillStackObjects = false;
Tom Stellard96468902014-09-24 01:33:17 +0000145
Eugene Zelenko59e12822017-08-08 00:47:13 +0000146 unsigned NumSpilledSGPRs = 0;
147 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000148
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000149 // Feature bits required for inputs passed in user SGPRs.
150 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000151 bool DispatchPtr : 1;
152 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000153 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000154 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000155 bool FlatScratchInit : 1;
156 bool GridWorkgroupCountX : 1;
157 bool GridWorkgroupCountY : 1;
158 bool GridWorkgroupCountZ : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000159
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000160 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000161 bool WorkGroupIDX : 1; // Always initialized.
162 bool WorkGroupIDY : 1;
163 bool WorkGroupIDZ : 1;
164 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000165 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000166
167 bool WorkItemIDX : 1; // Always initialized.
168 bool WorkItemIDY : 1;
169 bool WorkItemIDZ : 1;
170
Tom Stellard2f3f9852017-01-25 01:25:13 +0000171 // Private memory buffer
172 // Compute directly in sgpr[0:1]
173 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000174 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000175
Matt Arsenault9166ce82017-07-28 15:52:08 +0000176 // Pointer to where the ABI inserts special kernel arguments separate from the
177 // user arguments. This is an offset from the KernargSegmentPtr.
178 bool ImplicitArgPtr : 1;
179
Tim Renouf13229152017-09-29 09:49:35 +0000180 // The hard-wired high half of the address of the global information table
181 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
182 // current hardware only allows a 16 bit value.
183 unsigned GITPtrHigh;
184
Matt Arsenault923712b2018-02-09 16:57:57 +0000185 unsigned HighBitsOf32BitAddress;
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
Tim Renouf13229152017-09-29 09:49:35 +0000408 unsigned getGITPtrHigh() const {
409 return GITPtrHigh;
410 }
411
Matt Arsenault923712b2018-02-09 16:57:57 +0000412 unsigned get32BitAddressHighBits() const {
413 return HighBitsOf32BitAddress;
414 }
415
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000416 unsigned getNumUserSGPRs() const {
417 return NumUserSGPRs;
418 }
419
420 unsigned getNumPreloadedSGPRs() const {
421 return NumUserSGPRs + NumSystemSGPRs;
422 }
423
424 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000425 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000426 }
427
Matt Arsenault49affb82015-11-25 20:55:12 +0000428 /// \brief Returns the physical register reserved for use as the resource
429 /// descriptor for scratch accesses.
430 unsigned getScratchRSrcReg() const {
431 return ScratchRSrcReg;
432 }
433
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000434 void setScratchRSrcReg(unsigned Reg) {
435 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
436 ScratchRSrcReg = Reg;
437 }
438
439 unsigned getScratchWaveOffsetReg() const {
440 return ScratchWaveOffsetReg;
441 }
442
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000443 unsigned getFrameOffsetReg() const {
444 return FrameOffsetReg;
445 }
446
447 void setStackPtrOffsetReg(unsigned Reg) {
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000448 StackPtrOffsetReg = Reg;
449 }
450
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000451 // Note the unset value for this is AMDGPU::SP_REG rather than
452 // NoRegister. This is mostly a workaround for MIR tests where state that
453 // can't be directly computed from the function is not preserved in serialized
454 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000455 unsigned getStackPtrOffsetReg() const {
456 return StackPtrOffsetReg;
457 }
458
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000459 void setScratchWaveOffsetReg(unsigned Reg) {
460 assert(Reg != AMDGPU::NoRegister && "Should never be unset");
461 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000462 if (isEntryFunction())
463 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000464 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000465
Matt Arsenault99c14522016-04-25 19:27:24 +0000466 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000467 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000468 }
469
Matt Arsenault10fc0622017-06-26 03:01:31 +0000470 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000471 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000472 }
473
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000474 bool hasSpilledSGPRs() const {
475 return HasSpilledSGPRs;
476 }
477
478 void setHasSpilledSGPRs(bool Spill = true) {
479 HasSpilledSGPRs = Spill;
480 }
481
482 bool hasSpilledVGPRs() const {
483 return HasSpilledVGPRs;
484 }
485
486 void setHasSpilledVGPRs(bool Spill = true) {
487 HasSpilledVGPRs = Spill;
488 }
Tom Stellard96468902014-09-24 01:33:17 +0000489
Matt Arsenault296b8492016-02-12 06:31:30 +0000490 bool hasNonSpillStackObjects() const {
491 return HasNonSpillStackObjects;
492 }
493
494 void setHasNonSpillStackObjects(bool StackObject = true) {
495 HasNonSpillStackObjects = StackObject;
496 }
497
Marek Olsak0532c192016-07-13 17:35:15 +0000498 unsigned getNumSpilledSGPRs() const {
499 return NumSpilledSGPRs;
500 }
501
502 unsigned getNumSpilledVGPRs() const {
503 return NumSpilledVGPRs;
504 }
505
506 void addToSpilledSGPRs(unsigned num) {
507 NumSpilledSGPRs += num;
508 }
509
510 void addToSpilledVGPRs(unsigned num) {
511 NumSpilledVGPRs += num;
512 }
513
Marek Olsakfccabaf2016-01-13 11:45:36 +0000514 unsigned getPSInputAddr() const {
515 return PSInputAddr;
516 }
517
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000518 unsigned getPSInputEnable() const {
519 return PSInputEnable;
520 }
521
Marek Olsakfccabaf2016-01-13 11:45:36 +0000522 bool isPSInputAllocated(unsigned Index) const {
523 return PSInputAddr & (1 << Index);
524 }
525
526 void markPSInputAllocated(unsigned Index) {
527 PSInputAddr |= 1 << Index;
528 }
529
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000530 void markPSInputEnabled(unsigned Index) {
531 PSInputEnable |= 1 << Index;
532 }
533
Marek Olsak8e9cc632016-01-13 17:23:09 +0000534 bool returnsVoid() const {
535 return ReturnsVoid;
536 }
537
538 void setIfReturnsVoid(bool Value) {
539 ReturnsVoid = Value;
540 }
541
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000542 /// \returns A pair of default/requested minimum/maximum flat work group sizes
543 /// for this function.
544 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
545 return FlatWorkGroupSizes;
546 }
547
548 /// \returns Default/requested minimum flat work group size for this function.
549 unsigned getMinFlatWorkGroupSize() const {
550 return FlatWorkGroupSizes.first;
551 }
552
553 /// \returns Default/requested maximum flat work group size for this function.
554 unsigned getMaxFlatWorkGroupSize() const {
555 return FlatWorkGroupSizes.second;
556 }
557
558 /// \returns A pair of default/requested minimum/maximum number of waves per
559 /// execution unit.
560 std::pair<unsigned, unsigned> getWavesPerEU() const {
561 return WavesPerEU;
562 }
563
564 /// \returns Default/requested minimum number of waves per execution unit.
565 unsigned getMinWavesPerEU() const {
566 return WavesPerEU.first;
567 }
568
569 /// \returns Default/requested maximum number of waves per execution unit.
570 unsigned getMaxWavesPerEU() const {
571 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000572 }
573
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000574 /// \returns Stack object index for \p Dim's work group ID.
575 int getDebuggerWorkGroupIDStackObjectIndex(unsigned Dim) const {
576 assert(Dim < 3);
577 return DebuggerWorkGroupIDStackObjectIndices[Dim];
578 }
579
580 /// \brief Sets stack object index for \p Dim's work group ID to \p ObjectIdx.
581 void setDebuggerWorkGroupIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
582 assert(Dim < 3);
583 DebuggerWorkGroupIDStackObjectIndices[Dim] = ObjectIdx;
584 }
585
586 /// \returns Stack object index for \p Dim's work item ID.
587 int getDebuggerWorkItemIDStackObjectIndex(unsigned Dim) const {
588 assert(Dim < 3);
589 return DebuggerWorkItemIDStackObjectIndices[Dim];
590 }
591
592 /// \brief Sets stack object index for \p Dim's work item ID to \p ObjectIdx.
593 void setDebuggerWorkItemIDStackObjectIndex(unsigned Dim, int ObjectIdx) {
594 assert(Dim < 3);
595 DebuggerWorkItemIDStackObjectIndices[Dim] = ObjectIdx;
596 }
597
598 /// \returns SGPR used for \p Dim's work group ID.
599 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
600 switch (Dim) {
601 case 0:
602 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000603 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000604 case 1:
605 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000606 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000607 case 2:
608 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000609 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000610 }
611 llvm_unreachable("unexpected dimension");
612 }
613
614 /// \returns VGPR used for \p Dim' work item ID.
615 unsigned getWorkItemIDVGPR(unsigned Dim) const {
616 switch (Dim) {
617 case 0:
618 assert(hasWorkItemIDX());
619 return AMDGPU::VGPR0;
620 case 1:
621 assert(hasWorkItemIDY());
622 return AMDGPU::VGPR1;
623 case 2:
624 assert(hasWorkItemIDZ());
625 return AMDGPU::VGPR2;
626 }
627 llvm_unreachable("unexpected dimension");
628 }
Tom Stellard244891d2016-12-20 15:52:17 +0000629
Matt Arsenault161e2b42017-04-18 20:59:40 +0000630 unsigned getLDSWaveSpillSize() const {
631 return LDSWaveSpillSize;
632 }
633
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000634 const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII,
635 const Value *BufferRsrc) {
636 assert(BufferRsrc);
637 auto PSV = BufferPSVs.try_emplace(
638 BufferRsrc,
639 llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII));
640 return PSV.first->second.get();
Tom Stellard6f9ef142016-12-20 17:19:44 +0000641 }
642
Matt Arsenault905f3512017-12-29 17:18:14 +0000643 const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII,
644 const Value *ImgRsrc) {
645 assert(ImgRsrc);
646 auto PSV = ImagePSVs.try_emplace(
647 ImgRsrc,
648 llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII));
649 return PSV.first->second.get();
Tom Stellard244891d2016-12-20 15:52:17 +0000650 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000651};
652
Eugene Zelenko66203762017-01-21 00:53:49 +0000653} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000654
Eugene Zelenko66203762017-01-21 00:53:49 +0000655#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H