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