blob: 277f3616031f251ef763af414e0146333b968d31 [file] [log] [blame]
Matt Arsenault7016f132017-08-03 22:30:46 +00001//==- AMDGPUArgumentrUsageInfo.h - Function Arg Usage Info -------*- C++ -*-==//
2//
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
Matt Arsenault7016f132017-08-03 22:30:46 +00006//
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/IR/Function.h"
14#include "llvm/Pass.h"
15
16namespace llvm {
17
18class Function;
19class raw_ostream;
Tom Stellard5bfbae52018-07-11 20:59:01 +000020class GCNSubtarget;
Matt Arsenault7016f132017-08-03 22:30:46 +000021class TargetMachine;
22class TargetRegisterClass;
23class TargetRegisterInfo;
24
25struct ArgDescriptor {
26private:
27 friend struct AMDGPUFunctionArgInfo;
Florian Gross2feb1052017-08-04 10:53:07 +000028 friend class AMDGPUArgumentUsageInfo;
Matt Arsenault7016f132017-08-03 22:30:46 +000029
30 union {
31 unsigned Register;
32 unsigned StackOffset;
33 };
34
35 bool IsStack : 1;
36 bool IsSet : 1;
37
38 ArgDescriptor(unsigned Val = 0, bool IsStack = false, bool IsSet = false)
39 : Register(Val), IsStack(IsStack), IsSet(IsSet) {}
40public:
41 static ArgDescriptor createRegister(unsigned Reg) {
42 return ArgDescriptor(Reg, false, true);
43 }
44
45 static ArgDescriptor createStack(unsigned Reg) {
46 return ArgDescriptor(Reg, true, true);
47 }
48
49 bool isSet() const {
50 return IsSet;
51 }
52
53 explicit operator bool() const {
54 return isSet();
55 }
56
57 bool isRegister() const {
58 return !IsStack;
59 }
60
61 unsigned getRegister() const {
62 assert(!IsStack);
63 return Register;
64 }
65
66 unsigned getStackOffset() const {
67 assert(IsStack);
68 return StackOffset;
69 }
70
71 void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const;
72};
73
74inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) {
75 Arg.print(OS);
76 return OS;
77}
78
79struct AMDGPUFunctionArgInfo {
80 enum PreloadedValue {
81 // SGPRS:
82 PRIVATE_SEGMENT_BUFFER = 0,
83 DISPATCH_PTR = 1,
84 QUEUE_PTR = 2,
85 KERNARG_SEGMENT_PTR = 3,
86 DISPATCH_ID = 4,
87 FLAT_SCRATCH_INIT = 5,
88 WORKGROUP_ID_X = 10,
89 WORKGROUP_ID_Y = 11,
90 WORKGROUP_ID_Z = 12,
91 PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14,
92 IMPLICIT_BUFFER_PTR = 15,
Matt Arsenault817c2532017-08-03 23:12:44 +000093 IMPLICIT_ARG_PTR = 16,
Matt Arsenault7016f132017-08-03 22:30:46 +000094
95 // VGPRS:
Matt Arsenault817c2532017-08-03 23:12:44 +000096 WORKITEM_ID_X = 17,
97 WORKITEM_ID_Y = 18,
98 WORKITEM_ID_Z = 19,
99 FIRST_VGPR_VALUE = WORKITEM_ID_X
Matt Arsenault7016f132017-08-03 22:30:46 +0000100 };
101
102 // Kernel input registers setup for the HSA ABI in allocation order.
103
104 // User SGPRs in kernels
105 // XXX - Can these require argument spills?
106 ArgDescriptor PrivateSegmentBuffer;
107 ArgDescriptor DispatchPtr;
108 ArgDescriptor QueuePtr;
109 ArgDescriptor KernargSegmentPtr;
110 ArgDescriptor DispatchID;
111 ArgDescriptor FlatScratchInit;
112 ArgDescriptor PrivateSegmentSize;
Matt Arsenault7016f132017-08-03 22:30:46 +0000113
114 // System SGPRs in kernels.
115 ArgDescriptor WorkGroupIDX;
116 ArgDescriptor WorkGroupIDY;
117 ArgDescriptor WorkGroupIDZ;
118 ArgDescriptor WorkGroupInfo;
119 ArgDescriptor PrivateSegmentWaveByteOffset;
120
Matt Arsenault817c2532017-08-03 23:12:44 +0000121 // Pointer with offset from kernargsegmentptr to where special ABI arguments
122 // are passed to callable functions.
123 ArgDescriptor ImplicitArgPtr;
124
Matt Arsenault7016f132017-08-03 22:30:46 +0000125 // Input registers for non-HSA ABI
126 ArgDescriptor ImplicitBufferPtr = 0;
127
128 // VGPRs inputs. These are always v0, v1 and v2 for entry functions.
129 ArgDescriptor WorkItemIDX;
130 ArgDescriptor WorkItemIDY;
131 ArgDescriptor WorkItemIDZ;
132
133 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
134 getPreloadedValue(PreloadedValue Value) const;
135};
136
137class AMDGPUArgumentUsageInfo : public ImmutablePass {
138private:
139 static const AMDGPUFunctionArgInfo ExternFunctionInfo;
140 DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap;
141
142public:
143 static char ID;
144
145 AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { }
146
147 void getAnalysisUsage(AnalysisUsage &AU) const override {
148 AU.setPreservesAll();
149 }
150
151 bool doInitialization(Module &M) override;
152 bool doFinalization(Module &M) override;
153
154 void print(raw_ostream &OS, const Module *M = nullptr) const override;
155
156 void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) {
157 ArgInfoMap[&F] = ArgInfo;
158 }
159
160 const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const {
161 auto I = ArgInfoMap.find(&F);
162 if (I == ArgInfoMap.end()) {
163 assert(F.isDeclaration());
164 return ExternFunctionInfo;
165 }
166
167 return I->second;
168 }
169};
170
171} // end namespace llvm
172
173#endif