1//==- AMDGPUArgumentrUsageInfo.h - Function Arg Usage Info -------*- C++ -*-==//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUARGUMENTUSAGEINFO_H
10#define LLVM_LIB_TARGET_AMDGPU_AMDGPUARGUMENTUSAGEINFO_H
11
12#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
13#include "llvm/CodeGen/Register.h"
14#include <variant>
15
16namespace llvm {
17
18class LLT;
19class raw_ostream;
20class TargetRegisterClass;
21class TargetRegisterInfo;
22
23struct ArgDescriptor {
24private:
25 friend struct AMDGPUFunctionArgInfo;
26
27 std::variant<std::monostate, MCRegister, unsigned> Val;
28
29 // Bitmask to locate argument within the register.
30 unsigned Mask;
31
32public:
33 ArgDescriptor(unsigned Mask = ~0u) : Mask(Mask) {}
34
35 static ArgDescriptor createRegister(Register Reg, unsigned Mask = ~0u) {
36 ArgDescriptor Ret(Mask);
37 Ret.Val = Reg.asMCReg();
38 return Ret;
39 }
40
41 static ArgDescriptor createStack(unsigned Offset, unsigned Mask = ~0u) {
42 ArgDescriptor Ret(Mask);
43 Ret.Val = Offset;
44 return Ret;
45 }
46
47 static ArgDescriptor createArg(const ArgDescriptor &Arg, unsigned Mask) {
48 // Copy the descriptor, then change the mask.
49 ArgDescriptor Ret(Arg);
50 Ret.Mask = Mask;
51 return Ret;
52 }
53
54 bool isSet() const { return !std::holds_alternative<std::monostate>(v: Val); }
55
56 explicit operator bool() const {
57 return isSet();
58 }
59
60 bool isRegister() const { return std::holds_alternative<MCRegister>(v: Val); }
61
62 MCRegister getRegister() const { return std::get<MCRegister>(v: Val); }
63
64 unsigned getStackOffset() const { return std::get<unsigned>(v: Val); }
65
66 unsigned getMask() const {
67 // None of the target SGPRs or VGPRs are expected to have a 'zero' mask.
68 assert(Mask && "Invalid mask.");
69 return Mask;
70 }
71
72 bool isMasked() const {
73 return Mask != ~0u;
74 }
75
76 void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const;
77};
78
79inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) {
80 Arg.print(OS);
81 return OS;
82}
83
84struct KernArgPreloadDescriptor : public ArgDescriptor {
85 KernArgPreloadDescriptor() = default;
86 SmallVector<MCRegister> Regs;
87};
88
89struct AMDGPUFunctionArgInfo {
90 // clang-format off
91 enum PreloadedValue {
92 // SGPRS:
93 PRIVATE_SEGMENT_BUFFER = 0,
94 DISPATCH_PTR = 1,
95 QUEUE_PTR = 2,
96 KERNARG_SEGMENT_PTR = 3,
97 DISPATCH_ID = 4,
98 FLAT_SCRATCH_INIT = 5,
99 LDS_KERNEL_ID = 6, // LLVM internal, not part of the ABI
100 WORKGROUP_ID_X = 10, // Also used for cluster ID X.
101 WORKGROUP_ID_Y = 11, // Also used for cluster ID Y.
102 WORKGROUP_ID_Z = 12, // Also used for cluster ID Z.
103 PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14,
104 IMPLICIT_BUFFER_PTR = 15,
105 IMPLICIT_ARG_PTR = 16,
106 PRIVATE_SEGMENT_SIZE = 17,
107 CLUSTER_WORKGROUP_ID_X = 21,
108 CLUSTER_WORKGROUP_ID_Y = 22,
109 CLUSTER_WORKGROUP_ID_Z = 23,
110 CLUSTER_WORKGROUP_MAX_ID_X = 24,
111 CLUSTER_WORKGROUP_MAX_ID_Y = 25,
112 CLUSTER_WORKGROUP_MAX_ID_Z = 26,
113 CLUSTER_WORKGROUP_MAX_FLAT_ID = 27,
114
115 // VGPRS:
116 WORKITEM_ID_X = 28,
117 WORKITEM_ID_Y = 29,
118 WORKITEM_ID_Z = 30,
119 FIRST_VGPR_VALUE = WORKITEM_ID_X
120 };
121 // clang-format on
122
123 // Kernel input registers setup for the HSA ABI in allocation order.
124
125 // User SGPRs in kernels
126 // XXX - Can these require argument spills?
127 ArgDescriptor PrivateSegmentBuffer;
128 ArgDescriptor DispatchPtr;
129 ArgDescriptor QueuePtr;
130 ArgDescriptor KernargSegmentPtr;
131 ArgDescriptor DispatchID;
132 ArgDescriptor FlatScratchInit;
133 ArgDescriptor PrivateSegmentSize;
134 ArgDescriptor LDSKernelId;
135
136 // System SGPRs in kernels.
137 ArgDescriptor WorkGroupIDX;
138 ArgDescriptor WorkGroupIDY;
139 ArgDescriptor WorkGroupIDZ;
140 ArgDescriptor WorkGroupInfo;
141 ArgDescriptor PrivateSegmentWaveByteOffset;
142
143 // Pointer with offset from kernargsegmentptr to where special ABI arguments
144 // are passed to callable functions.
145 ArgDescriptor ImplicitArgPtr;
146
147 // Input registers for non-HSA ABI
148 ArgDescriptor ImplicitBufferPtr;
149
150 // VGPRs inputs. For entry functions these are either v0, v1 and v2 or packed
151 // into v0, 10 bits per dimension if packed-tid is set.
152 ArgDescriptor WorkItemIDX;
153 ArgDescriptor WorkItemIDY;
154 ArgDescriptor WorkItemIDZ;
155
156 // Map the index of preloaded kernel arguments to its descriptor.
157 SmallDenseMap<int, KernArgPreloadDescriptor> PreloadKernArgs{};
158 // The first user SGPR allocated for kernarg preloading.
159 Register FirstKernArgPreloadReg;
160
161 std::tuple<const ArgDescriptor *, const TargetRegisterClass *, LLT>
162 getPreloadedValue(PreloadedValue Value) const;
163
164 static AMDGPUFunctionArgInfo fixedABILayout();
165 static const AMDGPUFunctionArgInfo FixedABIFunctionInfo;
166};
167
168} // end namespace llvm
169
170#endif
171