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 LDS_KERNEL_ID = 6, // LLVM internal, not part of the ABI 107 WORKGROUP_ID_X = 10, 108 WORKGROUP_ID_Y = 11, 109 WORKGROUP_ID_Z = 12, 110 PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14, 111 IMPLICIT_BUFFER_PTR = 15, 112 IMPLICIT_ARG_PTR = 16, 113 114 // VGPRS: 115 WORKITEM_ID_X = 17, 116 WORKITEM_ID_Y = 18, 117 WORKITEM_ID_Z = 19, 118 FIRST_VGPR_VALUE = WORKITEM_ID_X 119 }; 120 121 // Kernel input registers setup for the HSA ABI in allocation order. 122 123 // User SGPRs in kernels 124 // XXX - Can these require argument spills? 125 ArgDescriptor PrivateSegmentBuffer; 126 ArgDescriptor DispatchPtr; 127 ArgDescriptor QueuePtr; 128 ArgDescriptor KernargSegmentPtr; 129 ArgDescriptor DispatchID; 130 ArgDescriptor FlatScratchInit; 131 ArgDescriptor PrivateSegmentSize; 132 ArgDescriptor LDSKernelId; 133 134 // System SGPRs in kernels. 135 ArgDescriptor WorkGroupIDX; 136 ArgDescriptor WorkGroupIDY; 137 ArgDescriptor WorkGroupIDZ; 138 ArgDescriptor WorkGroupInfo; 139 ArgDescriptor PrivateSegmentWaveByteOffset; 140 141 // Pointer with offset from kernargsegmentptr to where special ABI arguments 142 // are passed to callable functions. 143 ArgDescriptor ImplicitArgPtr; 144 145 // Input registers for non-HSA ABI 146 ArgDescriptor ImplicitBufferPtr; 147 148 // VGPRs inputs. For entry functions these are either v0, v1 and v2 or packed 149 // into v0, 10 bits per dimension if packed-tid is set. 150 ArgDescriptor WorkItemIDX; 151 ArgDescriptor WorkItemIDY; 152 ArgDescriptor WorkItemIDZ; 153 154 std::tuple<const ArgDescriptor *, const TargetRegisterClass *, LLT> 155 getPreloadedValue(PreloadedValue Value) const; 156 157 static constexpr AMDGPUFunctionArgInfo fixedABILayout(); 158 }; 159 160 class AMDGPUArgumentUsageInfo : public ImmutablePass { 161 private: 162 DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap; 163 164 public: 165 static char ID; 166 167 static const AMDGPUFunctionArgInfo ExternFunctionInfo; 168 static const AMDGPUFunctionArgInfo FixedABIFunctionInfo; 169 170 AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { } 171 172 void getAnalysisUsage(AnalysisUsage &AU) const override { 173 AU.setPreservesAll(); 174 } 175 176 bool doInitialization(Module &M) override; 177 bool doFinalization(Module &M) override; 178 179 void print(raw_ostream &OS, const Module *M = nullptr) const override; 180 181 void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) { 182 ArgInfoMap[&F] = ArgInfo; 183 } 184 185 const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const; 186 }; 187 188 } // end namespace llvm 189 190 #endif 191