blob: ce103dcc31b6f67678130d775b31c0119e839282 [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
Marek Olsakfccabaf2016-01-13 11:45:36 +0000151 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000152 unsigned PSInputAddr = 0;
153 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000154
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000155 /// Number of bytes of arguments this function has on the stack. If the callee
156 /// is expected to restore the argument stack this should be a multiple of 16,
157 /// all usable during a tail call.
158 ///
159 /// The alternative would forbid tail call optimisation in some cases: if we
160 /// want to transfer control from a function with 8-bytes of stack-argument
161 /// space to a function with 16-bytes then misalignment of this value would
162 /// make a stack adjustment necessary, which could not be undone by the
163 /// callee.
164 unsigned BytesInStackArgArea = 0;
165
Eugene Zelenko59e12822017-08-08 00:47:13 +0000166 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000167
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000168 // A pair of default/requested minimum/maximum flat work group sizes.
169 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000170 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000171
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000172 // A pair of default/requested minimum/maximum number of waves per execution
173 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000174 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000175
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000176 DenseMap<const Value *,
177 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
Matt Arsenault905f3512017-12-29 17:18:14 +0000178 DenseMap<const Value *,
179 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
180
Matt Arsenault161e2b42017-04-18 20:59:40 +0000181private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000182 unsigned LDSWaveSpillSize = 0;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000183 unsigned NumUserSGPRs = 0;
184 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000185
Eugene Zelenko59e12822017-08-08 00:47:13 +0000186 bool HasSpilledSGPRs = false;
187 bool HasSpilledVGPRs = false;
188 bool HasNonSpillStackObjects = false;
Matt Arsenault03ae3992018-03-29 21:30:06 +0000189 bool IsStackRealigned = false;
Tom Stellard96468902014-09-24 01:33:17 +0000190
Eugene Zelenko59e12822017-08-08 00:47:13 +0000191 unsigned NumSpilledSGPRs = 0;
192 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000193
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000194 // Feature bits required for inputs passed in user SGPRs.
195 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000196 bool DispatchPtr : 1;
197 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000198 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000199 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000200 bool FlatScratchInit : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000201
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000202 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000203 bool WorkGroupIDX : 1; // Always initialized.
204 bool WorkGroupIDY : 1;
205 bool WorkGroupIDZ : 1;
206 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000207 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000208
209 bool WorkItemIDX : 1; // Always initialized.
210 bool WorkItemIDY : 1;
211 bool WorkItemIDZ : 1;
212
Tom Stellard2f3f9852017-01-25 01:25:13 +0000213 // Private memory buffer
214 // Compute directly in sgpr[0:1]
215 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000216 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000217
Matt Arsenault9166ce82017-07-28 15:52:08 +0000218 // Pointer to where the ABI inserts special kernel arguments separate from the
219 // user arguments. This is an offset from the KernargSegmentPtr.
220 bool ImplicitArgPtr : 1;
221
Tim Renouf13229152017-09-29 09:49:35 +0000222 // The hard-wired high half of the address of the global information table
223 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
224 // current hardware only allows a 16 bit value.
225 unsigned GITPtrHigh;
226
Matt Arsenault923712b2018-02-09 16:57:57 +0000227 unsigned HighBitsOf32BitAddress;
228
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000229 // Current recorded maximum possible occupancy.
230 unsigned Occupancy;
231
Tom Stellard44b30b42018-05-22 02:03:23 +0000232 MCPhysReg getNextUserSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000233
Tom Stellard44b30b42018-05-22 02:03:23 +0000234 MCPhysReg getNextSystemSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000235
Matt Arsenault49affb82015-11-25 20:55:12 +0000236public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000237 struct SpilledReg {
Tom Stellard44b30b42018-05-22 02:03:23 +0000238 unsigned VGPR = 0;
Eugene Zelenko66203762017-01-21 00:53:49 +0000239 int Lane = -1;
240
241 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000242 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000243
Tom Stellardc149dc02013-11-27 21:23:35 +0000244 bool hasLane() { return Lane != -1;}
Tom Stellard44b30b42018-05-22 02:03:23 +0000245 bool hasReg() { return VGPR != 0;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000246 };
247
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000248 struct SGPRSpillVGPRCSR {
249 // VGPR used for SGPR spills
250 unsigned VGPR;
251
252 // If the VGPR is a CSR, the stack slot used to save/restore it in the
253 // prolog/epilog.
254 Optional<int> FI;
255
Eugene Zelenko59e12822017-08-08 00:47:13 +0000256 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000257 };
258
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000259private:
260 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000261 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000262
263 // Track VGPR + wave index for each subregister of the SGPR spilled to
264 // frameindex key.
265 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
266 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000267 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000268
269public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000270 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000271
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000272 bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI);
273
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000274 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
275 auto I = SGPRToVGPRSpills.find(FrameIndex);
276 return (I == SGPRToVGPRSpills.end()) ?
277 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
278 }
279
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000280 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
281 return SpillVGPRs;
282 }
283
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000284 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
285 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
286
Tom Stellard44b30b42018-05-22 02:03:23 +0000287 bool hasCalculatedTID() const { return TIDReg != 0; };
288 unsigned getTIDReg() const { return TIDReg; };
Tom Stellard96468902014-09-24 01:33:17 +0000289 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000290
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000291 unsigned getBytesInStackArgArea() const {
292 return BytesInStackArgArea;
293 }
294
295 void setBytesInStackArgArea(unsigned Bytes) {
296 BytesInStackArgArea = Bytes;
297 }
298
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000299 // Add user SGPRs.
300 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
301 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
302 unsigned addQueuePtr(const SIRegisterInfo &TRI);
303 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000304 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000305 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000306 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000307
308 // Add system SGPRs.
309 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000310 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000311 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000312 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000313 }
314
315 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000316 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000317 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000318 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000319 }
320
321 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000322 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000323 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000324 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000325 }
326
327 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000328 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000329 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000330 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000331 }
332
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000333 // Add special VGPR inputs
334 void setWorkItemIDX(ArgDescriptor Arg) {
335 ArgInfo.WorkItemIDX = Arg;
336 }
337
338 void setWorkItemIDY(ArgDescriptor Arg) {
339 ArgInfo.WorkItemIDY = Arg;
340 }
341
342 void setWorkItemIDZ(ArgDescriptor Arg) {
343 ArgInfo.WorkItemIDZ = Arg;
344 }
345
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000346 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000347 ArgInfo.PrivateSegmentWaveByteOffset
348 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000349 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000350 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000351 }
352
Tom Stellardf110f8f2016-04-14 16:27:03 +0000353 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000354 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000355 }
356
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000357 bool hasPrivateSegmentBuffer() const {
358 return PrivateSegmentBuffer;
359 }
360
Matt Arsenault49affb82015-11-25 20:55:12 +0000361 bool hasDispatchPtr() const {
362 return DispatchPtr;
363 }
364
365 bool hasQueuePtr() const {
366 return QueuePtr;
367 }
368
Matt Arsenault49affb82015-11-25 20:55:12 +0000369 bool hasKernargSegmentPtr() const {
370 return KernargSegmentPtr;
371 }
372
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000373 bool hasDispatchID() const {
374 return DispatchID;
375 }
376
Matt Arsenault49affb82015-11-25 20:55:12 +0000377 bool hasFlatScratchInit() const {
378 return FlatScratchInit;
379 }
380
Matt Arsenault49affb82015-11-25 20:55:12 +0000381 bool hasWorkGroupIDX() const {
382 return WorkGroupIDX;
383 }
384
385 bool hasWorkGroupIDY() const {
386 return WorkGroupIDY;
387 }
388
389 bool hasWorkGroupIDZ() const {
390 return WorkGroupIDZ;
391 }
392
393 bool hasWorkGroupInfo() const {
394 return WorkGroupInfo;
395 }
396
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000397 bool hasPrivateSegmentWaveByteOffset() const {
398 return PrivateSegmentWaveByteOffset;
399 }
400
Matt Arsenault49affb82015-11-25 20:55:12 +0000401 bool hasWorkItemIDX() const {
402 return WorkItemIDX;
403 }
404
405 bool hasWorkItemIDY() const {
406 return WorkItemIDY;
407 }
408
409 bool hasWorkItemIDZ() const {
410 return WorkItemIDZ;
411 }
412
Matt Arsenault9166ce82017-07-28 15:52:08 +0000413 bool hasImplicitArgPtr() const {
414 return ImplicitArgPtr;
415 }
416
Matt Arsenault10fc0622017-06-26 03:01:31 +0000417 bool hasImplicitBufferPtr() const {
418 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000419 }
420
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000421 AMDGPUFunctionArgInfo &getArgInfo() {
422 return ArgInfo;
423 }
424
425 const AMDGPUFunctionArgInfo &getArgInfo() const {
426 return ArgInfo;
427 }
428
429 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
430 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
431 return ArgInfo.getPreloadedValue(Value);
432 }
433
434 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
435 return ArgInfo.getPreloadedValue(Value).first->getRegister();
436 }
437
Tim Renouf13229152017-09-29 09:49:35 +0000438 unsigned getGITPtrHigh() const {
439 return GITPtrHigh;
440 }
441
Matt Arsenault923712b2018-02-09 16:57:57 +0000442 unsigned get32BitAddressHighBits() const {
443 return HighBitsOf32BitAddress;
444 }
445
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000446 unsigned getNumUserSGPRs() const {
447 return NumUserSGPRs;
448 }
449
450 unsigned getNumPreloadedSGPRs() const {
451 return NumUserSGPRs + NumSystemSGPRs;
452 }
453
454 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000455 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000456 }
457
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000458 /// Returns the physical register reserved for use as the resource
Matt Arsenault49affb82015-11-25 20:55:12 +0000459 /// descriptor for scratch accesses.
460 unsigned getScratchRSrcReg() const {
461 return ScratchRSrcReg;
462 }
463
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000464 void setScratchRSrcReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000465 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000466 ScratchRSrcReg = Reg;
467 }
468
469 unsigned getScratchWaveOffsetReg() const {
470 return ScratchWaveOffsetReg;
471 }
472
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000473 unsigned getFrameOffsetReg() const {
474 return FrameOffsetReg;
475 }
476
477 void setStackPtrOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000478 assert(Reg != 0 && "Should never be unset");
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000479 StackPtrOffsetReg = Reg;
480 }
481
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000482 // Note the unset value for this is AMDGPU::SP_REG rather than
483 // NoRegister. This is mostly a workaround for MIR tests where state that
484 // can't be directly computed from the function is not preserved in serialized
485 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000486 unsigned getStackPtrOffsetReg() const {
487 return StackPtrOffsetReg;
488 }
489
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000490 void setScratchWaveOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000491 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000492 ScratchWaveOffsetReg = Reg;
Matt Arsenault2b1f9aa2017-05-17 21:56:25 +0000493 if (isEntryFunction())
494 FrameOffsetReg = ScratchWaveOffsetReg;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000495 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000496
Matt Arsenault99c14522016-04-25 19:27:24 +0000497 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000498 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000499 }
500
Matt Arsenault10fc0622017-06-26 03:01:31 +0000501 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000502 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000503 }
504
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000505 bool hasSpilledSGPRs() const {
506 return HasSpilledSGPRs;
507 }
508
509 void setHasSpilledSGPRs(bool Spill = true) {
510 HasSpilledSGPRs = Spill;
511 }
512
513 bool hasSpilledVGPRs() const {
514 return HasSpilledVGPRs;
515 }
516
517 void setHasSpilledVGPRs(bool Spill = true) {
518 HasSpilledVGPRs = Spill;
519 }
Tom Stellard96468902014-09-24 01:33:17 +0000520
Matt Arsenault296b8492016-02-12 06:31:30 +0000521 bool hasNonSpillStackObjects() const {
522 return HasNonSpillStackObjects;
523 }
524
525 void setHasNonSpillStackObjects(bool StackObject = true) {
526 HasNonSpillStackObjects = StackObject;
527 }
528
Matt Arsenault03ae3992018-03-29 21:30:06 +0000529 bool isStackRealigned() const {
530 return IsStackRealigned;
531 }
532
533 void setIsStackRealigned(bool Realigned = true) {
534 IsStackRealigned = Realigned;
535 }
536
Marek Olsak0532c192016-07-13 17:35:15 +0000537 unsigned getNumSpilledSGPRs() const {
538 return NumSpilledSGPRs;
539 }
540
541 unsigned getNumSpilledVGPRs() const {
542 return NumSpilledVGPRs;
543 }
544
545 void addToSpilledSGPRs(unsigned num) {
546 NumSpilledSGPRs += num;
547 }
548
549 void addToSpilledVGPRs(unsigned num) {
550 NumSpilledVGPRs += num;
551 }
552
Marek Olsakfccabaf2016-01-13 11:45:36 +0000553 unsigned getPSInputAddr() const {
554 return PSInputAddr;
555 }
556
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000557 unsigned getPSInputEnable() const {
558 return PSInputEnable;
559 }
560
Marek Olsakfccabaf2016-01-13 11:45:36 +0000561 bool isPSInputAllocated(unsigned Index) const {
562 return PSInputAddr & (1 << Index);
563 }
564
565 void markPSInputAllocated(unsigned Index) {
566 PSInputAddr |= 1 << Index;
567 }
568
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000569 void markPSInputEnabled(unsigned Index) {
570 PSInputEnable |= 1 << Index;
571 }
572
Marek Olsak8e9cc632016-01-13 17:23:09 +0000573 bool returnsVoid() const {
574 return ReturnsVoid;
575 }
576
577 void setIfReturnsVoid(bool Value) {
578 ReturnsVoid = Value;
579 }
580
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000581 /// \returns A pair of default/requested minimum/maximum flat work group sizes
582 /// for this function.
583 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
584 return FlatWorkGroupSizes;
585 }
586
587 /// \returns Default/requested minimum flat work group size for this function.
588 unsigned getMinFlatWorkGroupSize() const {
589 return FlatWorkGroupSizes.first;
590 }
591
592 /// \returns Default/requested maximum flat work group size for this function.
593 unsigned getMaxFlatWorkGroupSize() const {
594 return FlatWorkGroupSizes.second;
595 }
596
597 /// \returns A pair of default/requested minimum/maximum number of waves per
598 /// execution unit.
599 std::pair<unsigned, unsigned> getWavesPerEU() const {
600 return WavesPerEU;
601 }
602
603 /// \returns Default/requested minimum number of waves per execution unit.
604 unsigned getMinWavesPerEU() const {
605 return WavesPerEU.first;
606 }
607
608 /// \returns Default/requested maximum number of waves per execution unit.
609 unsigned getMaxWavesPerEU() const {
610 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000611 }
612
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000613 /// \returns SGPR used for \p Dim's work group ID.
614 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
615 switch (Dim) {
616 case 0:
617 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000618 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000619 case 1:
620 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000621 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000622 case 2:
623 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000624 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000625 }
626 llvm_unreachable("unexpected dimension");
627 }
628
629 /// \returns VGPR used for \p Dim' work item ID.
Tom Stellard44b30b42018-05-22 02:03:23 +0000630 unsigned getWorkItemIDVGPR(unsigned Dim) const;
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 }
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000653
654 unsigned getOccupancy() const {
655 return Occupancy;
656 }
657
658 unsigned getMinAllowedOccupancy() const {
659 if (!isMemoryBound() && !needsWaveLimiter())
660 return Occupancy;
661 return (Occupancy < 4) ? Occupancy : 4;
662 }
663
664 void limitOccupancy(const MachineFunction &MF);
665
666 void limitOccupancy(unsigned Limit) {
667 if (Occupancy > Limit)
668 Occupancy = Limit;
669 }
670
671 void increaseOccupancy(const MachineFunction &MF, unsigned Limit) {
672 if (Occupancy < Limit)
673 Occupancy = Limit;
674 limitOccupancy(MF);
675 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000676};
677
Eugene Zelenko66203762017-01-21 00:53:49 +0000678} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000679
Eugene Zelenko66203762017-01-21 00:53:49 +0000680#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H