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 "llvm/ADT/DenseMap.h"
13#include "llvm/CodeGen/Register.h"
14#include "llvm/Pass.h"
15
16namespace llvm {
17
18class Function;
19class LLT;
20class raw_ostream;
21class TargetRegisterClass;
22class TargetRegisterInfo;
23
24struct ArgDescriptor {
25private:
26 friend struct AMDGPUFunctionArgInfo;
27 friend class AMDGPUArgumentUsageInfo;
28
29 union {
30 MCRegister Reg;
31 unsigned StackOffset;
32 };
33
34 // Bitmask to locate argument within the register.
35 unsigned Mask;
36
37 bool IsStack : 1;
38 bool IsSet : 1;
39
40public:
41 ArgDescriptor(unsigned Val = 0, unsigned Mask = ~0u, bool IsStack = false,
42 bool IsSet = false)
43 : Reg(Val), Mask(Mask), IsStack(IsStack), IsSet(IsSet) {}
44
45 static ArgDescriptor createRegister(Register Reg, unsigned Mask = ~0u) {
46 return ArgDescriptor(Reg, Mask, false, true);
47 }
48
49 static ArgDescriptor createStack(unsigned Offset, unsigned Mask = ~0u) {
50 return ArgDescriptor(Offset, Mask, true, true);
51 }
52
53 static ArgDescriptor createArg(const ArgDescriptor &Arg, unsigned Mask) {
54 return ArgDescriptor(Arg.Reg, Mask, Arg.IsStack, Arg.IsSet);
55 }
56
57 bool isSet() const {
58 return IsSet;
59 }
60
61 explicit operator bool() const {
62 return isSet();
63 }
64
65 bool isRegister() const {
66 return !IsStack;
67 }
68
69 MCRegister getRegister() const {
70 assert(!IsStack);
71 return Reg;
72 }
73
74 unsigned getStackOffset() const {
75 assert(IsStack);
76 return StackOffset;
77 }
78
79 unsigned getMask() const {
80 return Mask;
81 }
82
83 bool isMasked() const {
84 return Mask != ~0u;
85 }
86
87 void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const;
88};
89
90inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) {
91 Arg.print(OS);
92 return OS;
93}
94
95struct KernArgPreloadDescriptor : public ArgDescriptor {
96 KernArgPreloadDescriptor() {}
97 SmallVector<MCRegister> Regs;
98};
99
100struct AMDGPUFunctionArgInfo {
101 // clang-format off
102 enum PreloadedValue {
103 // SGPRS:
104 PRIVATE_SEGMENT_BUFFER = 0,
105 DISPATCH_PTR = 1,
106 QUEUE_PTR = 2,
107 KERNARG_SEGMENT_PTR = 3,
108 DISPATCH_ID = 4,
109 FLAT_SCRATCH_INIT = 5,
110 LDS_KERNEL_ID = 6, // LLVM internal, not part of the ABI
111 WORKGROUP_ID_X = 10,
112 WORKGROUP_ID_Y = 11,
113 WORKGROUP_ID_Z = 12,
114 PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14,
115 IMPLICIT_BUFFER_PTR = 15,
116 IMPLICIT_ARG_PTR = 16,
117
118 // VGPRS:
119 WORKITEM_ID_X = 17,
120 WORKITEM_ID_Y = 18,
121 WORKITEM_ID_Z = 19,
122 FIRST_VGPR_VALUE = WORKITEM_ID_X
123 };
124 // clang-format on
125
126 // Kernel input registers setup for the HSA ABI in allocation order.
127
128 // User SGPRs in kernels
129 // XXX - Can these require argument spills?
130 ArgDescriptor PrivateSegmentBuffer;
131 ArgDescriptor DispatchPtr;
132 ArgDescriptor QueuePtr;
133 ArgDescriptor KernargSegmentPtr;
134 ArgDescriptor DispatchID;
135 ArgDescriptor FlatScratchInit;
136 ArgDescriptor PrivateSegmentSize;
137 ArgDescriptor LDSKernelId;
138
139 // System SGPRs in kernels.
140 ArgDescriptor WorkGroupIDX;
141 ArgDescriptor WorkGroupIDY;
142 ArgDescriptor WorkGroupIDZ;
143 ArgDescriptor WorkGroupInfo;
144 ArgDescriptor PrivateSegmentWaveByteOffset;
145
146 // Pointer with offset from kernargsegmentptr to where special ABI arguments
147 // are passed to callable functions.
148 ArgDescriptor ImplicitArgPtr;
149
150 // Input registers for non-HSA ABI
151 ArgDescriptor ImplicitBufferPtr;
152
153 // VGPRs inputs. For entry functions these are either v0, v1 and v2 or packed
154 // into v0, 10 bits per dimension if packed-tid is set.
155 ArgDescriptor WorkItemIDX;
156 ArgDescriptor WorkItemIDY;
157 ArgDescriptor WorkItemIDZ;
158
159 // Map the index of preloaded kernel arguments to its descriptor.
160 SmallDenseMap<int, KernArgPreloadDescriptor> PreloadKernArgs{};
161
162 std::tuple<const ArgDescriptor *, const TargetRegisterClass *, LLT>
163 getPreloadedValue(PreloadedValue Value) const;
164
165 static AMDGPUFunctionArgInfo fixedABILayout();
166};
167
168class AMDGPUArgumentUsageInfo : public ImmutablePass {
169private:
170 DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap;
171
172public:
173 static char ID;
174
175 static const AMDGPUFunctionArgInfo ExternFunctionInfo;
176 static const AMDGPUFunctionArgInfo FixedABIFunctionInfo;
177
178 AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { }
179
180 void getAnalysisUsage(AnalysisUsage &AU) const override {
181 AU.setPreservesAll();
182 }
183
184 bool doInitialization(Module &M) override;
185 bool doFinalization(Module &M) override;
186
187 void print(raw_ostream &OS, const Module *M = nullptr) const override;
188
189 void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) {
190 ArgInfoMap[&F] = ArgInfo;
191 }
192
193 const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const;
194};
195
196} // end namespace llvm
197
198#endif
199

source code of llvm/lib/Target/AMDGPU/AMDGPUArgumentUsageInfo.h