blob: 421541c5e28dd27a310bf0f7b7c60e456c8c5350 [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
Matt Arsenaulte683eba2019-06-17 13:52:15 +000042class AMDGPUPseudoSourceValue : public PseudoSourceValue {
Tom Stellard244891d2016-12-20 15:52:17 +000043public:
Matt Arsenaulte683eba2019-06-17 13:52:15 +000044 enum AMDGPUPSVKind : unsigned {
45 PSVBuffer = PseudoSourceValue::TargetCustom,
Matt Arsenault4d55d022019-06-19 19:55:27 +000046 PSVImage,
47 GWSResource
Matt Arsenaulte683eba2019-06-17 13:52:15 +000048 };
Tom Stellard244891d2016-12-20 15:52:17 +000049
Matt Arsenaulte683eba2019-06-17 13:52:15 +000050protected:
51 AMDGPUPseudoSourceValue(unsigned Kind, const TargetInstrInfo &TII)
52 : PseudoSourceValue(Kind, TII) {}
53
54public:
Tom Stellard244891d2016-12-20 15:52:17 +000055 bool isConstant(const MachineFrameInfo *) const override {
56 // This should probably be true for most images, but we will start by being
57 // conservative.
58 return false;
59 }
60
61 bool isAliased(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000062 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000063 }
64
Eugene Zelenko59e12822017-08-08 00:47:13 +000065 bool mayAlias(const MachineFrameInfo *) const override {
Tim Renouf75ced9d2018-01-12 22:57:24 +000066 return true;
Tom Stellard244891d2016-12-20 15:52:17 +000067 }
68};
69
Matt Arsenaulte683eba2019-06-17 13:52:15 +000070class AMDGPUBufferPseudoSourceValue final : public AMDGPUPseudoSourceValue {
Tom Stellard6f9ef142016-12-20 17:19:44 +000071public:
Matt Arsenaulte683eba2019-06-17 13:52:15 +000072 explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII)
73 : AMDGPUPseudoSourceValue(PSVBuffer, TII) {}
Tom Stellard6f9ef142016-12-20 17:19:44 +000074
Matt Arsenaulte683eba2019-06-17 13:52:15 +000075 static bool classof(const PseudoSourceValue *V) {
76 return V->kind() == PSVBuffer;
Tom Stellard6f9ef142016-12-20 17:19:44 +000077 }
Matt Arsenaulte683eba2019-06-17 13:52:15 +000078};
Tom Stellard6f9ef142016-12-20 17:19:44 +000079
Matt Arsenaulte683eba2019-06-17 13:52:15 +000080class AMDGPUImagePseudoSourceValue final : public AMDGPUPseudoSourceValue {
81public:
82 // TODO: Is the img rsrc useful?
83 explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII)
84 : AMDGPUPseudoSourceValue(PSVImage, TII) {}
Tom Stellard6f9ef142016-12-20 17:19:44 +000085
Matt Arsenaulte683eba2019-06-17 13:52:15 +000086 static bool classof(const PseudoSourceValue *V) {
87 return V->kind() == PSVImage;
Tom Stellard6f9ef142016-12-20 17:19:44 +000088 }
89};
Tom Stellard244891d2016-12-20 15:52:17 +000090
Matt Arsenault4d55d022019-06-19 19:55:27 +000091class AMDGPUGWSResourcePseudoSourceValue final : public AMDGPUPseudoSourceValue {
92public:
93 explicit AMDGPUGWSResourcePseudoSourceValue(const TargetInstrInfo &TII)
94 : AMDGPUPseudoSourceValue(GWSResource, TII) {}
95
96 static bool classof(const PseudoSourceValue *V) {
97 return V->kind() == GWSResource;
98 }
99
100 // These are inaccessible memory from IR.
101 bool isAliased(const MachineFrameInfo *) const override {
102 return false;
103 }
104
105 // These are inaccessible memory from IR.
106 bool mayAlias(const MachineFrameInfo *) const override {
107 return false;
108 }
109
110 void printCustom(raw_ostream &OS) const override {
111 OS << "GWSResource";
112 }
113};
114
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000115namespace yaml {
116
117struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo {
118 uint64_t ExplicitKernArgSize = 0;
119 unsigned MaxKernArgAlign = 0;
120 unsigned LDSSize = 0;
121 bool IsEntryFunction = false;
122 bool NoSignedZerosFPMath = false;
123 bool MemoryBound = false;
124 bool WaveLimiter = false;
125
126 StringValue ScratchRSrcReg = "$private_rsrc_reg";
127 StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg";
128 StringValue FrameOffsetReg = "$fp_reg";
129 StringValue StackPtrOffsetReg = "$sp_reg";
130
131 SIMachineFunctionInfo() = default;
132 SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &,
133 const TargetRegisterInfo &TRI);
134
135 void mappingImpl(yaml::IO &YamlIO) override;
136 ~SIMachineFunctionInfo() = default;
137};
138
139template <> struct MappingTraits<SIMachineFunctionInfo> {
140 static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) {
141 YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize,
142 UINT64_C(0));
143 YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u);
144 YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u);
145 YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false);
146 YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false);
147 YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false);
148 YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false);
149 YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg,
150 StringValue("$private_rsrc_reg"));
151 YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg,
152 StringValue("$scratch_wave_offset_reg"));
153 YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg,
154 StringValue("$fp_reg"));
155 YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg,
156 StringValue("$sp_reg"));
157 }
158};
159
160} // end namespace yaml
161
Tom Stellard75aadc22012-12-11 21:25:42 +0000162/// This class keeps track of the SPI_SP_INPUT_ADDR config register, which
163/// tells the hardware which interpolation parameters to load.
Matt Arsenault6b6a2c32016-03-11 08:00:27 +0000164class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000165 friend class GCNTargetMachine;
166
Eugene Zelenko59e12822017-08-08 00:47:13 +0000167 unsigned TIDReg = AMDGPU::NoRegister;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000168
169 // Registers that may be reserved for spilling purposes. These may be the same
170 // as the input registers.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000171 unsigned ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
172 unsigned ScratchWaveOffsetReg = AMDGPU::SCRATCH_WAVE_OFFSET_REG;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000173
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000174 // This is the current function's incremented size from the kernel's scratch
175 // wave offset register. For an entry function, this is exactly the same as
176 // the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000177 unsigned FrameOffsetReg = AMDGPU::FP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000178
179 // Top of the stack SGPR offset derived from the ScratchWaveOffsetReg.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000180 unsigned StackPtrOffsetReg = AMDGPU::SP_REG;
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000181
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000182 AMDGPUFunctionArgInfo ArgInfo;
Matt Arsenaulte15855d2017-07-17 22:35:50 +0000183
Matt Arsenault055e4dc2019-03-29 19:14:54 +0000184 // State of MODE register, assumed FP mode.
185 AMDGPU::SIModeRegisterDefaults Mode;
186
Marek Olsakfccabaf2016-01-13 11:45:36 +0000187 // Graphics info.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000188 unsigned PSInputAddr = 0;
189 unsigned PSInputEnable = 0;
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000190
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000191 /// Number of bytes of arguments this function has on the stack. If the callee
192 /// is expected to restore the argument stack this should be a multiple of 16,
193 /// all usable during a tail call.
194 ///
195 /// The alternative would forbid tail call optimisation in some cases: if we
196 /// want to transfer control from a function with 8-bytes of stack-argument
197 /// space to a function with 16-bytes then misalignment of this value would
198 /// make a stack adjustment necessary, which could not be undone by the
199 /// callee.
200 unsigned BytesInStackArgArea = 0;
201
Eugene Zelenko59e12822017-08-08 00:47:13 +0000202 bool ReturnsVoid = true;
Marek Olsakfccabaf2016-01-13 11:45:36 +0000203
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000204 // A pair of default/requested minimum/maximum flat work group sizes.
205 // Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000206 std::pair<unsigned, unsigned> FlatWorkGroupSizes = {0, 0};
Tom Stellard79a1fd72016-04-14 16:27:07 +0000207
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000208 // A pair of default/requested minimum/maximum number of waves per execution
209 // unit. Minimum - first, maximum - second.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000210 std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000211
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000212 DenseMap<const Value *,
213 std::unique_ptr<const AMDGPUBufferPseudoSourceValue>> BufferPSVs;
Matt Arsenault905f3512017-12-29 17:18:14 +0000214 DenseMap<const Value *,
215 std::unique_ptr<const AMDGPUImagePseudoSourceValue>> ImagePSVs;
Matt Arsenault4d55d022019-06-19 19:55:27 +0000216 std::unique_ptr<const AMDGPUGWSResourcePseudoSourceValue> GWSResourcePSV;
Matt Arsenault905f3512017-12-29 17:18:14 +0000217
Matt Arsenault161e2b42017-04-18 20:59:40 +0000218private:
Eugene Zelenko59e12822017-08-08 00:47:13 +0000219 unsigned LDSWaveSpillSize = 0;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000220 unsigned NumUserSGPRs = 0;
221 unsigned NumSystemSGPRs = 0;
Matt Arsenault49affb82015-11-25 20:55:12 +0000222
Eugene Zelenko59e12822017-08-08 00:47:13 +0000223 bool HasSpilledSGPRs = false;
224 bool HasSpilledVGPRs = false;
225 bool HasNonSpillStackObjects = false;
Matt Arsenault03ae3992018-03-29 21:30:06 +0000226 bool IsStackRealigned = false;
Tom Stellard96468902014-09-24 01:33:17 +0000227
Eugene Zelenko59e12822017-08-08 00:47:13 +0000228 unsigned NumSpilledSGPRs = 0;
229 unsigned NumSpilledVGPRs = 0;
Marek Olsak0532c192016-07-13 17:35:15 +0000230
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000231 // Feature bits required for inputs passed in user SGPRs.
232 bool PrivateSegmentBuffer : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000233 bool DispatchPtr : 1;
234 bool QueuePtr : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000235 bool KernargSegmentPtr : 1;
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000236 bool DispatchID : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000237 bool FlatScratchInit : 1;
Tom Stellardc149dc02013-11-27 21:23:35 +0000238
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000239 // Feature bits required for inputs passed in system SGPRs.
Matt Arsenault49affb82015-11-25 20:55:12 +0000240 bool WorkGroupIDX : 1; // Always initialized.
241 bool WorkGroupIDY : 1;
242 bool WorkGroupIDZ : 1;
243 bool WorkGroupInfo : 1;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000244 bool PrivateSegmentWaveByteOffset : 1;
Matt Arsenault49affb82015-11-25 20:55:12 +0000245
246 bool WorkItemIDX : 1; // Always initialized.
247 bool WorkItemIDY : 1;
248 bool WorkItemIDZ : 1;
249
Tom Stellard2f3f9852017-01-25 01:25:13 +0000250 // Private memory buffer
251 // Compute directly in sgpr[0:1]
252 // Other shaders indirect 64-bits at sgpr[0:1]
Matt Arsenault10fc0622017-06-26 03:01:31 +0000253 bool ImplicitBufferPtr : 1;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000254
Matt Arsenault9166ce82017-07-28 15:52:08 +0000255 // Pointer to where the ABI inserts special kernel arguments separate from the
256 // user arguments. This is an offset from the KernargSegmentPtr.
257 bool ImplicitArgPtr : 1;
258
Tim Renouf13229152017-09-29 09:49:35 +0000259 // The hard-wired high half of the address of the global information table
260 // for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
261 // current hardware only allows a 16 bit value.
262 unsigned GITPtrHigh;
263
Matt Arsenault923712b2018-02-09 16:57:57 +0000264 unsigned HighBitsOf32BitAddress;
265
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000266 // Current recorded maximum possible occupancy.
267 unsigned Occupancy;
268
Tom Stellard44b30b42018-05-22 02:03:23 +0000269 MCPhysReg getNextUserSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000270
Tom Stellard44b30b42018-05-22 02:03:23 +0000271 MCPhysReg getNextSystemSGPR() const;
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000272
Matt Arsenault49affb82015-11-25 20:55:12 +0000273public:
Tom Stellardc149dc02013-11-27 21:23:35 +0000274 struct SpilledReg {
Tom Stellard44b30b42018-05-22 02:03:23 +0000275 unsigned VGPR = 0;
Eugene Zelenko66203762017-01-21 00:53:49 +0000276 int Lane = -1;
277
278 SpilledReg() = default;
Eugene Zelenko59e12822017-08-08 00:47:13 +0000279 SpilledReg(unsigned R, int L) : VGPR (R), Lane (L) {}
Eugene Zelenko66203762017-01-21 00:53:49 +0000280
Tom Stellardc149dc02013-11-27 21:23:35 +0000281 bool hasLane() { return Lane != -1;}
Tom Stellard44b30b42018-05-22 02:03:23 +0000282 bool hasReg() { return VGPR != 0;}
Tom Stellardc149dc02013-11-27 21:23:35 +0000283 };
284
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000285 struct SGPRSpillVGPRCSR {
286 // VGPR used for SGPR spills
287 unsigned VGPR;
288
289 // If the VGPR is a CSR, the stack slot used to save/restore it in the
290 // prolog/epilog.
291 Optional<int> FI;
292
Eugene Zelenko59e12822017-08-08 00:47:13 +0000293 SGPRSpillVGPRCSR(unsigned V, Optional<int> F) : VGPR(V), FI(F) {}
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000294 };
295
Neil Henning0a30f332019-04-01 15:19:52 +0000296 SparseBitVector<> WWMReservedRegs;
297
298 void ReserveWWMRegister(unsigned reg) { WWMReservedRegs.set(reg); }
299
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000300private:
301 // SGPR->VGPR spilling support.
Eugene Zelenko59e12822017-08-08 00:47:13 +0000302 using SpillRegMask = std::pair<unsigned, unsigned>;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000303
304 // Track VGPR + wave index for each subregister of the SGPR spilled to
305 // frameindex key.
306 DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
307 unsigned NumVGPRSpillLanes = 0;
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000308 SmallVector<SGPRSpillVGPRCSR, 2> SpillVGPRs;
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000309
310public:
Tom Stellard75aadc22012-12-11 21:25:42 +0000311 SIMachineFunctionInfo(const MachineFunction &MF);
Eugene Zelenko66203762017-01-21 00:53:49 +0000312
Matt Arsenaultbc6d07c2019-03-14 22:54:43 +0000313 bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI);
314
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000315 ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
316 auto I = SGPRToVGPRSpills.find(FrameIndex);
317 return (I == SGPRToVGPRSpills.end()) ?
318 ArrayRef<SpilledReg>() : makeArrayRef(I->second);
319 }
320
Matt Arsenault8e8f8f42017-08-02 01:52:45 +0000321 ArrayRef<SGPRSpillVGPRCSR> getSGPRSpillVGPRs() const {
322 return SpillVGPRs;
323 }
324
Matt Arsenault055e4dc2019-03-29 19:14:54 +0000325 AMDGPU::SIModeRegisterDefaults getMode() const {
326 return Mode;
327 }
328
Matt Arsenaulte0bf7d02017-02-21 19:12:08 +0000329 bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
330 void removeSGPRToVGPRFrameIndices(MachineFrameInfo &MFI);
331
Tom Stellard44b30b42018-05-22 02:03:23 +0000332 bool hasCalculatedTID() const { return TIDReg != 0; };
333 unsigned getTIDReg() const { return TIDReg; };
Tom Stellard96468902014-09-24 01:33:17 +0000334 void setTIDReg(unsigned Reg) { TIDReg = Reg; }
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000335
Matt Arsenault71bcbd42017-08-11 20:42:08 +0000336 unsigned getBytesInStackArgArea() const {
337 return BytesInStackArgArea;
338 }
339
340 void setBytesInStackArgArea(unsigned Bytes) {
341 BytesInStackArgArea = Bytes;
342 }
343
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000344 // Add user SGPRs.
345 unsigned addPrivateSegmentBuffer(const SIRegisterInfo &TRI);
346 unsigned addDispatchPtr(const SIRegisterInfo &TRI);
347 unsigned addQueuePtr(const SIRegisterInfo &TRI);
348 unsigned addKernargSegmentPtr(const SIRegisterInfo &TRI);
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000349 unsigned addDispatchID(const SIRegisterInfo &TRI);
Matt Arsenault296b8492016-02-12 06:31:30 +0000350 unsigned addFlatScratchInit(const SIRegisterInfo &TRI);
Matt Arsenault10fc0622017-06-26 03:01:31 +0000351 unsigned addImplicitBufferPtr(const SIRegisterInfo &TRI);
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000352
353 // Add system SGPRs.
354 unsigned addWorkGroupIDX() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000355 ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000356 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000357 return ArgInfo.WorkGroupIDX.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000358 }
359
360 unsigned addWorkGroupIDY() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000361 ArgInfo.WorkGroupIDY = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000362 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000363 return ArgInfo.WorkGroupIDY.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000364 }
365
366 unsigned addWorkGroupIDZ() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000367 ArgInfo.WorkGroupIDZ = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000368 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000369 return ArgInfo.WorkGroupIDZ.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000370 }
371
372 unsigned addWorkGroupInfo() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000373 ArgInfo.WorkGroupInfo = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000374 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000375 return ArgInfo.WorkGroupInfo.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000376 }
377
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000378 // Add special VGPR inputs
379 void setWorkItemIDX(ArgDescriptor Arg) {
380 ArgInfo.WorkItemIDX = Arg;
381 }
382
383 void setWorkItemIDY(ArgDescriptor Arg) {
384 ArgInfo.WorkItemIDY = Arg;
385 }
386
387 void setWorkItemIDZ(ArgDescriptor Arg) {
388 ArgInfo.WorkItemIDZ = Arg;
389 }
390
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000391 unsigned addPrivateSegmentWaveByteOffset() {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000392 ArgInfo.PrivateSegmentWaveByteOffset
393 = ArgDescriptor::createRegister(getNextSystemSGPR());
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000394 NumSystemSGPRs += 1;
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000395 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000396 }
397
Tom Stellardf110f8f2016-04-14 16:27:03 +0000398 void setPrivateSegmentWaveByteOffset(unsigned Reg) {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000399 ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
Tom Stellardf110f8f2016-04-14 16:27:03 +0000400 }
401
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000402 bool hasPrivateSegmentBuffer() const {
403 return PrivateSegmentBuffer;
404 }
405
Matt Arsenault49affb82015-11-25 20:55:12 +0000406 bool hasDispatchPtr() const {
407 return DispatchPtr;
408 }
409
410 bool hasQueuePtr() const {
411 return QueuePtr;
412 }
413
Matt Arsenault49affb82015-11-25 20:55:12 +0000414 bool hasKernargSegmentPtr() const {
415 return KernargSegmentPtr;
416 }
417
Matt Arsenault8d718dc2016-07-22 17:01:30 +0000418 bool hasDispatchID() const {
419 return DispatchID;
420 }
421
Matt Arsenault49affb82015-11-25 20:55:12 +0000422 bool hasFlatScratchInit() const {
423 return FlatScratchInit;
424 }
425
Matt Arsenault49affb82015-11-25 20:55:12 +0000426 bool hasWorkGroupIDX() const {
427 return WorkGroupIDX;
428 }
429
430 bool hasWorkGroupIDY() const {
431 return WorkGroupIDY;
432 }
433
434 bool hasWorkGroupIDZ() const {
435 return WorkGroupIDZ;
436 }
437
438 bool hasWorkGroupInfo() const {
439 return WorkGroupInfo;
440 }
441
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000442 bool hasPrivateSegmentWaveByteOffset() const {
443 return PrivateSegmentWaveByteOffset;
444 }
445
Matt Arsenault49affb82015-11-25 20:55:12 +0000446 bool hasWorkItemIDX() const {
447 return WorkItemIDX;
448 }
449
450 bool hasWorkItemIDY() const {
451 return WorkItemIDY;
452 }
453
454 bool hasWorkItemIDZ() const {
455 return WorkItemIDZ;
456 }
457
Matt Arsenault9166ce82017-07-28 15:52:08 +0000458 bool hasImplicitArgPtr() const {
459 return ImplicitArgPtr;
460 }
461
Matt Arsenault10fc0622017-06-26 03:01:31 +0000462 bool hasImplicitBufferPtr() const {
463 return ImplicitBufferPtr;
Tom Stellard2f3f9852017-01-25 01:25:13 +0000464 }
465
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000466 AMDGPUFunctionArgInfo &getArgInfo() {
467 return ArgInfo;
468 }
469
470 const AMDGPUFunctionArgInfo &getArgInfo() const {
471 return ArgInfo;
472 }
473
474 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
475 getPreloadedValue(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
476 return ArgInfo.getPreloadedValue(Value);
477 }
478
Matt Arsenault1b317682019-07-01 13:44:46 +0000479 Register getPreloadedReg(AMDGPUFunctionArgInfo::PreloadedValue Value) const {
Matt Arsenaultb812b7a2019-06-05 22:20:47 +0000480 auto Arg = ArgInfo.getPreloadedValue(Value).first;
Matt Arsenault1b317682019-07-01 13:44:46 +0000481 return Arg ? Arg->getRegister() : Register();
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000482 }
483
Tim Renouf13229152017-09-29 09:49:35 +0000484 unsigned getGITPtrHigh() const {
485 return GITPtrHigh;
486 }
487
Matt Arsenault923712b2018-02-09 16:57:57 +0000488 unsigned get32BitAddressHighBits() const {
489 return HighBitsOf32BitAddress;
490 }
491
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000492 unsigned getNumUserSGPRs() const {
493 return NumUserSGPRs;
494 }
495
496 unsigned getNumPreloadedSGPRs() const {
497 return NumUserSGPRs + NumSystemSGPRs;
498 }
499
500 unsigned getPrivateSegmentWaveByteOffsetSystemSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000501 return ArgInfo.PrivateSegmentWaveByteOffset.getRegister();
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000502 }
503
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000504 /// Returns the physical register reserved for use as the resource
Matt Arsenault49affb82015-11-25 20:55:12 +0000505 /// descriptor for scratch accesses.
506 unsigned getScratchRSrcReg() const {
507 return ScratchRSrcReg;
508 }
509
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000510 void setScratchRSrcReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000511 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000512 ScratchRSrcReg = Reg;
513 }
514
515 unsigned getScratchWaveOffsetReg() const {
516 return ScratchWaveOffsetReg;
517 }
518
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000519 unsigned getFrameOffsetReg() const {
520 return FrameOffsetReg;
521 }
522
Matt Arsenaultb812b7a2019-06-05 22:20:47 +0000523 void setFrameOffsetReg(unsigned Reg) {
524 assert(Reg != 0 && "Should never be unset");
525 FrameOffsetReg = Reg;
526 }
527
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000528 void setStackPtrOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000529 assert(Reg != 0 && "Should never be unset");
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000530 StackPtrOffsetReg = Reg;
531 }
532
Matt Arsenault1cc47f82017-07-18 16:44:56 +0000533 // Note the unset value for this is AMDGPU::SP_REG rather than
534 // NoRegister. This is mostly a workaround for MIR tests where state that
535 // can't be directly computed from the function is not preserved in serialized
536 // MIR.
Matt Arsenault1c0ae392017-04-24 18:05:16 +0000537 unsigned getStackPtrOffsetReg() const {
538 return StackPtrOffsetReg;
539 }
540
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000541 void setScratchWaveOffsetReg(unsigned Reg) {
Tom Stellard44b30b42018-05-22 02:03:23 +0000542 assert(Reg != 0 && "Should never be unset");
Matt Arsenault26f8f3d2015-11-30 21:16:03 +0000543 ScratchWaveOffsetReg = Reg;
544 }
Matt Arsenault49affb82015-11-25 20:55:12 +0000545
Matt Arsenault99c14522016-04-25 19:27:24 +0000546 unsigned getQueuePtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000547 return ArgInfo.QueuePtr.getRegister();
Matt Arsenault99c14522016-04-25 19:27:24 +0000548 }
549
Matt Arsenault10fc0622017-06-26 03:01:31 +0000550 unsigned getImplicitBufferPtrUserSGPR() const {
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000551 return ArgInfo.ImplicitBufferPtr.getRegister();
Tom Stellard2f3f9852017-01-25 01:25:13 +0000552 }
553
Matt Arsenault5b22dfa2015-11-05 05:27:10 +0000554 bool hasSpilledSGPRs() const {
555 return HasSpilledSGPRs;
556 }
557
558 void setHasSpilledSGPRs(bool Spill = true) {
559 HasSpilledSGPRs = Spill;
560 }
561
562 bool hasSpilledVGPRs() const {
563 return HasSpilledVGPRs;
564 }
565
566 void setHasSpilledVGPRs(bool Spill = true) {
567 HasSpilledVGPRs = Spill;
568 }
Tom Stellard96468902014-09-24 01:33:17 +0000569
Matt Arsenault296b8492016-02-12 06:31:30 +0000570 bool hasNonSpillStackObjects() const {
571 return HasNonSpillStackObjects;
572 }
573
574 void setHasNonSpillStackObjects(bool StackObject = true) {
575 HasNonSpillStackObjects = StackObject;
576 }
577
Matt Arsenault03ae3992018-03-29 21:30:06 +0000578 bool isStackRealigned() const {
579 return IsStackRealigned;
580 }
581
582 void setIsStackRealigned(bool Realigned = true) {
583 IsStackRealigned = Realigned;
584 }
585
Marek Olsak0532c192016-07-13 17:35:15 +0000586 unsigned getNumSpilledSGPRs() const {
587 return NumSpilledSGPRs;
588 }
589
590 unsigned getNumSpilledVGPRs() const {
591 return NumSpilledVGPRs;
592 }
593
594 void addToSpilledSGPRs(unsigned num) {
595 NumSpilledSGPRs += num;
596 }
597
598 void addToSpilledVGPRs(unsigned num) {
599 NumSpilledVGPRs += num;
600 }
601
Marek Olsakfccabaf2016-01-13 11:45:36 +0000602 unsigned getPSInputAddr() const {
603 return PSInputAddr;
604 }
605
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000606 unsigned getPSInputEnable() const {
607 return PSInputEnable;
608 }
609
Marek Olsakfccabaf2016-01-13 11:45:36 +0000610 bool isPSInputAllocated(unsigned Index) const {
611 return PSInputAddr & (1 << Index);
612 }
613
614 void markPSInputAllocated(unsigned Index) {
615 PSInputAddr |= 1 << Index;
616 }
617
Matt Arsenaulte622dc32017-04-11 22:29:24 +0000618 void markPSInputEnabled(unsigned Index) {
619 PSInputEnable |= 1 << Index;
620 }
621
Marek Olsak8e9cc632016-01-13 17:23:09 +0000622 bool returnsVoid() const {
623 return ReturnsVoid;
624 }
625
626 void setIfReturnsVoid(bool Value) {
627 ReturnsVoid = Value;
628 }
629
Konstantin Zhuravlyov1d650262016-09-06 20:22:28 +0000630 /// \returns A pair of default/requested minimum/maximum flat work group sizes
631 /// for this function.
632 std::pair<unsigned, unsigned> getFlatWorkGroupSizes() const {
633 return FlatWorkGroupSizes;
634 }
635
636 /// \returns Default/requested minimum flat work group size for this function.
637 unsigned getMinFlatWorkGroupSize() const {
638 return FlatWorkGroupSizes.first;
639 }
640
641 /// \returns Default/requested maximum flat work group size for this function.
642 unsigned getMaxFlatWorkGroupSize() const {
643 return FlatWorkGroupSizes.second;
644 }
645
646 /// \returns A pair of default/requested minimum/maximum number of waves per
647 /// execution unit.
648 std::pair<unsigned, unsigned> getWavesPerEU() const {
649 return WavesPerEU;
650 }
651
652 /// \returns Default/requested minimum number of waves per execution unit.
653 unsigned getMinWavesPerEU() const {
654 return WavesPerEU.first;
655 }
656
657 /// \returns Default/requested maximum number of waves per execution unit.
658 unsigned getMaxWavesPerEU() const {
659 return WavesPerEU.second;
Konstantin Zhuravlyov71515e52016-04-26 17:24:40 +0000660 }
661
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000662 /// \returns SGPR used for \p Dim's work group ID.
663 unsigned getWorkGroupIDSGPR(unsigned Dim) const {
664 switch (Dim) {
665 case 0:
666 assert(hasWorkGroupIDX());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000667 return ArgInfo.WorkGroupIDX.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000668 case 1:
669 assert(hasWorkGroupIDY());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000670 return ArgInfo.WorkGroupIDY.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000671 case 2:
672 assert(hasWorkGroupIDZ());
Matt Arsenault8623e8d2017-08-03 23:00:29 +0000673 return ArgInfo.WorkGroupIDZ.getRegister();
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000674 }
675 llvm_unreachable("unexpected dimension");
676 }
677
Matt Arsenault161e2b42017-04-18 20:59:40 +0000678 unsigned getLDSWaveSpillSize() const {
679 return LDSWaveSpillSize;
680 }
681
Matt Arsenaulte19bc2e2017-12-29 17:18:21 +0000682 const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII,
683 const Value *BufferRsrc) {
684 assert(BufferRsrc);
685 auto PSV = BufferPSVs.try_emplace(
686 BufferRsrc,
687 llvm::make_unique<AMDGPUBufferPseudoSourceValue>(TII));
688 return PSV.first->second.get();
Tom Stellard6f9ef142016-12-20 17:19:44 +0000689 }
690
Matt Arsenault905f3512017-12-29 17:18:14 +0000691 const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII,
692 const Value *ImgRsrc) {
693 assert(ImgRsrc);
694 auto PSV = ImagePSVs.try_emplace(
695 ImgRsrc,
696 llvm::make_unique<AMDGPUImagePseudoSourceValue>(TII));
697 return PSV.first->second.get();
Tom Stellard244891d2016-12-20 15:52:17 +0000698 }
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000699
Matt Arsenault4d55d022019-06-19 19:55:27 +0000700 const AMDGPUGWSResourcePseudoSourceValue *getGWSPSV(const SIInstrInfo &TII) {
701 if (!GWSResourcePSV) {
702 GWSResourcePSV =
703 llvm::make_unique<AMDGPUGWSResourcePseudoSourceValue>(TII);
704 }
705
706 return GWSResourcePSV.get();
707 }
708
Stanislav Mekhanoshind4b500c2018-05-31 05:36:04 +0000709 unsigned getOccupancy() const {
710 return Occupancy;
711 }
712
713 unsigned getMinAllowedOccupancy() const {
714 if (!isMemoryBound() && !needsWaveLimiter())
715 return Occupancy;
716 return (Occupancy < 4) ? Occupancy : 4;
717 }
718
719 void limitOccupancy(const MachineFunction &MF);
720
721 void limitOccupancy(unsigned Limit) {
722 if (Occupancy > Limit)
723 Occupancy = Limit;
724 }
725
726 void increaseOccupancy(const MachineFunction &MF, unsigned Limit) {
727 if (Occupancy < Limit)
728 Occupancy = Limit;
729 limitOccupancy(MF);
730 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000731};
732
Eugene Zelenko66203762017-01-21 00:53:49 +0000733} // end namespace llvm
Tom Stellard75aadc22012-12-11 21:25:42 +0000734
Eugene Zelenko66203762017-01-21 00:53:49 +0000735#endif // LLVM_LIB_TARGET_AMDGPU_SIMACHINEFUNCTIONINFO_H