blob: 29e2460ae7939b6ebeebc57d3818ba844ea23f36 [file] [log] [blame]
Eugene Zelenko59e12822017-08-08 00:47:13 +00001//==- SIMachineFunctionInfo.h - SIMachineFunctionInfo interface --*- C++ -*-==//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Tom Stellard75aadc22012-12-11 21:25:42 +00006//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10//
11//===----------------------------------------------------------------------===//
12
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000013#ifndef LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
14#define LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H
Tom Stellard75aadc22012-12-11 21:25:42 +000015
Matt Arsenault8623e8d2017-08-03 23:00:29 +000016#include "AMDGPUArgumentUsageInfo.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000017#include "AMDGPUMachineFunction.h"
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +000018#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
Tom Stellard44b30b42018-05-22 02:03:23 +000019#include "SIInstrInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000020#include "SIRegisterInfo.h"
Eugene Zelenko59e12822017-08-08 00:47:13 +000021#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/Optional.h"
24#include "llvm/ADT/SmallVector.h"
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +000025#include "llvm/CodeGen/MIRYamlMapping.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000026#include "llvm/CodeGen/PseudoSourceValue.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000027#include "llvm/CodeGen/TargetInstrInfo.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000028#include "llvm/MC/MCRegisterInfo.h"
29#include "llvm/Support/ErrorHandling.h"
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000030#include <array>
Eugene Zelenko66203762017-01-21 00:53:49 +000031#include <cassert>
Eugene Zelenko66203762017-01-21 00:53:49 +000032#include <utility>
Eugene Zelenko59e12822017-08-08 00:47:13 +000033#include <vector>
Tom Stellard75aadc22012-12-11 21:25:42 +000034
35namespace llvm {
36
Eugene Zelenko59e12822017-08-08 00:47:13 +000037class MachineFrameInfo;
38class MachineFunction;
39class TargetRegisterClass;
40
Tom Stellard244891d2016-12-20 15:52:17 +000041class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
42public:
Matt Arsenault905f3512017-12-29 17:18:14 +000043 // TODO: Is the img rsrc useful?
Jan Sjodin312ccf72017-09-14 20:53:51 +000044 explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII) :
Matt Arsenault905f3512017-12-29 17:18:14 +000045 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) {}
Tom Stellard244891d2016-12-20 15:52:17 +000046
47 bool isConstant(const MachineFrameInfo *) const override {
48 // This should probably be true for most images, but we will start by being
49 // conservative.
50 return false;
51 }
52
53 bool isAliased(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000054 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000055 }
56
Eugene Zelenko59e12822017-08-08 00:47:13 +000057 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000058 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000059 }
60};
61
Tom Stellard6f9ef142016-12-20 17:19:44 +000062class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
63public:
Jan Sjodin312ccf72017-09-14 20:53:51 +000064 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) :
65 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
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 {
Tim Renouf8234b482018-02-20 10:03:38 +000074 return true;
Tom Stellard6f9ef142016-12-20 17:19:44 +000075 }
76
Eugene Zelenko59e12822017-08-08 00:47:13 +000077 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf8234b482018-02-20 10:03:38 +000078 return true;
Tom Stellard6f9ef142016-12-20 17:19:44 +000079 }
80};
Tom Stellard244891d2016-12-20 15:52:17 +000081
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +000082namespace yaml {
83
84struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo {
85 uint64_t ExplicitKernArgSize = 0;
86 unsigned MaxKernArgAlign = 0;
87 unsigned LDSSize = 0;
88 bool IsEntryFunction = false;
89 bool NoSignedZerosFPMath = false;
90 bool MemoryBound = false;
91 bool WaveLimiter = false;
92
93 StringValue ScratchRSrcReg = "$private_rsrc_reg";
94 StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg";
95 StringValue FrameOffsetReg = "$fp_reg";
96 StringValue StackPtrOffsetReg = "$sp_reg";
97
98 SIMachineFunctionInfo() = default;
99 SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &,
100 const TargetRegisterInfo &TRI);
101
102 void mappingImpl(yaml::IO &YamlIO) override;
103 ~SIMachineFunctionInfo() = default;
104};
105
106template <> struct MappingTraits<SIMachineFunctionInfo> {
107 static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) {
108 YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize,
109 UINT64_C(0));
110 YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u);
111 YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u);
112 YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false);
113 YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false);
114 YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false);
115 YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false);
116 YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg,
117 StringValue("$private_rsrc_reg"));
118 YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg,
119 StringValue("$scratch_wave_offset_reg"));
120 YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg,
121 StringValue("$fp_reg"));
122 YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg,
123 StringValue("$sp_reg"));
124 }
125};
126
127} // end namespace yaml
128
Tom Stellard75aadc22012-12-11 21:25:42 +0000129/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
130/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +0000131class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000132 friend class GCNTargetMachine;
133
Eugene Zelenko59e12822017-08-08 00:47:13 +0000134 unsigned TIDReg = AMDGPU::NoRegister;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000135
136 // Registers that may be reserved for spilling purposes. These may be the same
137 // as the input registers.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000138 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
139 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000140
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000141 // This is the current function's incremented size from the kernel's scratch
142 // wave offset register. For an entry function, this is exactly the same as
143 // the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000144 unsigned FrameOffsetReg = AMDGPU::FP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000145
146 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000147 unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000148
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000149 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000150
Matt Arsenault055e4dc2019-03-29 19:14:54 +0000151 // State of MODE register, assumed FP mode.
152 AMDGPU::SIModeRegisterDefaults Mode;
153
Marek Olsakfccabaf2016-01-13 11:45:36 +0000154 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000155 unsigned PSInputAddr = 0;
156 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000157
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000158 /// Number of bytes of arguments this function has on the stack. If the callee
159 /// is expected to restore the argument stack this should be a multiple of 16,
160 /// all usable during a tail call.
161 ///
162 /// The alternative would forbid tail call optimisation in some cases: if we
163 /// want to transfer control from a function with 8-bytes of stack-argument
164 /// space to a function with 16-bytes then misalignment of this value would
165 /// make a stack adjustment necessary, which could not be undone by the
166 /// callee.
167 unsigned BytesInStackArgArea = 0;
168
Eugene Zelenko59e12822017-08-08 00:47:13 +0000169 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000170
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000171 // A pair of default/requested minimum/maximum flat work group sizes.
172 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000173 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000174
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000175 // A pair of default/requested minimum/maximum number of waves per execution
176 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000177 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000178
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000179 DenseMap<const Value *,
180 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
Matt Arsenault905f3512017-12-29 17:18:14 +0000181 DenseMap<const Value *,
182 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
183
Matt Arsenault161e2b42017-04-18 20:59:40 +0000184private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000185 unsigned LDSWaveSpillSize = 0;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000186 unsigned NumUserSGPRs = 0;
187 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000188
Eugene Zelenko59e12822017-08-08 00:47:13 +0000189 bool HasSpilledSGPRs = false;
190 bool HasSpilledVGPRs = false;
191 bool HasNonSpillStackObjects = false;
Matt Arsenault03ae3992018-03-29 21:30:06 +0000192 bool IsStackRealigned = false;
Tom Stellard96468902014-09-24 01:33:17 +0000193
Eugene Zelenko59e12822017-08-08 00:47:13 +0000194 unsigned NumSpilledSGPRs = 0;
195 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000196
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000197 // Feature bits required for inputs passed in user SGPRs.
198 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000199 bool DispatchPtr : 1;
200 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000201 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000202 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000203 bool FlatScratchInit : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000204
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000205 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000206 bool WorkGroupIDX : 1; // Always initialized.
207 bool WorkGroupIDY : 1;
208 bool WorkGroupIDZ : 1;
209 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000210 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000211
212 bool WorkItemIDX : 1; // Always initialized.
213 bool WorkItemIDY : 1;
214 bool WorkItemIDZ : 1;
215
Tom Stellard2f3f9852017-01-25 01:25:13 +0000216 // Private memory buffer
217 // Compute directly in sgpr[0:1]
218 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000219 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000220
Matt Arsenault9166ce82017-07-28 15:52:08 +0000221 // Pointer to where the ABI inserts special kernel arguments separate from the
222 // user arguments. This is an offset from the KernargSegmentPtr.
223 bool ImplicitArgPtr : 1;
224
Tim Renouf13229152017-09-29 09:49:35 +0000225 // The hard-wired high half of the address of the global information table
226 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
227 // current hardware only allows a 16 bit value.
228 unsigned GITPtrHigh;
229
Matt Arsenault923712b2018-02-09 16:57:57 +0000230 unsigned HighBitsOf32BitAddress;
231
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000232 // Current recorded maximum possible occupancy.
233 unsigned Occupancy;
234
Tom Stellard44b30b42018-05-22 02:03:23 +0000235 MCPhysReg getNextUserSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000236
Tom Stellard44b30b42018-05-22 02:03:23 +0000237 MCPhysReg getNextSystemSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000238
Matt Arsenault49affb82015-11-25 20:55:12 +0000239public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000240 struct SpilledReg {
Tom Stellard44b30b42018-05-22 02:03:23 +0000241 unsigned VGPR = 0;
Eugene Zelenko66203762017-01-21 00:53:49 +0000242 int Lane = -1;
243
244 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000245 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000246
Tom Stellardc149dc02013-11-27 21:23:35 +0000247 bool hasLane() { return Lane != -1;}
Tom Stellard44b30b42018-05-22 02:03:23 +0000248 bool hasReg() { return VGPR != 0;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000249 };
250
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000251 struct SGPRSpillVGPRCSR {
252 // VGPR used for SGPR spills
253 unsigned VGPR;
254
255 // If the VGPR is a CSR, the stack slot used to save/restore it in the
256 // prolog/epilog.
257 Optional<int> FI;
258
Eugene Zelenko59e12822017-08-08 00:47:13 +0000259 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000260 };
261
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000262private:
263 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000264 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000265
266 // Track VGPR + wave index for each subregister of the SGPR spilled to
267 // frameindex key.
268 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
269 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000270 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000271
272public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000273 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000274
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000275 bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI);
276
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000277 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
278 auto I = SGPRToVGPRSpills.find(FrameIndex);
279 return (I == SGPRToVGPRSpills.end()) ?
280 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
281 }
282
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000283 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
284 return SpillVGPRs;
285 }
286
Matt Arsenault055e4dc2019-03-29 19:14:54 +0000287 AMDGPU::SIModeRegisterDefaults getMode() const {
288 return Mode;
289 }
290
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000291 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
292 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
293
Tom Stellard44b30b42018-05-22 02:03:23 +0000294 bool hasCalculatedTID() const { return TIDReg != 0; };
295 unsigned getTIDReg() const { return TIDReg; };
Tom Stellard96468902014-09-24 01:33:17 +0000296 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000297
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000298 unsigned getBytesInStackArgArea() const {
299 return BytesInStackArgArea;
300 }
301
302 void setBytesInStackArgArea(unsigned Bytes) {
303 BytesInStackArgArea = Bytes;
304 }
305
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000306 // Add user SGPRs.
307 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
308 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
309 unsigned addQueuePtr(const SIRegisterInfo &TRI);
310 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000311 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000312 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000313 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000314
315 // Add system SGPRs.
316 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000317 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000318 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000319 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000320 }
321
322 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000323 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000324 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000325 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000326 }
327
328 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000329 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000330 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000331 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000332 }
333
334 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000335 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000336 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000337 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000338 }
339
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000340 // Add special VGPR inputs
341 void setWorkItemIDX(ArgDescriptor Arg) {
342 ArgInfo.WorkItemIDX = Arg;
343 }
344
345 void setWorkItemIDY(ArgDescriptor Arg) {
346 ArgInfo.WorkItemIDY = Arg;
347 }
348
349 void setWorkItemIDZ(ArgDescriptor Arg) {
350 ArgInfo.WorkItemIDZ = Arg;
351 }
352
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000353 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000354 ArgInfo.PrivateSegmentWaveByteOffset
355 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000356 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000357 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000358 }
359
Tom Stellardf110f8f2016-04-14 16:27:03 +0000360 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000361 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000362 }
363
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000364 bool hasPrivateSegmentBuffer() const {
365 return PrivateSegmentBuffer;
366 }
367
Matt Arsenault49affb82015-11-25 20:55:12 +0000368 bool hasDispatchPtr() const {
369 return DispatchPtr;
370 }
371
372 bool hasQueuePtr() const {
373 return QueuePtr;
374 }
375
Matt Arsenault49affb82015-11-25 20:55:12 +0000376 bool hasKernargSegmentPtr() const {
377 return KernargSegmentPtr;
378 }
379
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000380 bool hasDispatchID() const {
381 return DispatchID;
382 }
383
Matt Arsenault49affb82015-11-25 20:55:12 +0000384 bool hasFlatScratchInit() const {
385 return FlatScratchInit;
386 }
387
Matt Arsenault49affb82015-11-25 20:55:12 +0000388 bool hasWorkGroupIDX() const {
389 return WorkGroupIDX;
390 }
391
392 bool hasWorkGroupIDY() const {
393 return WorkGroupIDY;
394 }
395
396 bool hasWorkGroupIDZ() const {
397 return WorkGroupIDZ;
398 }
399
400 bool hasWorkGroupInfo() const {
401 return WorkGroupInfo;
402 }
403
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000404 bool hasPrivateSegmentWaveByteOffset() const {
405 return PrivateSegmentWaveByteOffset;
406 }
407
Matt Arsenault49affb82015-11-25 20:55:12 +0000408 bool hasWorkItemIDX() const {
409 return WorkItemIDX;
410 }
411
412 bool hasWorkItemIDY() const {
413 return WorkItemIDY;
414 }
415
416 bool hasWorkItemIDZ() const {
417 return WorkItemIDZ;
418 }
419
Matt Arsenault9166ce82017-07-28 15:52:08 +0000420 bool hasImplicitArgPtr() const {
421 return ImplicitArgPtr;
422 }
423
Matt Arsenault10fc0622017-06-26 03:01:31 +0000424 bool hasImplicitBufferPtr() const {
425 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000426 }
427
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000428 AMDGPUFunctionArgInfo &getArgInfo() {
429 return ArgInfo;
430 }
431
432 const AMDGPUFunctionArgInfo &getArgInfo() const {
433 return ArgInfo;
434 }
435
436 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
437 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
438 return ArgInfo.getPreloadedValue(Value);
439 }
440
441 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
442 return ArgInfo.getPreloadedValue(Value).first->getRegister();
443 }
444
Tim Renouf13229152017-09-29 09:49:35 +0000445 unsigned getGITPtrHigh() const {
446 return GITPtrHigh;
447 }
448
Matt Arsenault923712b2018-02-09 16:57:57 +0000449 unsigned get32BitAddressHighBits() const {
450 return HighBitsOf32BitAddress;
451 }
452
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000453 unsigned getNumUserSGPRs() const {
454 return NumUserSGPRs;
455 }
456
457 unsigned getNumPreloadedSGPRs() const {
458 return NumUserSGPRs + NumSystemSGPRs;
459 }
460
461 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000462 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000463 }
464
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000465 /// Returns the physical register reserved for use as the resource
Matt Arsenault49affb82015-11-25 20:55:12 +0000466 /// descriptor for scratch accesses.
467 unsigned getScratchRSrcReg() const {
468 return ScratchRSrcReg;
469 }
470
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000471 void setScratchRSrcReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000472 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000473 ScratchRSrcReg = Reg;
474 }
475
476 unsigned getScratchWaveOffsetReg() const {
477 return ScratchWaveOffsetReg;
478 }
479
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000480 unsigned getFrameOffsetReg() const {
481 return FrameOffsetReg;
482 }
483
484 void setStackPtrOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000485 assert(Reg != 0 && "Should never be unset");
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000486 StackPtrOffsetReg = Reg;
487 }
488
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000489 // Note the unset value for this is AMDGPU::SP_REG rather than
490 // NoRegister. This is mostly a workaround for MIR tests where state that
491 // can't be directly computed from the function is not preserved in serialized
492 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000493 unsigned getStackPtrOffsetReg() const {
494 return StackPtrOffsetReg;
495 }
496
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000497 void setScratchWaveOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000498 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000499 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000500 if (isEntryFunction())
501 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000502 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000503
Matt Arsenault99c14522016-04-25 19:27:24 +0000504 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000505 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000506 }
507
Matt Arsenault10fc0622017-06-26 03:01:31 +0000508 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000509 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000510 }
511
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000512 bool hasSpilledSGPRs() const {
513 return HasSpilledSGPRs;
514 }
515
516 void setHasSpilledSGPRs(bool Spill = true) {
517 HasSpilledSGPRs = Spill;
518 }
519
520 bool hasSpilledVGPRs() const {
521 return HasSpilledVGPRs;
522 }
523
524 void setHasSpilledVGPRs(bool Spill = true) {
525 HasSpilledVGPRs = Spill;
526 }
Tom Stellard96468902014-09-24 01:33:17 +0000527
Matt Arsenault296b8492016-02-12 06:31:30 +0000528 bool hasNonSpillStackObjects() const {
529 return HasNonSpillStackObjects;
530 }
531
532 void setHasNonSpillStackObjects(bool StackObject = true) {
533 HasNonSpillStackObjects = StackObject;
534 }
535
Matt Arsenault03ae3992018-03-29 21:30:06 +0000536 bool isStackRealigned() const {
537 return IsStackRealigned;
538 }
539
540 void setIsStackRealigned(bool Realigned = true) {
541 IsStackRealigned = Realigned;
542 }
543
Marek Olsak0532c192016-07-13 17:35:15 +0000544 unsigned getNumSpilledSGPRs() const {
545 return NumSpilledSGPRs;
546 }
547
548 unsigned getNumSpilledVGPRs() const {
549 return NumSpilledVGPRs;
550 }
551
552 void addToSpilledSGPRs(unsigned num) {
553 NumSpilledSGPRs += num;
554 }
555
556 void addToSpilledVGPRs(unsigned num) {
557 NumSpilledVGPRs += num;
558 }
559
Marek Olsakfccabaf2016-01-13 11:45:36 +0000560 unsigned getPSInputAddr() const {
561 return PSInputAddr;
562 }
563
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000564 unsigned getPSInputEnable() const {
565 return PSInputEnable;
566 }
567
Marek Olsakfccabaf2016-01-13 11:45:36 +0000568 bool isPSInputAllocated(unsigned Index) const {
569 return PSInputAddr & (1 << Index);
570 }
571
572 void markPSInputAllocated(unsigned Index) {
573 PSInputAddr |= 1 << Index;
574 }
575
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000576 void markPSInputEnabled(unsigned Index) {
577 PSInputEnable |= 1 << Index;
578 }
579
Marek Olsak8e9cc632016-01-13 17:23:09 +0000580 bool returnsVoid() const {
581 return ReturnsVoid;
582 }
583
584 void setIfReturnsVoid(bool Value) {
585 ReturnsVoid = Value;
586 }
587
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000588 /// \returns A pair of default/requested minimum/maximum flat work group sizes
589 /// for this function.
590 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
591 return FlatWorkGroupSizes;
592 }
593
594 /// \returns Default/requested minimum flat work group size for this function.
595 unsigned getMinFlatWorkGroupSize() const {
596 return FlatWorkGroupSizes.first;
597 }
598
599 /// \returns Default/requested maximum flat work group size for this function.
600 unsigned getMaxFlatWorkGroupSize() const {
601 return FlatWorkGroupSizes.second;
602 }
603
604 /// \returns A pair of default/requested minimum/maximum number of waves per
605 /// execution unit.
606 std::pair<unsigned, unsigned> getWavesPerEU() const {
607 return WavesPerEU;
608 }
609
610 /// \returns Default/requested minimum number of waves per execution unit.
611 unsigned getMinWavesPerEU() const {
612 return WavesPerEU.first;
613 }
614
615 /// \returns Default/requested maximum number of waves per execution unit.
616 unsigned getMaxWavesPerEU() const {
617 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000618 }
619
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000620 /// \returns SGPR used for \p Dim's work group ID.
621 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
622 switch (Dim) {
623 case 0:
624 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000625 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000626 case 1:
627 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000628 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000629 case 2:
630 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000631 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000632 }
633 llvm_unreachable("unexpected dimension");
634 }
635
636 /// \returns VGPR used for \p Dim' work item ID.
Tom Stellard44b30b42018-05-22 02:03:23 +0000637 unsigned getWorkItemIDVGPR(unsigned Dim) const;
Tom Stellard244891d2016-12-20 15:52:17 +0000638
Matt Arsenault161e2b42017-04-18 20:59:40 +0000639 unsigned getLDSWaveSpillSize() const {
640 return LDSWaveSpillSize;
641 }
642
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000643 const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII,
644 const Value *BufferRsrc) {
645 assert(BufferRsrc);
646 auto PSV = BufferPSVs.try_emplace(
647 BufferRsrc,
648 llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII));
649 return PSV.first->second.get();
Tom Stellard6f9ef142016-12-20 17:19:44 +0000650 }
651
Matt Arsenault905f3512017-12-29 17:18:14 +0000652 const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII,
653 const Value *ImgRsrc) {
654 assert(ImgRsrc);
655 auto PSV = ImagePSVs.try_emplace(
656 ImgRsrc,
657 llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII));
658 return PSV.first->second.get();
Tom Stellard244891d2016-12-20 15:52:17 +0000659 }
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000660
661 unsigned getOccupancy() const {
662 return Occupancy;
663 }
664
665 unsigned getMinAllowedOccupancy() const {
666 if (!isMemoryBound() && !needsWaveLimiter())
667 return Occupancy;
668 return (Occupancy < 4) ? Occupancy : 4;
669 }
670
671 void limitOccupancy(const MachineFunction &MF);
672
673 void limitOccupancy(unsigned Limit) {
674 if (Occupancy > Limit)
675 Occupancy = Limit;
676 }
677
678 void increaseOccupancy(const MachineFunction &MF, unsigned Limit) {
679 if (Occupancy < Limit)
680 Occupancy = Limit;
681 limitOccupancy(MF);
682 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000683};
684
Eugene Zelenko66203762017-01-21 00:53:49 +0000685} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000686
Eugene Zelenko66203762017-01-21 00:53:49 +0000687#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H