1 //===- AMDGPUTargetTransformInfo.h - AMDGPU specific TTI --------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// This file a TargetTransformInfo::Concept conforming object specific to the 12 /// AMDGPU target machine. It uses the target's detailed information to 13 /// provide more precise answers to certain TTI queries, while letting the 14 /// target independent and default TTI implementations handle the rest. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETTRANSFORMINFO_H 19 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETTRANSFORMINFO_H 20 21 #include "AMDGPU.h" 22 #include "AMDGPUSubtarget.h" 23 #include "AMDGPUTargetMachine.h" 24 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 25 #include "Utils/AMDGPUBaseInfo.h" 26 #include "llvm/ADT/ArrayRef.h" 27 #include "llvm/Analysis/TargetTransformInfo.h" 28 #include "llvm/CodeGen/BasicTTIImpl.h" 29 #include "llvm/IR/Function.h" 30 #include "llvm/MC/SubtargetFeature.h" 31 #include "llvm/Support/MathExtras.h" 32 #include <cassert> 33 34 namespace llvm { 35 36 class AMDGPUTargetLowering; 37 class Loop; 38 class ScalarEvolution; 39 class Type; 40 class Value; 41 42 class AMDGPUTTIImpl final : public BasicTTIImplBase<AMDGPUTTIImpl> { 43 using BaseT = BasicTTIImplBase<AMDGPUTTIImpl>; 44 using TTI = TargetTransformInfo; 45 46 friend BaseT; 47 48 const AMDGPUSubtarget *ST; 49 const AMDGPUTargetLowering *TLI; 50 51 public: 52 explicit AMDGPUTTIImpl(const AMDGPUTargetMachine *TM, const Function &F) 53 : BaseT(TM, F.getParent()->getDataLayout()), 54 ST(TM->getSubtargetImpl(F)), 55 TLI(ST->getTargetLowering()) {} 56 57 const AMDGPUSubtarget *getST() const { return ST; } 58 const AMDGPUTargetLowering *getTLI() const { return TLI; } 59 60 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 61 TTI::UnrollingPreferences &UP); 62 }; 63 64 class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> { 65 using BaseT = BasicTTIImplBase<GCNTTIImpl>; 66 using TTI = TargetTransformInfo; 67 68 friend BaseT; 69 70 const AMDGPUSubtarget *ST; 71 const AMDGPUTargetLowering *TLI; 72 AMDGPUTTIImpl CommonTTI; 73 bool IsGraphicsShader; 74 75 const FeatureBitset InlineFeatureIgnoreList = { 76 // Codegen control options which don't matter. 77 AMDGPU::FeatureEnableLoadStoreOpt, 78 AMDGPU::FeatureEnableSIScheduler, 79 AMDGPU::FeatureEnableUnsafeDSOffsetFolding, 80 AMDGPU::FeatureFlatForGlobal, 81 AMDGPU::FeaturePromoteAlloca, 82 AMDGPU::FeatureUnalignedBufferAccess, 83 AMDGPU::FeatureUnalignedScratchAccess, 84 85 AMDGPU::FeatureAutoWaitcntBeforeBarrier, 86 AMDGPU::FeatureDebuggerEmitPrologue, 87 AMDGPU::FeatureDebuggerInsertNops, 88 89 // Property of the kernel/environment which can't actually differ. 90 AMDGPU::FeatureSGPRInitBug, 91 AMDGPU::FeatureXNACK, 92 AMDGPU::FeatureTrapHandler, 93 94 // Perf-tuning features 95 AMDGPU::FeatureFastFMAF32, 96 AMDGPU::HalfRate64Ops 97 }; 98 99 const AMDGPUSubtarget *getST() const { return ST; } 100 const AMDGPUTargetLowering *getTLI() const { return TLI; } 101 102 static inline int getFullRateInstrCost() { 103 return TargetTransformInfo::TCC_Basic; 104 } 105 106 static inline int getHalfRateInstrCost() { 107 return 2 * TargetTransformInfo::TCC_Basic; 108 } 109 110 // TODO: The size is usually 8 bytes, but takes 4x as many cycles. Maybe 111 // should be 2 or 4. 112 static inline int getQuarterRateInstrCost() { 113 return 3 * TargetTransformInfo::TCC_Basic; 114 } 115 116 // On some parts, normal fp64 operations are half rate, and others 117 // quarter. This also applies to some integer operations. 118 inline int get64BitInstrCost() const { 119 return ST->hasHalfRate64Ops() ? 120 getHalfRateInstrCost() : getQuarterRateInstrCost(); 121 } 122 123 public: 124 explicit GCNTTIImpl(const AMDGPUTargetMachine *TM, const Function &F) 125 : BaseT(TM, F.getParent()->getDataLayout()), 126 ST(TM->getSubtargetImpl(F)), 127 TLI(ST->getTargetLowering()), 128 CommonTTI(TM, F), 129 IsGraphicsShader(AMDGPU::isShader(F.getCallingConv())) {} 130 131 bool hasBranchDivergence() { return true; } 132 133 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 134 TTI::UnrollingPreferences &UP); 135 136 TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) { 137 assert(isPowerOf2_32(TyWidth) && "Ty width must be power of 2"); 138 return TTI::PSK_FastHardware; 139 } 140 141 unsigned getHardwareNumberOfRegisters(bool Vector) const; 142 unsigned getNumberOfRegisters(bool Vector) const; 143 unsigned getRegisterBitWidth(bool Vector) const; 144 unsigned getMinVectorRegisterBitWidth() const; 145 unsigned getLoadVectorFactor(unsigned VF, unsigned LoadSize, 146 unsigned ChainSizeInBytes, 147 VectorType *VecTy) const; 148 unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize, 149 unsigned ChainSizeInBytes, 150 VectorType *VecTy) const; 151 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const; 152 153 bool isLegalToVectorizeMemChain(unsigned ChainSizeInBytes, 154 unsigned Alignment, 155 unsigned AddrSpace) const; 156 bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, 157 unsigned Alignment, 158 unsigned AddrSpace) const; 159 bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, 160 unsigned Alignment, 161 unsigned AddrSpace) const; 162 163 unsigned getMaxInterleaveFactor(unsigned VF); 164 165 bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const; 166 167 int getArithmeticInstrCost( 168 unsigned Opcode, Type *Ty, 169 TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue, 170 TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue, 171 TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None, 172 TTI::OperandValueProperties Opd2PropInfo = TTI::OP_None, 173 ArrayRef<const Value *> Args = ArrayRef<const Value *>()); 174 175 unsigned getCFInstrCost(unsigned Opcode); 176 177 int getVectorInstrCost(unsigned Opcode, Type *ValTy, unsigned Index); 178 bool isSourceOfDivergence(const Value *V) const; 179 bool isAlwaysUniform(const Value *V) const; 180 181 unsigned getFlatAddressSpace() const { 182 // Don't bother running InferAddressSpaces pass on graphics shaders which 183 // don't use flat addressing. 184 if (IsGraphicsShader) 185 return -1; 186 return ST->hasFlatAddressSpace() ? 187 ST->getAMDGPUAS().FLAT_ADDRESS : ST->getAMDGPUAS().UNKNOWN_ADDRESS_SPACE; 188 } 189 190 unsigned getVectorSplitCost() { return 0; } 191 192 unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index, 193 Type *SubTp); 194 195 bool areInlineCompatible(const Function *Caller, 196 const Function *Callee) const; 197 198 unsigned getInliningThresholdMultiplier() { return 9; } 199 200 int getArithmeticReductionCost(unsigned Opcode, 201 Type *Ty, 202 bool IsPairwise); 203 int getMinMaxReductionCost(Type *Ty, Type *CondTy, 204 bool IsPairwiseForm, 205 bool IsUnsigned); 206 }; 207 208 class R600TTIImpl final : public BasicTTIImplBase<R600TTIImpl> { 209 using BaseT = BasicTTIImplBase<R600TTIImpl>; 210 using TTI = TargetTransformInfo; 211 212 friend BaseT; 213 214 const AMDGPUSubtarget *ST; 215 const AMDGPUTargetLowering *TLI; 216 AMDGPUTTIImpl CommonTTI; 217 218 public: 219 explicit R600TTIImpl(const AMDGPUTargetMachine *TM, const Function &F) 220 : BaseT(TM, F.getParent()->getDataLayout()), 221 ST(TM->getSubtargetImpl(F)), 222 TLI(ST->getTargetLowering()), 223 CommonTTI(TM, F) {} 224 225 const AMDGPUSubtarget *getST() const { return ST; } 226 const AMDGPUTargetLowering *getTLI() const { return TLI; } 227 228 void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, 229 TTI::UnrollingPreferences &UP); 230 unsigned getHardwareNumberOfRegisters(bool Vec) const; 231 unsigned getNumberOfRegisters(bool Vec) const; 232 unsigned getRegisterBitWidth(bool Vector) const; 233 unsigned getMinVectorRegisterBitWidth() const; 234 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const; 235 bool isLegalToVectorizeMemChain(unsigned ChainSizeInBytes, unsigned Alignment, 236 unsigned AddrSpace) const; 237 bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, 238 unsigned Alignment, 239 unsigned AddrSpace) const; 240 bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, 241 unsigned Alignment, 242 unsigned AddrSpace) const; 243 unsigned getMaxInterleaveFactor(unsigned VF); 244 unsigned getCFInstrCost(unsigned Opcode); 245 int getVectorInstrCost(unsigned Opcode, Type *ValTy, unsigned Index); 246 }; 247 248 } // end namespace llvm 249 250 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETTRANSFORMINFO_H 251