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-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file a TargetTransformInfoImplBase conforming object specific to the
10/// X86 target machine. It uses the target's detailed information to
11/// provide more precise answers to certain TTI queries, while letting the
12/// target independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_X86_X86TARGETTRANSFORMINFO_H
17#define LLVM_LIB_TARGET_X86_X86TARGETTRANSFORMINFO_H
18
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
39public:
40 explicit X86TTIImpl(const X86TargetMachine *TM, const Function &F)
41 : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
42 TLI(ST->getTargetLowering()) {}
43
44 /// \name Scalar TTI Implementations
45 /// @{
46 TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override;
47
48 /// @}
49
50 /// \name Cache TTI Implementation
51 /// @{
52 std::optional<unsigned> getCacheSize(
53 TargetTransformInfo::CacheLevel Level) const override;
54 std::optional<unsigned> getCacheAssociativity(
55 TargetTransformInfo::CacheLevel Level) const override;
56 /// @}
57
58 /// \name Vector TTI Implementations
59 /// @{
60
61 unsigned getNumberOfRegisters(unsigned ClassID) const override;
62 unsigned getRegisterClassForType(bool Vector, Type *Ty) const override;
63 bool hasConditionalLoadStoreForType(Type *Ty, bool IsStore) const override;
64 TypeSize
65 getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
66 unsigned getLoadStoreVecRegBitWidth(unsigned AS) const override;
67 unsigned getMaxInterleaveFactor(ElementCount VF,
68 bool HasUnorderedReductions) const override;
69 InstructionCost getArithmeticInstrCost(
70 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
71 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
72 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
73 ArrayRef<const Value *> Args = {},
74 const Instruction *CtxI = nullptr) const override;
75 InstructionCost
76 getAltInstrCost(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
77 const SmallBitVector &OpcodeMask,
78 TTI::TargetCostKind CostKind,
79 ArrayRef<const Value *> Scalars) const override;
80
81 InstructionCost
82 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
83 TTI::TargetCostKind CostKind, ArrayRef<int> Mask, int Index,
84 VectorType *SubTp, ArrayRef<const Value *> Args = {},
85 const Instruction *CtxI = nullptr,
86 TTI::VectorInstrContext VIC =
87 TTI::VectorInstrContext::None) const override;
88 InstructionCost
89 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
90 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
91 const Instruction *I = nullptr) const override;
92 InstructionCost getCmpSelInstrCost(
93 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
94 TTI::TargetCostKind CostKind,
95 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
96 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
97 const Instruction *I = nullptr) const override;
98 using BaseT::getVectorInstrCost;
99 InstructionCost
100 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
101 unsigned Index, const Value *Op0, const Value *Op1,
102 TTI::VectorInstrContext VIC =
103 TTI::VectorInstrContext::None) const override;
104 InstructionCost
105 getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
106 bool Insert, bool Extract,
107 TTI::TargetCostKind CostKind,
108 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
109 TTI::VectorInstrContext VIC =
110 TTI::VectorInstrContext::None) const override;
111 InstructionCost
112 getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF,
113 const APInt &DemandedDstElts,
114 TTI::TargetCostKind CostKind) const override;
115 InstructionCost getMemoryOpCost(
116 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
117 TTI::TargetCostKind CostKind,
118 TTI::OperandValueInfo OpInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
119 const Instruction *I = nullptr) const override;
120 InstructionCost
121 getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA,
122 TTI::TargetCostKind CostKind) const override;
123 InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
124 TTI::TargetCostKind CostKind) const;
125 InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA,
126 TTI::TargetCostKind CostKind) const;
127 InstructionCost
128 getPointersChainCost(ArrayRef<const Value *> Ptrs, const Value *Base,
129 const TTI::PointersChainInfo &Info, Type *AccessTy,
130 const TTI::TargetCostKind CostKind) const override;
131 InstructionCost
132 getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr,
133 TTI::TargetCostKind CostKind) const override;
134
135 std::optional<Instruction *>
136 instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;
137 std::optional<Value *>
138 simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
139 APInt DemandedMask, KnownBits &Known,
140 bool &KnownBitsComputed) const override;
141 std::optional<Value *> simplifyDemandedVectorEltsIntrinsic(
142 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
143 APInt &UndefElts2, APInt &UndefElts3,
144 std::function<void(Instruction *, unsigned, APInt, APInt &)>
145 SimplifyAndSetOp) const override;
146
147 unsigned getAtomicMemIntrinsicMaxElementSize() const override;
148
149 InstructionCost
150 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
151 TTI::TargetCostKind CostKind) const override;
152
153 InstructionCost
154 getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
155 std::optional<FastMathFlags> FMF,
156 TTI::TargetCostKind CostKind) const override;
157
158 InstructionCost getPartialReductionCost(
159 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
160 ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
161 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
162 TTI::TargetCostKind CostKind,
163 std::optional<FastMathFlags> FMF) const override;
164
165 InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty,
166 TTI::TargetCostKind CostKind,
167 FastMathFlags FMF) const;
168
169 InstructionCost
170 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,
171 TTI::TargetCostKind CostKind) const override;
172
173 InstructionCost getInterleavedMemoryOpCost(
174 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
175 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
176 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
177 InstructionCost getInterleavedMemoryOpCostAVX512(
178 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
179 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
180 TTI::TargetCostKind CostKind, bool UseMaskForCond = false,
181 bool UseMaskForGaps = false) const;
182
183 InstructionCost getIntImmCost(int64_t) const;
184
185 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
186 TTI::TargetCostKind CostKind) const override;
187
188 InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
189 const Instruction *I = nullptr) const override;
190
191 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
192 const APInt &Imm, Type *Ty,
193 TTI::TargetCostKind CostKind,
194 Instruction *Inst = nullptr) const override;
195 InstructionCost
196 getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
197 Type *Ty, TTI::TargetCostKind CostKind) const override;
198 /// Return the cost of the scaling factor used in the addressing
199 /// mode represented by AM for this target, for a load/store
200 /// of the specified type.
201 /// If the AM is supported, the return value must be >= 0.
202 /// If the AM is not supported, it returns an invalid cost.
203 InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
204 StackOffset BaseOffset, bool HasBaseReg,
205 int64_t Scale,
206 unsigned AddrSpace) const override;
207
208 bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
209 const TargetTransformInfo::LSRCost &C2) const override;
210 bool canMacroFuseCmp() const override;
211 bool
212 isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace,
213 TTI::MaskKind MaskKind =
214 TTI::MaskKind::VariableOrConstantMask) const override;
215 bool
216 isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace,
217 TTI::MaskKind MaskKind =
218 TTI::MaskKind::VariableOrConstantMask) const override;
219 bool isLegalNTLoad(Type *DataType, Align Alignment) const override;
220 bool isLegalNTStore(Type *DataType, Align Alignment) const override;
221 bool isLegalBroadcastLoad(Type *ElementTy,
222 ElementCount NumElements) const override;
223 bool forceScalarizeMaskedGather(VectorType *VTy,
224 Align Alignment) const override;
225 bool forceScalarizeMaskedScatter(VectorType *VTy,
226 Align Alignment) const override {
227 return forceScalarizeMaskedGather(VTy, Alignment);
228 }
229 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const;
230 bool isLegalMaskedGather(Type *DataType, Align Alignment) const override;
231 bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override;
232 bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override;
233 bool isLegalMaskedCompressStore(Type *DataType,
234 Align Alignment) const override;
235 bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
236 const SmallBitVector &OpcodeMask,
237 ArrayRef<const Value *> Scalars) const override;
238 bool hasDivRemOp(Type *DataType, bool IsSigned) const override;
239 bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override;
240 bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override;
241 bool areInlineCompatible(const Function *Caller,
242 const Function *Callee) const override;
243 bool areTypesABICompatible(const Function *Caller, const Function *Callee,
244 ArrayRef<Type *> Type) const override;
245
246 uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override {
247 return ST->getMaxInlineSizeThreshold();
248 }
249
250 TTI::MemCmpExpansionOptions
251 enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override;
252 bool preferAlternateOpcodeVectorization() const override { return false; }
253 bool prefersVectorizedAddressing() const override;
254 bool supportsEfficientVectorElementLoadStore() const override;
255 bool enableInterleavedAccessVectorization() const override;
256
257 bool shouldExpandReduction(const IntrinsicInst *II) const override;
258
259 InstructionCost getBranchMispredictPenalty() const override;
260
261 bool isProfitableToSinkOperands(Instruction *I,
262 SmallVectorImpl<Use *> &Ops) const override;
263
264 bool isVectorShiftByScalarCheap(Type *Ty) const override;
265
266 unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
267 Align Alignment,
268 unsigned AddrSpace) const override;
269
270 bool useFastCCForInternalCall(Function &F) const override;
271
272private:
273 bool supportsGather() const;
274 InstructionCost getGSVectorCost(unsigned Opcode, TTI::TargetCostKind CostKind,
275 Type *DataTy, const Value *Ptr,
276 Align Alignment, unsigned AddressSpace) const;
277
278 int getGatherOverhead() const;
279 int getScatterOverhead() const;
280
281 /// @}
282};
283
284} // end namespace llvm
285
286#endif
287