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