342 lines · c
1//===-- X86TargetTransformInfo.h - X86 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-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// This file a TargetTransformInfoImplBase conforming object specific to the10/// X86 target machine. It uses the target's detailed information to11/// provide more precise answers to certain TTI queries, while letting the12/// target independent and default TTI implementations handle the rest.13///14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_LIB_TARGET_X86_X86TARGETTRANSFORMINFO_H17#define LLVM_LIB_TARGET_X86_X86TARGETTRANSFORMINFO_H18 19#include "X86TargetMachine.h"20#include "llvm/Analysis/TargetTransformInfo.h"21#include "llvm/CodeGen/BasicTTIImpl.h"22#include <optional>23 24namespace llvm {25 26class InstCombiner;27 28class X86TTIImpl final : public BasicTTIImplBase<X86TTIImpl> {29 typedef BasicTTIImplBase<X86TTIImpl> BaseT;30 typedef TargetTransformInfo TTI;31 friend BaseT;32 33 const X86Subtarget *ST;34 const X86TargetLowering *TLI;35 36 const X86Subtarget *getST() const { return ST; }37 const X86TargetLowering *getTLI() const { return TLI; }38 39 const FeatureBitset InlineFeatureIgnoreList = {40 // This indicates the CPU is 64 bit capable not that we are in 64-bit41 // mode.42 X86::FeatureX86_64,43 44 // These features don't have any intrinsics or ABI effect.45 X86::FeatureNOPL,46 X86::FeatureCX16,47 X86::FeatureLAHFSAHF64,48 49 // Some older targets can be setup to fold unaligned loads.50 X86::FeatureSSEUnalignedMem,51 52 // Codegen control options.53 X86::TuningFast11ByteNOP,54 X86::TuningFast15ByteNOP,55 X86::TuningFastBEXTR,56 X86::TuningFastHorizontalOps,57 X86::TuningFastLZCNT,58 X86::TuningFastScalarFSQRT,59 X86::TuningFastSHLDRotate,60 X86::TuningFastScalarShiftMasks,61 X86::TuningFastVectorShiftMasks,62 X86::TuningFastVariableCrossLaneShuffle,63 X86::TuningFastVariablePerLaneShuffle,64 X86::TuningFastVectorFSQRT,65 X86::TuningLEAForSP,66 X86::TuningLEAUsesAG,67 X86::TuningLZCNTFalseDeps,68 X86::TuningBranchFusion,69 X86::TuningMacroFusion,70 X86::TuningPadShortFunctions,71 X86::TuningPOPCNTFalseDeps,72 X86::TuningMULCFalseDeps,73 X86::TuningPERMFalseDeps,74 X86::TuningRANGEFalseDeps,75 X86::TuningGETMANTFalseDeps,76 X86::TuningMULLQFalseDeps,77 X86::TuningSlow3OpsLEA,78 X86::TuningSlowDivide32,79 X86::TuningSlowDivide64,80 X86::TuningSlowIncDec,81 X86::TuningSlowLEA,82 X86::TuningSlowPMADDWD,83 X86::TuningSlowPMULLD,84 X86::TuningSlowSHLD,85 X86::TuningSlowTwoMemOps,86 X86::TuningSlowUAMem16,87 X86::TuningPreferMaskRegisters,88 X86::TuningInsertVZEROUPPER,89 X86::TuningUseSLMArithCosts,90 X86::TuningUseGLMDivSqrtCosts,91 X86::TuningNoDomainDelay,92 X86::TuningNoDomainDelayMov,93 X86::TuningNoDomainDelayShuffle,94 X86::TuningNoDomainDelayBlend,95 X86::TuningPreferShiftShuffle,96 X86::TuningFastImmVectorShift,97 X86::TuningFastDPWSSD,98 99 // Perf-tuning flags.100 X86::TuningFastGather,101 X86::TuningSlowUAMem32,102 X86::TuningAllowLight256Bit,103 104 // Based on whether user set the -mprefer-vector-width command line.105 X86::TuningPrefer128Bit,106 X86::TuningPrefer256Bit,107 108 // CPU name enums. These just follow CPU string.109 X86::ProcIntelAtom110 };111 112public:113 explicit X86TTIImpl(const X86TargetMachine *TM, const Function &F)114 : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),115 TLI(ST->getTargetLowering()) {}116 117 /// \name Scalar TTI Implementations118 /// @{119 TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override;120 121 /// @}122 123 /// \name Cache TTI Implementation124 /// @{125 std::optional<unsigned> getCacheSize(126 TargetTransformInfo::CacheLevel Level) const override;127 std::optional<unsigned> getCacheAssociativity(128 TargetTransformInfo::CacheLevel Level) const override;129 /// @}130 131 /// \name Vector TTI Implementations132 /// @{133 134 unsigned getNumberOfRegisters(unsigned ClassID) const override;135 unsigned getRegisterClassForType(bool Vector, Type *Ty) const override;136 bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override;137 TypeSize138 getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;139 unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override;140 unsigned getMaxInterleaveFactor(ElementCount VF) const override;141 InstructionCost getArithmeticInstrCost(142 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,143 TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},144 TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},145 ArrayRef<const Value *> Args = {},146 const Instruction *CxtI = nullptr) const override;147 InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0,148 unsigned Opcode1,149 const SmallBitVector &OpcodeMask,150 TTI::TargetCostKind CostKind) const override;151 152 InstructionCost153 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,154 ArrayRef<int> Mask, TTI::TargetCostKind CostKind, int Index,155 VectorType *SubTp, ArrayRef<const Value *> Args = {},156 const Instruction *CxtI = nullptr) const override;157 InstructionCost158 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,159 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,160 const Instruction *I = nullptr) const override;161 InstructionCost getCmpSelInstrCost(162 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,163 TTI::TargetCostKind CostKind,164 TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},165 TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},166 const Instruction *I = nullptr) const override;167 using BaseT::getVectorInstrCost;168 InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,169 TTI::TargetCostKind CostKind,170 unsigned Index, const Value *Op0,171 const Value *Op1) const override;172 InstructionCost getScalarizationOverhead(173 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,174 TTI::TargetCostKind CostKind, bool ForPoisonSrc = true,175 ArrayRef<Value *> VL = {}) const override;176 InstructionCost177 getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF,178 const APInt &DemandedDstElts,179 TTI::TargetCostKind CostKind) const override;180 InstructionCost getMemoryOpCost(181 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,182 TTI::TargetCostKind CostKind,183 TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},184 const Instruction *I = nullptr) const override;185 InstructionCost186 getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,187 TTI::TargetCostKind CostKind) const override;188 InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy,189 const Value *Ptr, bool VariableMask,190 Align Alignment,191 TTI::TargetCostKind CostKind,192 const Instruction *I) const override;193 InstructionCost194 getPointersChainCost(ArrayRef<const Value *> Ptrs, const Value *Base,195 const TTI::PointersChainInfo &Info, Type *AccessTy,196 TTI::TargetCostKind CostKind) const override;197 InstructionCost198 getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr,199 TTI::TargetCostKind CostKind) const override;200 201 std::optional<Instruction *>202 instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;203 std::optional<Value *>204 simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,205 APInt DemandedMask, KnownBits &Known,206 bool &KnownBitsComputed) const override;207 std::optional<Value *> simplifyDemandedVectorEltsIntrinsic(208 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,209 APInt &UndefElts2, APInt &UndefElts3,210 std::function<void(Instruction *, unsigned, APInt, APInt &)>211 SimplifyAndSetOp) const override;212 213 unsigned getAtomicMemIntrinsicMaxElementSize() const override;214 215 InstructionCost216 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,217 TTI::TargetCostKind CostKind) const override;218 219 InstructionCost220 getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,221 std::optional<FastMathFlags> FMF,222 TTI::TargetCostKind CostKind) const override;223 224 InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty,225 TTI::TargetCostKind CostKind,226 FastMathFlags FMF) const;227 228 InstructionCost229 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,230 TTI::TargetCostKind CostKind) const override;231 232 InstructionCost getInterleavedMemoryOpCost(233 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,234 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,235 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;236 InstructionCost getInterleavedMemoryOpCostAVX512(237 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,238 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,239 TTI::TargetCostKind CostKind, bool UseMaskForCond = false,240 bool UseMaskForGaps = false) const;241 242 InstructionCost getIntImmCost(int64_t) const;243 244 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,245 TTI::TargetCostKind CostKind) const override;246 247 InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,248 const Instruction *I = nullptr) const override;249 250 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,251 const APInt &Imm, Type *Ty,252 TTI::TargetCostKind CostKind,253 Instruction *Inst = nullptr) const override;254 InstructionCost255 getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,256 Type *Ty, TTI::TargetCostKind CostKind) const override;257 /// Return the cost of the scaling factor used in the addressing258 /// mode represented by AM for this target, for a load/store259 /// of the specified type.260 /// If the AM is supported, the return value must be >= 0.261 /// If the AM is not supported, it returns an invalid cost.262 InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,263 StackOffset BaseOffset, bool HasBaseReg,264 int64_t Scale,265 unsigned AddrSpace) const override;266 267 bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,268 const TargetTransformInfo::LSRCost &C2) const override;269 bool canMacroFuseCmp() const override;270 bool271 isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace,272 TTI::MaskKind MaskKind =273 TTI::MaskKind::VariableOrConstantMask) const override;274 bool275 isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace,276 TTI::MaskKind MaskKind =277 TTI::MaskKind::VariableOrConstantMask) const override;278 bool isLegalNTLoad(Type *DataType, Align Alignment) const override;279 bool isLegalNTStore(Type *DataType, Align Alignment) const override;280 bool isLegalBroadcastLoad(Type *ElementTy,281 ElementCount NumElements) const override;282 bool forceScalarizeMaskedGather(VectorType *VTy,283 Align Alignment) const override;284 bool forceScalarizeMaskedScatter(VectorType *VTy,285 Align Alignment) const override {286 return forceScalarizeMaskedGather(VTy, Alignment);287 }288 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const;289 bool isLegalMaskedGather(Type *DataType, Align Alignment) const override;290 bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override;291 bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override;292 bool isLegalMaskedCompressStore(Type *DataType,293 Align Alignment) const override;294 bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,295 const SmallBitVector &OpcodeMask) const override;296 bool hasDivRemOp(Type *DataType, bool IsSigned) const override;297 bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override;298 bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override;299 bool areInlineCompatible(const Function *Caller,300 const Function *Callee) const override;301 bool areTypesABICompatible(const Function *Caller, const Function *Callee,302 ArrayRef<Type *> Type) const override;303 304 uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override {305 return ST->getMaxInlineSizeThreshold();306 }307 308 TTI::MemCmpExpansionOptions309 enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override;310 bool preferAlternateOpcodeVectorization() const override { return false; }311 bool prefersVectorizedAddressing() const override;312 bool supportsEfficientVectorElementLoadStore() const override;313 bool enableInterleavedAccessVectorization() const override;314 315 InstructionCost getBranchMispredictPenalty() const override;316 317 bool isProfitableToSinkOperands(Instruction *I,318 SmallVectorImpl<Use *> &Ops) const override;319 320 bool isVectorShiftByScalarCheap(Type *Ty) const override;321 322 unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,323 Type *ScalarValTy) const override;324 325 bool useFastCCForInternalCall(Function &F) const override;326 327private:328 bool supportsGather() const;329 InstructionCost getGSVectorCost(unsigned Opcode, TTI::TargetCostKind CostKind,330 Type *DataTy, const Value *Ptr,331 Align Alignment, unsigned AddressSpace) const;332 333 int getGatherOverhead() const;334 int getScatterOverhead() const;335 336 /// @}337};338 339} // end namespace llvm340 341#endif342