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