1 //==- AMDGPUArgumentrUsageInfo.h - Function Arg Usage Info -------*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUARGUMENTUSAGEINFO_H 10 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUARGUMENTUSAGEINFO_H 11 12 #include "llvm/CodeGen/Register.h" 13 #include "llvm/Pass.h" 14 15 namespace llvm { 16 17 class Function; 18 class LLT; 19 class raw_ostream; 20 class TargetRegisterClass; 21 class TargetRegisterInfo; 22 23 struct ArgDescriptor { 24 private: 25 friend struct AMDGPUFunctionArgInfo; 26 friend class AMDGPUArgumentUsageInfo; 27 28 union { 29 MCRegister Reg; 30 unsigned StackOffset; 31 }; 32 33 // Bitmask to locate argument within the register. 34 unsigned Mask; 35 36 bool IsStack : 1; 37 bool IsSet : 1; 38 39 public: 40 constexpr ArgDescriptor(unsigned Val = 0, unsigned Mask = ~0u, 41 bool IsStack = false, bool IsSet = false) 42 : Reg(Val), Mask(Mask), IsStack(IsStack), IsSet(IsSet) {} 43 44 static constexpr ArgDescriptor createRegister(Register Reg, 45 unsigned Mask = ~0u) { 46 return ArgDescriptor(Reg, Mask, false, true); 47 } 48 49 static constexpr ArgDescriptor createStack(unsigned Offset, 50 unsigned Mask = ~0u) { 51 return ArgDescriptor(Offset, Mask, true, true); 52 } 53 54 static constexpr ArgDescriptor createArg(const ArgDescriptor &Arg, 55 unsigned Mask) { 56 return ArgDescriptor(Arg.Reg, Mask, Arg.IsStack, Arg.IsSet); 57 } 58 59 bool isSet() const { 60 return IsSet; 61 } 62 63 explicit operator bool() const { 64 return isSet(); 65 } 66 67 bool isRegister() const { 68 return !IsStack; 69 } 70 71 MCRegister getRegister() const { 72 assert(!IsStack); 73 return Reg; 74 } 75 76 unsigned getStackOffset() const { 77 assert(IsStack); 78 return StackOffset; 79 } 80 81 unsigned getMask() const { 82 return Mask; 83 } 84 85 bool isMasked() const { 86 return Mask != ~0u; 87 } 88 89 void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const; 90 }; 91 92 inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) { 93 Arg.print(OS); 94 return OS; 95 } 96 97 struct AMDGPUFunctionArgInfo { 98 enum PreloadedValue { 99 // SGPRS: 100 PRIVATE_SEGMENT_BUFFER = 0, 101 DISPATCH_PTR = 1, 102 QUEUE_PTR = 2, 103 KERNARG_SEGMENT_PTR = 3, 104 DISPATCH_ID = 4, 105 FLAT_SCRATCH_INIT = 5, 106 WORKGROUP_ID_X = 10, 107 WORKGROUP_ID_Y = 11, 108 WORKGROUP_ID_Z = 12, 109 PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14, 110 IMPLICIT_BUFFER_PTR = 15, 111 IMPLICIT_ARG_PTR = 16, 112 113 // VGPRS: 114 WORKITEM_ID_X = 17, 115 WORKITEM_ID_Y = 18, 116 WORKITEM_ID_Z = 19, 117 FIRST_VGPR_VALUE = WORKITEM_ID_X 118 }; 119 120 // Kernel input registers setup for the HSA ABI in allocation order. 121 122 // User SGPRs in kernels 123 // XXX - Can these require argument spills? 124 ArgDescriptor PrivateSegmentBuffer; 125 ArgDescriptor DispatchPtr; 126 ArgDescriptor QueuePtr; 127 ArgDescriptor KernargSegmentPtr; 128 ArgDescriptor DispatchID; 129 ArgDescriptor FlatScratchInit; 130 ArgDescriptor PrivateSegmentSize; 131 132 // System SGPRs in kernels. 133 ArgDescriptor WorkGroupIDX; 134 ArgDescriptor WorkGroupIDY; 135 ArgDescriptor WorkGroupIDZ; 136 ArgDescriptor WorkGroupInfo; 137 ArgDescriptor PrivateSegmentWaveByteOffset; 138 139 // Pointer with offset from kernargsegmentptr to where special ABI arguments 140 // are passed to callable functions. 141 ArgDescriptor ImplicitArgPtr; 142 143 // Input registers for non-HSA ABI 144 ArgDescriptor ImplicitBufferPtr; 145 146 // VGPRs inputs. For entry functions these are either v0, v1 and v2 or packed 147 // into v0, 10 bits per dimension if packed-tid is set. 148 ArgDescriptor WorkItemIDX; 149 ArgDescriptor WorkItemIDY; 150 ArgDescriptor WorkItemIDZ; 151 152 std::tuple<const ArgDescriptor *, const TargetRegisterClass *, LLT> 153 getPreloadedValue(PreloadedValue Value) const; 154 155 static constexpr AMDGPUFunctionArgInfo fixedABILayout(); 156 }; 157 158 class AMDGPUArgumentUsageInfo : public ImmutablePass { 159 private: 160 DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap; 161 162 public: 163 static char ID; 164 165 static const AMDGPUFunctionArgInfo ExternFunctionInfo; 166 static const AMDGPUFunctionArgInfo FixedABIFunctionInfo; 167 168 AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { } 169 170 void getAnalysisUsage(AnalysisUsage &AU) const override { 171 AU.setPreservesAll(); 172 } 173 174 bool doInitialization(Module &M) override; 175 bool doFinalization(Module &M) override; 176 177 void print(raw_ostream &OS, const Module *M = nullptr) const override; 178 179 void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) { 180 ArgInfoMap[&F] = ArgInfo; 181 } 182 183 const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const; 184 }; 185 186 } // end namespace llvm 187 188 #endif 189