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/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 Register Reg; 33 unsigned StackOffset; 34 }; 35 36 // Bitmask to locate argument within the register. 37 unsigned Mask; 38 39 bool IsStack : 1; 40 bool IsSet : 1; 41 42 public: 43 constexpr ArgDescriptor(unsigned Val = 0, unsigned Mask = ~0u, 44 bool IsStack = false, bool IsSet = false) 45 : Reg(Val), Mask(Mask), IsStack(IsStack), IsSet(IsSet) {} 46 47 static constexpr ArgDescriptor createRegister(Register Reg, 48 unsigned Mask = ~0u) { 49 return ArgDescriptor(Reg, Mask, false, true); 50 } 51 52 static constexpr ArgDescriptor createStack(unsigned Offset, 53 unsigned Mask = ~0u) { 54 return ArgDescriptor(Offset, Mask, true, true); 55 } 56 57 static constexpr ArgDescriptor createArg(const ArgDescriptor &Arg, 58 unsigned Mask) { 59 return ArgDescriptor(Arg.Reg, Mask, Arg.IsStack, Arg.IsSet); 60 } 61 62 bool isSet() const { 63 return IsSet; 64 } 65 66 explicit operator bool() const { 67 return isSet(); 68 } 69 70 bool isRegister() const { 71 return !IsStack; 72 } 73 74 Register getRegister() const { 75 assert(!IsStack); 76 return Reg; 77 } 78 79 unsigned getStackOffset() const { 80 assert(IsStack); 81 return StackOffset; 82 } 83 84 unsigned getMask() const { 85 return Mask; 86 } 87 88 bool isMasked() const { 89 return Mask != ~0u; 90 } 91 92 void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const; 93 }; 94 95 inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) { 96 Arg.print(OS); 97 return OS; 98 } 99 100 struct AMDGPUFunctionArgInfo { 101 enum PreloadedValue { 102 // SGPRS: 103 PRIVATE_SEGMENT_BUFFER = 0, 104 DISPATCH_PTR = 1, 105 QUEUE_PTR = 2, 106 KERNARG_SEGMENT_PTR = 3, 107 DISPATCH_ID = 4, 108 FLAT_SCRATCH_INIT = 5, 109 WORKGROUP_ID_X = 10, 110 WORKGROUP_ID_Y = 11, 111 WORKGROUP_ID_Z = 12, 112 PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14, 113 IMPLICIT_BUFFER_PTR = 15, 114 IMPLICIT_ARG_PTR = 16, 115 116 // VGPRS: 117 WORKITEM_ID_X = 17, 118 WORKITEM_ID_Y = 18, 119 WORKITEM_ID_Z = 19, 120 FIRST_VGPR_VALUE = WORKITEM_ID_X 121 }; 122 123 // Kernel input registers setup for the HSA ABI in allocation order. 124 125 // User SGPRs in kernels 126 // XXX - Can these require argument spills? 127 ArgDescriptor PrivateSegmentBuffer; 128 ArgDescriptor DispatchPtr; 129 ArgDescriptor QueuePtr; 130 ArgDescriptor KernargSegmentPtr; 131 ArgDescriptor DispatchID; 132 ArgDescriptor FlatScratchInit; 133 ArgDescriptor PrivateSegmentSize; 134 135 // System SGPRs in kernels. 136 ArgDescriptor WorkGroupIDX; 137 ArgDescriptor WorkGroupIDY; 138 ArgDescriptor WorkGroupIDZ; 139 ArgDescriptor WorkGroupInfo; 140 ArgDescriptor PrivateSegmentWaveByteOffset; 141 142 // Pointer with offset from kernargsegmentptr to where special ABI arguments 143 // are passed to callable functions. 144 ArgDescriptor ImplicitArgPtr; 145 146 // Input registers for non-HSA ABI 147 ArgDescriptor ImplicitBufferPtr; 148 149 // VGPRs inputs. These are always v0, v1 and v2 for entry functions. 150 ArgDescriptor WorkItemIDX; 151 ArgDescriptor WorkItemIDY; 152 ArgDescriptor WorkItemIDZ; 153 154 std::pair<const ArgDescriptor *, const TargetRegisterClass *> 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