xref: /freebsd/contrib/llvm-project/llvm/lib/Target/X86/X86TargetTransformInfo.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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 TargetTransformInfo::Concept 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 
24 namespace llvm {
25 
26 class InstCombiner;
27 
28 class X86TTIImpl : 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-bit
41       // 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 
98       // Perf-tuning flags.
99       X86::TuningFastGather,
100       X86::TuningSlowUAMem32,
101       X86::TuningAllowLight256Bit,
102 
103       // Based on whether user set the -mprefer-vector-width command line.
104       X86::TuningPrefer128Bit,
105       X86::TuningPrefer256Bit,
106 
107       // CPU name enums. These just follow CPU string.
108       X86::ProcIntelAtom
109   };
110 
111 public:
112   explicit X86TTIImpl(const X86TargetMachine *TM, const Function &F)
113       : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
114         TLI(ST->getTargetLowering()) {}
115 
116   /// \name Scalar TTI Implementations
117   /// @{
118   TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth);
119 
120   /// @}
121 
122   /// \name Cache TTI Implementation
123   /// @{
124   std::optional<unsigned> getCacheSize(
125     TargetTransformInfo::CacheLevel Level) const override;
126   std::optional<unsigned> getCacheAssociativity(
127     TargetTransformInfo::CacheLevel Level) const override;
128   /// @}
129 
130   /// \name Vector TTI Implementations
131   /// @{
132 
133   unsigned getNumberOfRegisters(unsigned ClassID) const;
134   TypeSize getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const;
135   unsigned getLoadStoreVecRegBitWidth(unsigned AS) const;
136   unsigned getMaxInterleaveFactor(ElementCount VF);
137   InstructionCost getArithmeticInstrCost(
138       unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
139       TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},
140       TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},
141       ArrayRef<const Value *> Args = ArrayRef<const Value *>(),
142       const Instruction *CxtI = nullptr);
143   InstructionCost getAltInstrCost(VectorType *VecTy, unsigned Opcode0,
144                                   unsigned Opcode1,
145                                   const SmallBitVector &OpcodeMask,
146                                   TTI::TargetCostKind CostKind) const;
147 
148   InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp,
149                                  ArrayRef<int> Mask,
150                                  TTI::TargetCostKind CostKind, int Index,
151                                  VectorType *SubTp,
152                                  ArrayRef<const Value *> Args = std::nullopt);
153   InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
154                                    TTI::CastContextHint CCH,
155                                    TTI::TargetCostKind CostKind,
156                                    const Instruction *I = nullptr);
157   InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
158                                      CmpInst::Predicate VecPred,
159                                      TTI::TargetCostKind CostKind,
160                                      const Instruction *I = nullptr);
161   using BaseT::getVectorInstrCost;
162   InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,
163                                      TTI::TargetCostKind CostKind,
164                                      unsigned Index, Value *Op0, Value *Op1);
165   InstructionCost getScalarizationOverhead(VectorType *Ty,
166                                            const APInt &DemandedElts,
167                                            bool Insert, bool Extract,
168                                            TTI::TargetCostKind CostKind);
169   InstructionCost getReplicationShuffleCost(Type *EltTy, int ReplicationFactor,
170                                             int VF,
171                                             const APInt &DemandedDstElts,
172                                             TTI::TargetCostKind CostKind);
173   InstructionCost
174   getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
175                   unsigned AddressSpace, TTI::TargetCostKind CostKind,
176                   TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},
177                   const Instruction *I = nullptr);
178   InstructionCost getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
179                                         Align Alignment, unsigned AddressSpace,
180                                         TTI::TargetCostKind CostKind);
181   InstructionCost getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
182                                          const Value *Ptr, bool VariableMask,
183                                          Align Alignment,
184                                          TTI::TargetCostKind CostKind,
185                                          const Instruction *I);
186   InstructionCost getPointersChainCost(ArrayRef<const Value *> Ptrs,
187                                        const Value *Base,
188                                        const TTI::PointersChainInfo &Info,
189                                        Type *AccessTy,
190                                        TTI::TargetCostKind CostKind);
191   InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE,
192                                             const SCEV *Ptr);
193 
194   std::optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
195                                                     IntrinsicInst &II) const;
196   std::optional<Value *>
197   simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
198                                    APInt DemandedMask, KnownBits &Known,
199                                    bool &KnownBitsComputed) const;
200   std::optional<Value *> simplifyDemandedVectorEltsIntrinsic(
201       InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
202       APInt &UndefElts2, APInt &UndefElts3,
203       std::function<void(Instruction *, unsigned, APInt, APInt &)>
204           SimplifyAndSetOp) const;
205 
206   unsigned getAtomicMemIntrinsicMaxElementSize() const;
207 
208   InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
209                                         TTI::TargetCostKind CostKind);
210 
211   InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
212                                              std::optional<FastMathFlags> FMF,
213                                              TTI::TargetCostKind CostKind);
214 
215   InstructionCost getMinMaxCost(Intrinsic::ID IID, Type *Ty,
216                                 TTI::TargetCostKind CostKind,
217                                 FastMathFlags FMF);
218 
219   InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty,
220                                          FastMathFlags FMF,
221                                          TTI::TargetCostKind CostKind);
222 
223   InstructionCost getInterleavedMemoryOpCost(
224       unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
225       Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
226       bool UseMaskForCond = false, bool UseMaskForGaps = false);
227   InstructionCost getInterleavedMemoryOpCostAVX512(
228       unsigned Opcode, FixedVectorType *VecTy, unsigned Factor,
229       ArrayRef<unsigned> Indices, Align Alignment, unsigned AddressSpace,
230       TTI::TargetCostKind CostKind, bool UseMaskForCond = false,
231       bool UseMaskForGaps = false);
232 
233   InstructionCost getIntImmCost(int64_t);
234 
235   InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
236                                 TTI::TargetCostKind CostKind);
237 
238   InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,
239                                  const Instruction *I = nullptr);
240 
241   InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
242                                     const APInt &Imm, Type *Ty,
243                                     TTI::TargetCostKind CostKind,
244                                     Instruction *Inst = nullptr);
245   InstructionCost getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
246                                       const APInt &Imm, Type *Ty,
247                                       TTI::TargetCostKind CostKind);
248   /// Return the cost of the scaling factor used in the addressing
249   /// mode represented by AM for this target, for a load/store
250   /// of the specified type.
251   /// If the AM is supported, the return value must be >= 0.
252   /// If the AM is not supported, it returns a negative value.
253   InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
254                                        int64_t BaseOffset, bool HasBaseReg,
255                                        int64_t Scale, unsigned AddrSpace) const;
256 
257   bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
258                      const TargetTransformInfo::LSRCost &C2);
259   bool canMacroFuseCmp();
260   bool isLegalMaskedLoad(Type *DataType, Align Alignment);
261   bool isLegalMaskedStore(Type *DataType, Align Alignment);
262   bool isLegalNTLoad(Type *DataType, Align Alignment);
263   bool isLegalNTStore(Type *DataType, Align Alignment);
264   bool isLegalBroadcastLoad(Type *ElementTy, ElementCount NumElements) const;
265   bool forceScalarizeMaskedGather(VectorType *VTy, Align Alignment);
266   bool forceScalarizeMaskedScatter(VectorType *VTy, Align Alignment) {
267     return forceScalarizeMaskedGather(VTy, Alignment);
268   }
269   bool isLegalMaskedGatherScatter(Type *DataType, Align Alignment);
270   bool isLegalMaskedGather(Type *DataType, Align Alignment);
271   bool isLegalMaskedScatter(Type *DataType, Align Alignment);
272   bool isLegalMaskedExpandLoad(Type *DataType);
273   bool isLegalMaskedCompressStore(Type *DataType);
274   bool isLegalAltInstr(VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
275                        const SmallBitVector &OpcodeMask) const;
276   bool hasDivRemOp(Type *DataType, bool IsSigned);
277   bool isExpensiveToSpeculativelyExecute(const Instruction *I);
278   bool isFCmpOrdCheaperThanFCmpZero(Type *Ty);
279   bool areInlineCompatible(const Function *Caller,
280                            const Function *Callee) const;
281   bool areTypesABICompatible(const Function *Caller, const Function *Callee,
282                              const ArrayRef<Type *> &Type) const;
283 
284   uint64_t getMaxMemIntrinsicInlineSizeThreshold() const {
285     return ST->getMaxInlineSizeThreshold();
286   }
287 
288   TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
289                                                     bool IsZeroCmp) const;
290   bool prefersVectorizedAddressing() const;
291   bool supportsEfficientVectorElementLoadStore() const;
292   bool enableInterleavedAccessVectorization();
293 
294 private:
295   bool supportsGather() const;
296   InstructionCost getGSScalarCost(unsigned Opcode, Type *DataTy,
297                                   bool VariableMask, Align Alignment,
298                                   unsigned AddressSpace);
299   InstructionCost getGSVectorCost(unsigned Opcode, Type *DataTy,
300                                   const Value *Ptr, Align Alignment,
301                                   unsigned AddressSpace);
302 
303   int getGatherOverhead() const;
304   int getScatterOverhead() const;
305 
306   /// @}
307 };
308 
309 } // end namespace llvm
310 
311 #endif
312