1 //===- AMDGPUTargetTransformInfo.h - AMDGPU specific TTI --------*- 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 /// \file 10 /// This file a TargetTransformInfo::Concept conforming object specific to the 11 /// AMDGPU target machine. It uses the target's detailed information to 12 /// provide more precise answers to certain TTI queries, while letting the 13 /// target independent and default TTI implementations handle the rest. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETTRANSFORMINFO_H 18 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETTRANSFORMINFO_H 19 20 #include "AMDGPU.h" 21 #include "AMDGPUSubtarget.h" 22 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 23 #include "llvm/CodeGen/BasicTTIImpl.h" 24 25 namespace llvm { 26 27 class AMDGPUTargetLowering; 28 class AMDGPUTargetMachine; 29 class GCNSubtarget; 30 class InstCombiner; 31 class Loop; 32 class R600Subtarget; 33 class ScalarEvolution; 34 class SITargetLowering; 35 class Type; 36 class Value; 37 38 class AMDGPUTTIImpl final : public BasicTTIImplBase<AMDGPUTTIImpl> { 39 using BaseT = BasicTTIImplBase<AMDGPUTTIImpl>; 40 using TTI = TargetTransformInfo; 41 42 friend BaseT; 43 44 Triple TargetTriple; 45 46 const TargetSubtargetInfo *ST; 47 const TargetLoweringBase *TLI; 48 49 const TargetSubtargetInfo *getST() const { return ST; } 50 const TargetLoweringBase *getTLI() const { return TLI; } 51 52 public: 53 explicit AMDGPUTTIImpl(const AMDGPUTargetMachine *TM, const Function &F); 54 55 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 56 TTI::UnrollingPreferences &UP); 57 58 void getPeelingPreferences(Loop *L, ScalarEvolution &SE, 59 TTI::PeelingPreferences &PP); 60 }; 61 62 class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> { 63 using BaseT = BasicTTIImplBase<GCNTTIImpl>; 64 using TTI = TargetTransformInfo; 65 66 friend BaseT; 67 68 const GCNSubtarget *ST; 69 const SITargetLowering *TLI; 70 AMDGPUTTIImpl CommonTTI; 71 bool IsGraphics; 72 bool HasFP32Denormals; 73 bool HasFP64FP16Denormals; 74 unsigned MaxVGPRs; 75 76 static const FeatureBitset InlineFeatureIgnoreList; 77 78 const GCNSubtarget *getST() const { return ST; } 79 const SITargetLowering *getTLI() const { return TLI; } 80 81 static inline int getFullRateInstrCost() { 82 return TargetTransformInfo::TCC_Basic; 83 } 84 85 static inline int getHalfRateInstrCost( 86 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) { 87 return CostKind == TTI::TCK_CodeSize ? 2 88 : 2 * TargetTransformInfo::TCC_Basic; 89 } 90 91 // TODO: The size is usually 8 bytes, but takes 4x as many cycles. Maybe 92 // should be 2 or 4. 93 static inline int getQuarterRateInstrCost( 94 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) { 95 return CostKind == TTI::TCK_CodeSize ? 2 96 : 4 * TargetTransformInfo::TCC_Basic; 97 } 98 99 // On some parts, normal fp64 operations are half rate, and others 100 // quarter. This also applies to some integer operations. 101 int get64BitInstrCost( 102 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const; 103 104 public: 105 explicit GCNTTIImpl(const AMDGPUTargetMachine *TM, const Function &F); 106 107 bool hasBranchDivergence() { return true; } 108 bool useGPUDivergenceAnalysis() const; 109 110 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 111 TTI::UnrollingPreferences &UP); 112 113 void getPeelingPreferences(Loop *L, ScalarEvolution &SE, 114 TTI::PeelingPreferences &PP); 115 116 TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) { 117 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2"); 118 return TTI::PSK_FastHardware; 119 } 120 121 unsigned getHardwareNumberOfRegisters(bool Vector) const; 122 unsigned getNumberOfRegisters(bool Vector) const; 123 unsigned getNumberOfRegisters(unsigned RCID) const; 124 unsigned getRegisterBitWidth(bool Vector) const; 125 unsigned getMinVectorRegisterBitWidth() const; 126 unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const; 127 unsigned getLoadVectorFactor(unsigned VF, unsigned LoadSize, 128 unsigned ChainSizeInBytes, 129 VectorType *VecTy) const; 130 unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize, 131 unsigned ChainSizeInBytes, 132 VectorType *VecTy) const; 133 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const; 134 135 bool isLegalToVectorizeMemChain(unsigned ChainSizeInBytes, Align Alignment, 136 unsigned AddrSpace) const; 137 bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment, 138 unsigned AddrSpace) const; 139 bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment, 140 unsigned AddrSpace) const; 141 Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length, 142 unsigned SrcAddrSpace, unsigned DestAddrSpace, 143 unsigned SrcAlign, unsigned DestAlign) const; 144 145 void getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type *> &OpsOut, 146 LLVMContext &Context, 147 unsigned RemainingBytes, 148 unsigned SrcAddrSpace, 149 unsigned DestAddrSpace, 150 unsigned SrcAlign, 151 unsigned DestAlign) const; 152 unsigned getMaxInterleaveFactor(unsigned VF); 153 154 bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const; 155 156 int getArithmeticInstrCost( 157 unsigned Opcode, Type *Ty, 158 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput, 159 TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue, 160 TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, 161 TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, 162 TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, 163 ArrayRef<const Value *> Args = ArrayRef<const Value *>(), 164 const Instruction *CxtI = nullptr); 165 166 unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind); 167 168 bool isInlineAsmSourceOfDivergence(const CallInst *CI, 169 ArrayRef<unsigned> Indices = {}) const; 170 171 int getVectorInstrCost(unsigned Opcode, Type *ValTy, unsigned Index); 172 bool isSourceOfDivergence(const Value *V) const; 173 bool isAlwaysUniform(const Value *V) const; 174 175 unsigned getFlatAddressSpace() const { 176 // Don't bother running InferAddressSpaces pass on graphics shaders which 177 // don't use flat addressing. 178 if (IsGraphics) 179 return -1; 180 return AMDGPUAS::FLAT_ADDRESS; 181 } 182 183 bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes, 184 Intrinsic::ID IID) const; 185 Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV, 186 Value *NewV) const; 187 188 bool canSimplifyLegacyMulToMul(const Value *Op0, const Value *Op1, 189 InstCombiner &IC) const; 190 Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC, 191 IntrinsicInst &II) const; 192 Optional<Value *> simplifyDemandedVectorEltsIntrinsic( 193 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, 194 APInt &UndefElts2, APInt &UndefElts3, 195 std::function<void(Instruction *, unsigned, APInt, APInt &)> 196 SimplifyAndSetOp) const; 197 198 unsigned getVectorSplitCost() { return 0; } 199 200 unsigned getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp, 201 ArrayRef<int> Mask, int Index, VectorType *SubTp); 202 203 bool areInlineCompatible(const Function *Caller, 204 const Function *Callee) const; 205 206 unsigned getInliningThresholdMultiplier() { return 11; } 207 unsigned adjustInliningThreshold(const CallBase *CB) const; 208 209 int getInlinerVectorBonusPercent() { return 0; } 210 211 int getArithmeticReductionCost( 212 unsigned Opcode, 213 VectorType *Ty, 214 bool IsPairwise, 215 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput); 216 217 int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, 218 TTI::TargetCostKind CostKind); 219 int getMinMaxReductionCost( 220 VectorType *Ty, VectorType *CondTy, bool IsPairwiseForm, bool IsUnsigned, 221 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput); 222 }; 223 224 class R600TTIImpl final : public BasicTTIImplBase<R600TTIImpl> { 225 using BaseT = BasicTTIImplBase<R600TTIImpl>; 226 using TTI = TargetTransformInfo; 227 228 friend BaseT; 229 230 const R600Subtarget *ST; 231 const AMDGPUTargetLowering *TLI; 232 AMDGPUTTIImpl CommonTTI; 233 234 public: 235 explicit R600TTIImpl(const AMDGPUTargetMachine *TM, const Function &F); 236 237 const R600Subtarget *getST() const { return ST; } 238 const AMDGPUTargetLowering *getTLI() const { return TLI; } 239 240 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 241 TTI::UnrollingPreferences &UP); 242 void getPeelingPreferences(Loop *L, ScalarEvolution &SE, 243 TTI::PeelingPreferences &PP); 244 unsigned getHardwareNumberOfRegisters(bool Vec) const; 245 unsigned getNumberOfRegisters(bool Vec) const; 246 unsigned getRegisterBitWidth(bool Vector) const; 247 unsigned getMinVectorRegisterBitWidth() const; 248 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const; 249 bool isLegalToVectorizeMemChain(unsigned ChainSizeInBytes, Align Alignment, 250 unsigned AddrSpace) const; 251 bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment, 252 unsigned AddrSpace) const; 253 bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment, 254 unsigned AddrSpace) const; 255 unsigned getMaxInterleaveFactor(unsigned VF); 256 unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind); 257 int getVectorInstrCost(unsigned Opcode, Type *ValTy, unsigned Index); 258 }; 259 260 } // end namespace llvm 261 262 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETTRANSFORMINFO_H 263