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 *CxtI = nullptr) const override;
75 InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0,
76 unsigned Opcode1,
77 const SmallBitVector &OpcodeMask,
78 TTI::TargetCostKind CostKind) const override;
79
80 InstructionCost
81 getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,
82 ArrayRef<int> Mask, TTI::TargetCostKind CostKind, int Index,
83 VectorType *SubTp, ArrayRef<const Value *> Args = {},
84 const Instruction *CxtI = nullptr) const override;
85 InstructionCost
86 getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
87 TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,
88 const Instruction *I = nullptr) const override;
89 InstructionCost getCmpSelInstrCost(
90 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
91 TTI::TargetCostKind CostKind,
92 TTI::OperandValueInfo Op1Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
93 TTI::OperandValueInfo Op2Info = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
94 const Instruction *I = nullptr) const override;
95 using BaseT::getVectorInstrCost;
96 InstructionCost
97 getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind,
98 unsigned Index, const Value *Op0, const Value *Op1,
99 TTI::VectorInstrContext VIC =
100 TTI::VectorInstrContext::None) const override;
101 InstructionCost
102 getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
103 bool Insert, bool Extract,
104 TTI::TargetCostKind CostKind,
105 bool ForPoisonSrc = true, ArrayRef<Value *> VL = {},
106 TTI::VectorInstrContext VIC =
107 TTI::VectorInstrContext::None) const override;
108 InstructionCost
109 getReplicationShuffleCost(Type *EltTy, int ReplicationFactor, int VF,
110 const APInt &DemandedDstElts,
111 TTI::TargetCostKind CostKind) const override;
112 InstructionCost getMemoryOpCost(
113 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
114 TTI::TargetCostKind CostKind,
115 TTI::OperandValueInfo OpInfo = {.Kind: TTI::OK_AnyValue, .Properties: TTI::OP_None},
116 const Instruction *I = nullptr) const override;
117 InstructionCost
118 getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA,
119 TTI::TargetCostKind CostKind) const override;
120 InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,
121 TTI::TargetCostKind CostKind) const;
122 InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA,
123 TTI::TargetCostKind CostKind) const;
124 InstructionCost
125 getPointersChainCost(ArrayRef<const Value *> Ptrs, const Value *Base,
126 const TTI::PointersChainInfo &Info, Type *AccessTy,
127 TTI::TargetCostKind CostKind) const override;
128 InstructionCost
129 getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE, const SCEV *Ptr,
130 TTI::TargetCostKind CostKind) const override;
131
132 std::optional<Instruction *>
133 instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;
134 std::optional<Value *>
135 simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
136 APInt DemandedMask, KnownBits &Known,
137 bool &KnownBitsComputed) const override;
138 std::optional<Value *> simplifyDemandedVectorEltsIntrinsic(
139 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
140 APInt &UndefElts2, APInt &UndefElts3,
141 std::function<void(Instruction *, unsigned, APInt, APInt &)>
142 SimplifyAndSetOp) const override;
143
144 unsigned getAtomicMemIntrinsicMaxElementSize() const override;
145
146 InstructionCost
147 getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
148 TTI::TargetCostKind CostKind) const override;
149
150 InstructionCost
151 getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
152 std::optional<FastMathFlags> FMF,
153 TTI::TargetCostKind CostKind) const override;
154
155 InstructionCost getPartialReductionCost(
156 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
157 ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
158 TTI::PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
159 TTI::TargetCostKind CostKind,
160 std::optional<FastMathFlags> FMF) const override {
161 return InstructionCost::getInvalid();
162 }
163
164 InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty,
165 TTI::TargetCostKind CostKind,
166 FastMathFlags FMF) const;
167
168 InstructionCost
169 getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,
170 TTI::TargetCostKind CostKind) const override;
171
172 InstructionCost getInterleavedMemoryOpCost(
173 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
174 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
175 bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;
176 InstructionCost getInterleavedMemoryOpCostAVX512(
177 unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
178 ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
179 TTI::TargetCostKind CostKind, bool UseMaskForCond = false,
180 bool UseMaskForGaps = false) const;
181
182 InstructionCost getIntImmCost(int64_t) const;
183
184 InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
185 TTI::TargetCostKind CostKind) const override;
186
187 InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
188 const Instruction *I = nullptr) const override;
189
190 InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
191 const APInt &Imm, Type *Ty,
192 TTI::TargetCostKind CostKind,
193 Instruction *Inst = nullptr) const override;
194 InstructionCost
195 getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
196 Type *Ty, TTI::TargetCostKind CostKind) const override;
197 /// Return the cost of the scaling factor used in the addressing
198 /// mode represented by AM for this target, for a load/store
199 /// of the specified type.
200 /// If the AM is supported, the return value must be >= 0.
201 /// If the AM is not supported, it returns an invalid cost.
202 InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
203 StackOffset BaseOffset, bool HasBaseReg,
204 int64_t Scale,
205 unsigned AddrSpace) const override;
206
207 bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
208 const TargetTransformInfo::LSRCost &C2) const override;
209 bool canMacroFuseCmp() const override;
210 bool
211 isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddressSpace,
212 TTI::MaskKind MaskKind =
213 TTI::MaskKind::VariableOrConstantMask) const override;
214 bool
215 isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddressSpace,
216 TTI::MaskKind MaskKind =
217 TTI::MaskKind::VariableOrConstantMask) const override;
218 bool isLegalNTLoad(Type *DataType, Align Alignment) const override;
219 bool isLegalNTStore(Type *DataType, Align Alignment) const override;
220 bool isLegalBroadcastLoad(Type *ElementTy,
221 ElementCount NumElements) const override;
222 bool forceScalarizeMaskedGather(VectorType *VTy,
223 Align Alignment) const override;
224 bool forceScalarizeMaskedScatter(VectorType *VTy,
225 Align Alignment) const override {
226 return forceScalarizeMaskedGather(VTy, Alignment);
227 }
228 bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment) const;
229 bool isLegalMaskedGather(Type *DataType, Align Alignment) const override;
230 bool isLegalMaskedScatter(Type *DataType, Align Alignment) const override;
231 bool isLegalMaskedExpandLoad(Type *DataType, Align Alignment) const override;
232 bool isLegalMaskedCompressStore(Type *DataType,
233 Align Alignment) const override;
234 bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
235 const SmallBitVector &OpcodeMask) const override;
236 bool hasDivRemOp(Type *DataType, bool IsSigned) const override;
237 bool isExpensiveToSpeculativelyExecute(const Instruction *I) const override;
238 bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const override;
239 bool areInlineCompatible(const Function *Caller,
240 const Function *Callee) const override;
241 bool areTypesABICompatible(const Function *Caller, const Function *Callee,
242 ArrayRef<Type *> Type) const override;
243
244 uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override {
245 return ST->getMaxInlineSizeThreshold();
246 }
247
248 TTI::MemCmpExpansionOptions
249 enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const override;
250 bool preferAlternateOpcodeVectorization() const override { return false; }
251 bool prefersVectorizedAddressing() const override;
252 bool supportsEfficientVectorElementLoadStore() const override;
253 bool enableInterleavedAccessVectorization() const override;
254
255 bool shouldExpandReduction(const IntrinsicInst *II) const override;
256
257 InstructionCost getBranchMispredictPenalty() const override;
258
259 bool isProfitableToSinkOperands(Instruction *I,
260 SmallVectorImpl<Use *> &Ops) const override;
261
262 bool isVectorShiftByScalarCheap(Type *Ty) const override;
263
264 unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, Type *ScalarValTy,
265 Align Alignment,
266 unsigned AddrSpace) const override;
267
268 bool useFastCCForInternalCall(Function &F) const override;
269
270private:
271 bool supportsGather() const;
272 InstructionCost getGSVectorCost(unsigned Opcode, TTI::TargetCostKind CostKind,
273 Type *DataTy, const Value *Ptr,
274 Align Alignment, unsigned AddressSpace) const;
275
276 int getGatherOverhead() const;
277 int getScatterOverhead() const;
278
279 /// @}
280};
281
282} // end namespace llvm
283
284#endif
285