• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //==- 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 
17 namespace llvm {
18 
19 class Function;
20 class raw_ostream;
21 class GCNSubtarget;
22 class TargetMachine;
23 class TargetRegisterClass;
24 class TargetRegisterInfo;
25 
26 struct ArgDescriptor {
27 private:
28   friend struct AMDGPUFunctionArgInfo;
29   friend class AMDGPUArgumentUsageInfo;
30 
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)
RegisterArgDescriptor40     : Register(Val), IsStack(IsStack), IsSet(IsSet) {}
41 public:
createRegisterArgDescriptor42   static ArgDescriptor createRegister(unsigned Reg) {
43     return ArgDescriptor(Reg, false, true);
44   }
45 
createStackArgDescriptor46   static ArgDescriptor createStack(unsigned Reg) {
47     return ArgDescriptor(Reg, true, true);
48   }
49 
isSetArgDescriptor50   bool isSet() const {
51     return IsSet;
52   }
53 
54   explicit operator bool() const {
55     return isSet();
56   }
57 
isRegisterArgDescriptor58   bool isRegister() const {
59     return !IsStack;
60   }
61 
getRegisterArgDescriptor62   unsigned getRegister() const {
63     assert(!IsStack);
64     return Register;
65   }
66 
getStackOffsetArgDescriptor67   unsigned getStackOffset() const {
68     assert(IsStack);
69     return StackOffset;
70   }
71 
72   void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const;
73 };
74 
75 inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) {
76   Arg.print(OS);
77   return OS;
78 }
79 
80 struct 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,
94     IMPLICIT_ARG_PTR = 16,
95 
96     // VGPRS:
97     WORKITEM_ID_X       = 17,
98     WORKITEM_ID_Y       = 18,
99     WORKITEM_ID_Z       = 19,
100     FIRST_VGPR_VALUE    = WORKITEM_ID_X
101   };
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 
115   // System SGPRs in kernels.
116   ArgDescriptor WorkGroupIDX;
117   ArgDescriptor WorkGroupIDY;
118   ArgDescriptor WorkGroupIDZ;
119   ArgDescriptor WorkGroupInfo;
120   ArgDescriptor PrivateSegmentWaveByteOffset;
121 
122   // Pointer with offset from kernargsegmentptr to where special ABI arguments
123   // are passed to callable functions.
124   ArgDescriptor ImplicitArgPtr;
125 
126   // 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 
138 class AMDGPUArgumentUsageInfo : public ImmutablePass {
139 private:
140   static const AMDGPUFunctionArgInfo ExternFunctionInfo;
141   DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap;
142 
143 public:
144   static char ID;
145 
AMDGPUArgumentUsageInfo()146   AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { }
147 
getAnalysisUsage(AnalysisUsage & AU)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 
setFuncArgInfo(const Function & F,const AMDGPUFunctionArgInfo & ArgInfo)157   void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) {
158     ArgInfoMap[&F] = ArgInfo;
159   }
160 
lookupFuncArgInfo(const Function & F)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
175