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