blob: bfe6182a7c1cd3735a0e9ce18d63cb3c6380517e [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"
Neil Henning0a30f332019-04-01 15:19:52 +000025#include "llvm/ADT/SparseBitVector.h"
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +000026#include "llvm/CodeGen/MIRYamlMapping.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000027#include "llvm/CodeGen/PseudoSourceValue.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000028#include "llvm/CodeGen/TargetInstrInfo.h"
Eugene Zelenko66203762017-01-21 00:53:49 +000029#include "llvm/MC/MCRegisterInfo.h"
30#include "llvm/Support/ErrorHandling.h"
NAKAMURA Takumi5cbd41e2016-06-27 10:26:43 +000031#include <array>
Eugene Zelenko66203762017-01-21 00:53:49 +000032#include <cassert>
Eugene Zelenko66203762017-01-21 00:53:49 +000033#include <utility>
Eugene Zelenko59e12822017-08-08 00:47:13 +000034#include <vector>
Tom Stellard75aadc22012-12-11 21:25:42 +000035
36namespace llvm {
37
Eugene Zelenko59e12822017-08-08 00:47:13 +000038class MachineFrameInfo;
39class MachineFunction;
40class TargetRegisterClass;
41
Tom Stellard244891d2016-12-20 15:52:17 +000042class AMDGPUImagePseudoSourceValue : public PseudoSourceValue {
43public:
Matt Arsenault905f3512017-12-29 17:18:14 +000044 // TODO: Is the img rsrc useful?
Jan Sjodin312ccf72017-09-14 20:53:51 +000045 explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII) :
Matt Arsenault905f3512017-12-29 17:18:14 +000046 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) {}
Tom Stellard244891d2016-12-20 15:52:17 +000047
48 bool isConstant(const MachineFrameInfo *) const override {
49 // This should probably be true for most images, but we will start by being
50 // conservative.
51 return false;
52 }
53
54 bool isAliased(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000055 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000056 }
57
Eugene Zelenko59e12822017-08-08 00:47:13 +000058 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000059 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000060 }
61};
62
Tom Stellard6f9ef142016-12-20 17:19:44 +000063class AMDGPUBufferPseudoSourceValue : public PseudoSourceValue {
64public:
Jan Sjodin312ccf72017-09-14 20:53:51 +000065 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII) :
66 PseudoSourceValue(PseudoSourceValue::TargetCustom, TII) { }
Tom Stellard6f9ef142016-12-20 17:19:44 +000067
68 bool isConstant(const MachineFrameInfo *) const override {
69 // This should probably be true for most images, but we will start by being
70 // conservative.
71 return false;
72 }
73
74 bool isAliased(const MachineFrameInfo *) const override {
Tim Renouf8234b482018-02-20 10:03:38 +000075 return true;
Tom Stellard6f9ef142016-12-20 17:19:44 +000076 }
77
Eugene Zelenko59e12822017-08-08 00:47:13 +000078 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf8234b482018-02-20 10:03:38 +000079 return true;
Tom Stellard6f9ef142016-12-20 17:19:44 +000080 }
81};
Tom Stellard244891d2016-12-20 15:52:17 +000082
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +000083namespace yaml {
84
85struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo {
86 uint64_t ExplicitKernArgSize = 0;
87 unsigned MaxKernArgAlign = 0;
88 unsigned LDSSize = 0;
89 bool IsEntryFunction = false;
90 bool NoSignedZerosFPMath = false;
91 bool MemoryBound = false;
92 bool WaveLimiter = false;
93
94 StringValue ScratchRSrcReg = "$private_rsrc_reg";
95 StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg";
96 StringValue FrameOffsetReg = "$fp_reg";
97 StringValue StackPtrOffsetReg = "$sp_reg";
98
99 SIMachineFunctionInfo() = default;
100 SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &,
101 const TargetRegisterInfo &TRI);
102
103 void mappingImpl(yaml::IO &YamlIO) override;
104 ~SIMachineFunctionInfo() = default;
105};
106
107template <> struct MappingTraits<SIMachineFunctionInfo> {
108 static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) {
109 YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize,
110 UINT64_C(0));
111 YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u);
112 YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u);
113 YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false);
114 YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false);
115 YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false);
116 YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false);
117 YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg,
118 StringValue("$private_rsrc_reg"));
119 YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg,
120 StringValue("$scratch_wave_offset_reg"));
121 YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg,
122 StringValue("$fp_reg"));
123 YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg,
124 StringValue("$sp_reg"));
125 }
126};
127
128} // end namespace yaml
129
Tom Stellard75aadc22012-12-11 21:25:42 +0000130/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
131/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +0000132class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000133 friend class GCNTargetMachine;
134
Eugene Zelenko59e12822017-08-08 00:47:13 +0000135 unsigned TIDReg = AMDGPU::NoRegister;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000136
137 // Registers that may be reserved for spilling purposes. These may be the same
138 // as the input registers.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000139 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
140 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000141
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000142 // This is the current function's incremented size from the kernel's scratch
143 // wave offset register. For an entry function, this is exactly the same as
144 // the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000145 unsigned FrameOffsetReg = AMDGPU::FP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000146
147 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000148 unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000149
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000150 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000151
Matt Arsenault055e4dc2019-03-29 19:14:54 +0000152 // State of MODE register, assumed FP mode.
153 AMDGPU::SIModeRegisterDefaults Mode;
154
Marek Olsakfccabaf2016-01-13 11:45:36 +0000155 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000156 unsigned PSInputAddr = 0;
157 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000158
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000159 /// Number of bytes of arguments this function has on the stack. If the callee
160 /// is expected to restore the argument stack this should be a multiple of 16,
161 /// all usable during a tail call.
162 ///
163 /// The alternative would forbid tail call optimisation in some cases: if we
164 /// want to transfer control from a function with 8-bytes of stack-argument
165 /// space to a function with 16-bytes then misalignment of this value would
166 /// make a stack adjustment necessary, which could not be undone by the
167 /// callee.
168 unsigned BytesInStackArgArea = 0;
169
Eugene Zelenko59e12822017-08-08 00:47:13 +0000170 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000171
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000172 // A pair of default/requested minimum/maximum flat work group sizes.
173 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000174 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000175
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000176 // A pair of default/requested minimum/maximum number of waves per execution
177 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000178 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000179
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000180 DenseMap<const Value *,
181 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
Matt Arsenault905f3512017-12-29 17:18:14 +0000182 DenseMap<const Value *,
183 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
184
Matt Arsenault161e2b42017-04-18 20:59:40 +0000185private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000186 unsigned LDSWaveSpillSize = 0;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000187 unsigned NumUserSGPRs = 0;
188 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000189
Eugene Zelenko59e12822017-08-08 00:47:13 +0000190 bool HasSpilledSGPRs = false;
191 bool HasSpilledVGPRs = false;
192 bool HasNonSpillStackObjects = false;
Matt Arsenault03ae3992018-03-29 21:30:06 +0000193 bool IsStackRealigned = false;
Tom Stellard96468902014-09-24 01:33:17 +0000194
Eugene Zelenko59e12822017-08-08 00:47:13 +0000195 unsigned NumSpilledSGPRs = 0;
196 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000197
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000198 // Feature bits required for inputs passed in user SGPRs.
199 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000200 bool DispatchPtr : 1;
201 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000202 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000203 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000204 bool FlatScratchInit : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000205
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000206 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000207 bool WorkGroupIDX : 1; // Always initialized.
208 bool WorkGroupIDY : 1;
209 bool WorkGroupIDZ : 1;
210 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000211 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000212
213 bool WorkItemIDX : 1; // Always initialized.
214 bool WorkItemIDY : 1;
215 bool WorkItemIDZ : 1;
216
Tom Stellard2f3f9852017-01-25 01:25:13 +0000217 // Private memory buffer
218 // Compute directly in sgpr[0:1]
219 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000220 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000221
Matt Arsenault9166ce82017-07-28 15:52:08 +0000222 // Pointer to where the ABI inserts special kernel arguments separate from the
223 // user arguments. This is an offset from the KernargSegmentPtr.
224 bool ImplicitArgPtr : 1;
225
Tim Renouf13229152017-09-29 09:49:35 +0000226 // The hard-wired high half of the address of the global information table
227 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
228 // current hardware only allows a 16 bit value.
229 unsigned GITPtrHigh;
230
Matt Arsenault923712b2018-02-09 16:57:57 +0000231 unsigned HighBitsOf32BitAddress;
232
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000233 // Current recorded maximum possible occupancy.
234 unsigned Occupancy;
235
Tom Stellard44b30b42018-05-22 02:03:23 +0000236 MCPhysReg getNextUserSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000237
Tom Stellard44b30b42018-05-22 02:03:23 +0000238 MCPhysReg getNextSystemSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000239
Matt Arsenault49affb82015-11-25 20:55:12 +0000240public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000241 struct SpilledReg {
Tom Stellard44b30b42018-05-22 02:03:23 +0000242 unsigned VGPR = 0;
Eugene Zelenko66203762017-01-21 00:53:49 +0000243 int Lane = -1;
244
245 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000246 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000247
Tom Stellardc149dc02013-11-27 21:23:35 +0000248 bool hasLane() { return Lane != -1;}
Tom Stellard44b30b42018-05-22 02:03:23 +0000249 bool hasReg() { return VGPR != 0;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000250 };
251
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000252 struct SGPRSpillVGPRCSR {
253 // VGPR used for SGPR spills
254 unsigned VGPR;
255
256 // If the VGPR is a CSR, the stack slot used to save/restore it in the
257 // prolog/epilog.
258 Optional<int> FI;
259
Eugene Zelenko59e12822017-08-08 00:47:13 +0000260 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000261 };
262
Neil Henning0a30f332019-04-01 15:19:52 +0000263 SparseBitVector<> WWMReservedRegs;
264
265 void ReserveWWMRegister(unsigned reg) { WWMReservedRegs.set(reg); }
266
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000267private:
268 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000269 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000270
271 // Track VGPR + wave index for each subregister of the SGPR spilled to
272 // frameindex key.
273 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
274 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000275 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000276
277public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000278 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000279
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000280 bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI);
281
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000282 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
283 auto I = SGPRToVGPRSpills.find(FrameIndex);
284 return (I == SGPRToVGPRSpills.end()) ?
285 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
286 }
287
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000288 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
289 return SpillVGPRs;
290 }
291
Matt Arsenault055e4dc2019-03-29 19:14:54 +0000292 AMDGPU::SIModeRegisterDefaults getMode() const {
293 return Mode;
294 }
295
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000296 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
297 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
298
Tom Stellard44b30b42018-05-22 02:03:23 +0000299 bool hasCalculatedTID() const { return TIDReg != 0; };
300 unsigned getTIDReg() const { return TIDReg; };
Tom Stellard96468902014-09-24 01:33:17 +0000301 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000302
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000303 unsigned getBytesInStackArgArea() const {
304 return BytesInStackArgArea;
305 }
306
307 void setBytesInStackArgArea(unsigned Bytes) {
308 BytesInStackArgArea = Bytes;
309 }
310
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000311 // Add user SGPRs.
312 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
313 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
314 unsigned addQueuePtr(const SIRegisterInfo &TRI);
315 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000316 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000317 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000318 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000319
320 // Add system SGPRs.
321 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000322 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000323 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000324 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000325 }
326
327 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000328 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000329 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000330 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000331 }
332
333 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000334 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000335 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000336 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000337 }
338
339 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000340 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000341 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000342 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000343 }
344
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000345 // Add special VGPR inputs
346 void setWorkItemIDX(ArgDescriptor Arg) {
347 ArgInfo.WorkItemIDX = Arg;
348 }
349
350 void setWorkItemIDY(ArgDescriptor Arg) {
351 ArgInfo.WorkItemIDY = Arg;
352 }
353
354 void setWorkItemIDZ(ArgDescriptor Arg) {
355 ArgInfo.WorkItemIDZ = Arg;
356 }
357
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000358 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000359 ArgInfo.PrivateSegmentWaveByteOffset
360 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000361 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000362 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000363 }
364
Tom Stellardf110f8f2016-04-14 16:27:03 +0000365 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000366 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000367 }
368
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000369 bool hasPrivateSegmentBuffer() const {
370 return PrivateSegmentBuffer;
371 }
372
Matt Arsenault49affb82015-11-25 20:55:12 +0000373 bool hasDispatchPtr() const {
374 return DispatchPtr;
375 }
376
377 bool hasQueuePtr() const {
378 return QueuePtr;
379 }
380
Matt Arsenault49affb82015-11-25 20:55:12 +0000381 bool hasKernargSegmentPtr() const {
382 return KernargSegmentPtr;
383 }
384
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000385 bool hasDispatchID() const {
386 return DispatchID;
387 }
388
Matt Arsenault49affb82015-11-25 20:55:12 +0000389 bool hasFlatScratchInit() const {
390 return FlatScratchInit;
391 }
392
Matt Arsenault49affb82015-11-25 20:55:12 +0000393 bool hasWorkGroupIDX() const {
394 return WorkGroupIDX;
395 }
396
397 bool hasWorkGroupIDY() const {
398 return WorkGroupIDY;
399 }
400
401 bool hasWorkGroupIDZ() const {
402 return WorkGroupIDZ;
403 }
404
405 bool hasWorkGroupInfo() const {
406 return WorkGroupInfo;
407 }
408
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000409 bool hasPrivateSegmentWaveByteOffset() const {
410 return PrivateSegmentWaveByteOffset;
411 }
412
Matt Arsenault49affb82015-11-25 20:55:12 +0000413 bool hasWorkItemIDX() const {
414 return WorkItemIDX;
415 }
416
417 bool hasWorkItemIDY() const {
418 return WorkItemIDY;
419 }
420
421 bool hasWorkItemIDZ() const {
422 return WorkItemIDZ;
423 }
424
Matt Arsenault9166ce82017-07-28 15:52:08 +0000425 bool hasImplicitArgPtr() const {
426 return ImplicitArgPtr;
427 }
428
Matt Arsenault10fc0622017-06-26 03:01:31 +0000429 bool hasImplicitBufferPtr() const {
430 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000431 }
432
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000433 AMDGPUFunctionArgInfo &getArgInfo() {
434 return ArgInfo;
435 }
436
437 const AMDGPUFunctionArgInfo &getArgInfo() const {
438 return ArgInfo;
439 }
440
441 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
442 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
443 return ArgInfo.getPreloadedValue(Value);
444 }
445
446 unsigned getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
Matt Arsenaultb812b7a2019-06-05 22:20:47 +0000447 auto Arg = ArgInfo.getPreloadedValue(Value).first;
448 return Arg ? Arg->getRegister() : 0;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000449 }
450
Tim Renouf13229152017-09-29 09:49:35 +0000451 unsigned getGITPtrHigh() const {
452 return GITPtrHigh;
453 }
454
Matt Arsenault923712b2018-02-09 16:57:57 +0000455 unsigned get32BitAddressHighBits() const {
456 return HighBitsOf32BitAddress;
457 }
458
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000459 unsigned getNumUserSGPRs() const {
460 return NumUserSGPRs;
461 }
462
463 unsigned getNumPreloadedSGPRs() const {
464 return NumUserSGPRs + NumSystemSGPRs;
465 }
466
467 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000468 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000469 }
470
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000471 /// Returns the physical register reserved for use as the resource
Matt Arsenault49affb82015-11-25 20:55:12 +0000472 /// descriptor for scratch accesses.
473 unsigned getScratchRSrcReg() const {
474 return ScratchRSrcReg;
475 }
476
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000477 void setScratchRSrcReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000478 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000479 ScratchRSrcReg = Reg;
480 }
481
482 unsigned getScratchWaveOffsetReg() const {
483 return ScratchWaveOffsetReg;
484 }
485
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000486 unsigned getFrameOffsetReg() const {
487 return FrameOffsetReg;
488 }
489
Matt Arsenaultb812b7a2019-06-05 22:20:47 +0000490 void setFrameOffsetReg(unsigned Reg) {
491 assert(Reg != 0 && "Should never be unset");
492 FrameOffsetReg = Reg;
493 }
494
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000495 void setStackPtrOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000496 assert(Reg != 0 && "Should never be unset");
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000497 StackPtrOffsetReg = Reg;
498 }
499
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000500 // Note the unset value for this is AMDGPU::SP_REG rather than
501 // NoRegister. This is mostly a workaround for MIR tests where state that
502 // can't be directly computed from the function is not preserved in serialized
503 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000504 unsigned getStackPtrOffsetReg() const {
505 return StackPtrOffsetReg;
506 }
507
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000508 void setScratchWaveOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000509 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000510 ScratchWaveOffsetReg = Reg;
511 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000512
Matt Arsenault99c14522016-04-25 19:27:24 +0000513 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000514 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000515 }
516
Matt Arsenault10fc0622017-06-26 03:01:31 +0000517 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000518 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000519 }
520
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000521 bool hasSpilledSGPRs() const {
522 return HasSpilledSGPRs;
523 }
524
525 void setHasSpilledSGPRs(bool Spill = true) {
526 HasSpilledSGPRs = Spill;
527 }
528
529 bool hasSpilledVGPRs() const {
530 return HasSpilledVGPRs;
531 }
532
533 void setHasSpilledVGPRs(bool Spill = true) {
534 HasSpilledVGPRs = Spill;
535 }
Tom Stellard96468902014-09-24 01:33:17 +0000536
Matt Arsenault296b8492016-02-12 06:31:30 +0000537 bool hasNonSpillStackObjects() const {
538 return HasNonSpillStackObjects;
539 }
540
541 void setHasNonSpillStackObjects(bool StackObject = true) {
542 HasNonSpillStackObjects = StackObject;
543 }
544
Matt Arsenault03ae3992018-03-29 21:30:06 +0000545 bool isStackRealigned() const {
546 return IsStackRealigned;
547 }
548
549 void setIsStackRealigned(bool Realigned = true) {
550 IsStackRealigned = Realigned;
551 }
552
Marek Olsak0532c192016-07-13 17:35:15 +0000553 unsigned getNumSpilledSGPRs() const {
554 return NumSpilledSGPRs;
555 }
556
557 unsigned getNumSpilledVGPRs() const {
558 return NumSpilledVGPRs;
559 }
560
561 void addToSpilledSGPRs(unsigned num) {
562 NumSpilledSGPRs += num;
563 }
564
565 void addToSpilledVGPRs(unsigned num) {
566 NumSpilledVGPRs += num;
567 }
568
Marek Olsakfccabaf2016-01-13 11:45:36 +0000569 unsigned getPSInputAddr() const {
570 return PSInputAddr;
571 }
572
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000573 unsigned getPSInputEnable() const {
574 return PSInputEnable;
575 }
576
Marek Olsakfccabaf2016-01-13 11:45:36 +0000577 bool isPSInputAllocated(unsigned Index) const {
578 return PSInputAddr & (1 << Index);
579 }
580
581 void markPSInputAllocated(unsigned Index) {
582 PSInputAddr |= 1 << Index;
583 }
584
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000585 void markPSInputEnabled(unsigned Index) {
586 PSInputEnable |= 1 << Index;
587 }
588
Marek Olsak8e9cc632016-01-13 17:23:09 +0000589 bool returnsVoid() const {
590 return ReturnsVoid;
591 }
592
593 void setIfReturnsVoid(bool Value) {
594 ReturnsVoid = Value;
595 }
596
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000597 /// \returns A pair of default/requested minimum/maximum flat work group sizes
598 /// for this function.
599 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
600 return FlatWorkGroupSizes;
601 }
602
603 /// \returns Default/requested minimum flat work group size for this function.
604 unsigned getMinFlatWorkGroupSize() const {
605 return FlatWorkGroupSizes.first;
606 }
607
608 /// \returns Default/requested maximum flat work group size for this function.
609 unsigned getMaxFlatWorkGroupSize() const {
610 return FlatWorkGroupSizes.second;
611 }
612
613 /// \returns A pair of default/requested minimum/maximum number of waves per
614 /// execution unit.
615 std::pair<unsigned, unsigned> getWavesPerEU() const {
616 return WavesPerEU;
617 }
618
619 /// \returns Default/requested minimum number of waves per execution unit.
620 unsigned getMinWavesPerEU() const {
621 return WavesPerEU.first;
622 }
623
624 /// \returns Default/requested maximum number of waves per execution unit.
625 unsigned getMaxWavesPerEU() const {
626 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000627 }
628
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000629 /// \returns SGPR used for \p Dim's work group ID.
630 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
631 switch (Dim) {
632 case 0:
633 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000634 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000635 case 1:
636 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000637 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000638 case 2:
639 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000640 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000641 }
642 llvm_unreachable("unexpected dimension");
643 }
644
645 /// \returns VGPR used for \p Dim' work item ID.
Tom Stellard44b30b42018-05-22 02:03:23 +0000646 unsigned getWorkItemIDVGPR(unsigned Dim) const;
Tom Stellard244891d2016-12-20 15:52:17 +0000647
Matt Arsenault161e2b42017-04-18 20:59:40 +0000648 unsigned getLDSWaveSpillSize() const {
649 return LDSWaveSpillSize;
650 }
651
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000652 const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII,
653 const Value *BufferRsrc) {
654 assert(BufferRsrc);
655 auto PSV = BufferPSVs.try_emplace(
656 BufferRsrc,
657 llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII));
658 return PSV.first->second.get();
Tom Stellard6f9ef142016-12-20 17:19:44 +0000659 }
660
Matt Arsenault905f3512017-12-29 17:18:14 +0000661 const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII,
662 const Value *ImgRsrc) {
663 assert(ImgRsrc);
664 auto PSV = ImagePSVs.try_emplace(
665 ImgRsrc,
666 llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII));
667 return PSV.first->second.get();
Tom Stellard244891d2016-12-20 15:52:17 +0000668 }
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000669
670 unsigned getOccupancy() const {
671 return Occupancy;
672 }
673
674 unsigned getMinAllowedOccupancy() const {
675 if (!isMemoryBound() && !needsWaveLimiter())
676 return Occupancy;
677 return (Occupancy < 4) ? Occupancy : 4;
678 }
679
680 void limitOccupancy(const MachineFunction &MF);
681
682 void limitOccupancy(unsigned Limit) {
683 if (Occupancy > Limit)
684 Occupancy = Limit;
685 }
686
687 void increaseOccupancy(const MachineFunction &MF, unsigned Limit) {
688 if (Occupancy < Limit)
689 Occupancy = Limit;
690 limitOccupancy(MF);
691 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000692};
693
Eugene Zelenko66203762017-01-21 00:53:49 +0000694} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000695
Eugene Zelenko66203762017-01-21 00:53:49 +0000696#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H