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