blob: 9373b80e87bbb47af54d9f4f15434e3c422f16a1 [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;
29
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;
113 ArgDescriptor GridWorkGroupCountX;
114 ArgDescriptor GridWorkGroupCountY;
115 ArgDescriptor GridWorkGroupCountZ;
116
117 // System SGPRs in kernels.
118 ArgDescriptor WorkGroupIDX;
119 ArgDescriptor WorkGroupIDY;
120 ArgDescriptor WorkGroupIDZ;
121 ArgDescriptor WorkGroupInfo;
122 ArgDescriptor PrivateSegmentWaveByteOffset;
123
Matt Arsenault817c2532017-08-03 23:12:44 +0000124 // Pointer with offset from kernargsegmentptr to where special ABI arguments
125 // are passed to callable functions.
126 ArgDescriptor ImplicitArgPtr;
127
Matt Arsenault7016f132017-08-03 22:30:46 +0000128 // Input registers for non-HSA ABI
129 ArgDescriptor ImplicitBufferPtr = 0;
130
131 // VGPRs inputs. These are always v0, v1 and v2 for entry functions.
132 ArgDescriptor WorkItemIDX;
133 ArgDescriptor WorkItemIDY;
134 ArgDescriptor WorkItemIDZ;
135
136 std::pair<const ArgDescriptor *, const TargetRegisterClass *>
137 getPreloadedValue(PreloadedValue Value) const;
138};
139
140class AMDGPUArgumentUsageInfo : public ImmutablePass {
141private:
142 static const AMDGPUFunctionArgInfo ExternFunctionInfo;
143 DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap;
144
145public:
146 static char ID;
147
148 AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { }
149
150 void getAnalysisUsage(AnalysisUsage &AU) const override {
151 AU.setPreservesAll();
152 }
153
154 bool doInitialization(Module &M) override;
155 bool doFinalization(Module &M) override;
156
157 void print(raw_ostream &OS, const Module *M = nullptr) const override;
158
159 void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) {
160 ArgInfoMap[&F] = ArgInfo;
161 }
162
163 const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const {
164 auto I = ArgInfoMap.find(&F);
165 if (I == ArgInfoMap.end()) {
166 assert(F.isDeclaration());
167 return ExternFunctionInfo;
168 }
169
170 return I->second;
171 }
172};
173
174} // end namespace llvm
175
176#endif