blob: 47de99b02d978eff2cb4ff048470604be9b2e384 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- TargetTransformInfoImpl.h --------------------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file provides helpers for the implementation of
10/// a TargetTransformInfo-conforming class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFOIMPL_H
15#define LLVM_ANALYSIS_TARGETTRANSFORMINFOIMPL_H
16
17#include "llvm/Analysis/ScalarEvolutionExpressions.h"
18#include "llvm/Analysis/TargetTransformInfo.h"
19#include "llvm/Analysis/VectorUtils.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010020#include "llvm/IR/DataLayout.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/GetElementPtrTypeIterator.h"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020023#include "llvm/IR/IntrinsicInst.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010024#include "llvm/IR/Operator.h"
25#include "llvm/IR/Type.h"
26
27namespace llvm {
28
Andrew Scullcdfcccc2018-10-05 20:58:37 +010029/// Base class for use as a mix-in that aids implementing
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010030/// a TargetTransformInfo-compatible class.
31class TargetTransformInfoImplBase {
32protected:
33 typedef TargetTransformInfo TTI;
34
35 const DataLayout &DL;
36
37 explicit TargetTransformInfoImplBase(const DataLayout &DL) : DL(DL) {}
38
39public:
40 // Provide value semantics. MSVC requires that we spell all of these out.
41 TargetTransformInfoImplBase(const TargetTransformInfoImplBase &Arg)
42 : DL(Arg.DL) {}
43 TargetTransformInfoImplBase(TargetTransformInfoImplBase &&Arg) : DL(Arg.DL) {}
44
45 const DataLayout &getDataLayout() const { return DL; }
46
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010047 int getGEPCost(Type *PointeeType, const Value *Ptr,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020048 ArrayRef<const Value *> Operands,
49 TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010050 // In the basic model, we just assume that all-constant GEPs will be folded
51 // into their uses via addressing modes.
52 for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx)
53 if (!isa<Constant>(Operands[Idx]))
54 return TTI::TCC_Basic;
55
56 return TTI::TCC_Free;
57 }
58
59 unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020060 unsigned &JTSize,
61 ProfileSummaryInfo *PSI,
62 BlockFrequencyInfo *BFI) const {
63 (void)PSI;
64 (void)BFI;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 JTSize = 0;
66 return SI.getNumCases();
67 }
68
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020069 unsigned getInliningThresholdMultiplier() const { return 1; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010070
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020071 int getInlinerVectorBonusPercent() const { return 150; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010072
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020073 unsigned getMemcpyCost(const Instruction *I) const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +010074 return TTI::TCC_Expensive;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010075 }
76
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020077 bool hasBranchDivergence() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010078
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020079 bool useGPUDivergenceAnalysis() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010080
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020081 bool isSourceOfDivergence(const Value *V) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010082
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020083 bool isAlwaysUniform(const Value *V) const { return false; }
84
85 unsigned getFlatAddressSpace() const { return -1; }
86
87 bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
88 Intrinsic::ID IID) const {
89 return false;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010090 }
91
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020092 bool isNoopAddrSpaceCast(unsigned, unsigned) const { return false; }
93
94 unsigned getAssumedAddrSpace(const Value *V) const { return -1; }
95
96 Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
97 Value *NewV) const {
98 return nullptr;
99 }
100
101 bool isLoweredToCall(const Function *F) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100102 assert(F && "A concrete function must be provided to this routine.");
103
104 // FIXME: These should almost certainly not be handled here, and instead
105 // handled with the help of TLI or the target itself. This was largely
106 // ported from existing analysis heuristics here so that such refactorings
107 // can take place in the future.
108
109 if (F->isIntrinsic())
110 return false;
111
112 if (F->hasLocalLinkage() || !F->hasName())
113 return true;
114
115 StringRef Name = F->getName();
116
117 // These will all likely lower to a single selection DAG node.
118 if (Name == "copysign" || Name == "copysignf" || Name == "copysignl" ||
119 Name == "fabs" || Name == "fabsf" || Name == "fabsl" || Name == "sin" ||
120 Name == "fmin" || Name == "fminf" || Name == "fminl" ||
121 Name == "fmax" || Name == "fmaxf" || Name == "fmaxl" ||
122 Name == "sinf" || Name == "sinl" || Name == "cos" || Name == "cosf" ||
123 Name == "cosl" || Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl")
124 return false;
125
126 // These are all likely to be optimized into something smaller.
127 if (Name == "pow" || Name == "powf" || Name == "powl" || Name == "exp2" ||
128 Name == "exp2l" || Name == "exp2f" || Name == "floor" ||
129 Name == "floorf" || Name == "ceil" || Name == "round" ||
130 Name == "ffs" || Name == "ffsl" || Name == "abs" || Name == "labs" ||
131 Name == "llabs")
132 return false;
133
134 return true;
135 }
136
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100137 bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200138 AssumptionCache &AC, TargetLibraryInfo *LibInfo,
139 HardwareLoopInfo &HWLoopInfo) const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100140 return false;
141 }
142
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200143 bool preferPredicateOverEpilogue(Loop *L, LoopInfo *LI, ScalarEvolution &SE,
144 AssumptionCache &AC, TargetLibraryInfo *TLI,
145 DominatorTree *DT,
146 const LoopAccessInfo *LAI) const {
147 return false;
148 }
149
150 bool emitGetActiveLaneMask() const {
151 return false;
152 }
153
154 Optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
155 IntrinsicInst &II) const {
156 return None;
157 }
158
159 Optional<Value *>
160 simplifyDemandedUseBitsIntrinsic(InstCombiner &IC, IntrinsicInst &II,
161 APInt DemandedMask, KnownBits &Known,
162 bool &KnownBitsComputed) const {
163 return None;
164 }
165
166 Optional<Value *> simplifyDemandedVectorEltsIntrinsic(
167 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
168 APInt &UndefElts2, APInt &UndefElts3,
169 std::function<void(Instruction *, unsigned, APInt, APInt &)>
170 SimplifyAndSetOp) const {
171 return None;
172 }
173
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100174 void getUnrollingPreferences(Loop *, ScalarEvolution &,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200175 TTI::UnrollingPreferences &) const {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100176
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200177 void getPeelingPreferences(Loop *, ScalarEvolution &,
178 TTI::PeelingPreferences &) const {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100179
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200180 bool isLegalAddImmediate(int64_t Imm) const { return false; }
181
182 bool isLegalICmpImmediate(int64_t Imm) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100183
184 bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200185 bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
186 Instruction *I = nullptr) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100187 // Guess that only reg and reg+reg addressing is allowed. This heuristic is
188 // taken from the implementation of LSR.
189 return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);
190 }
191
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200192 bool isLSRCostLess(TTI::LSRCost &C1, TTI::LSRCost &C2) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100193 return std::tie(C1.NumRegs, C1.AddRecCost, C1.NumIVMuls, C1.NumBaseAdds,
194 C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
195 std::tie(C2.NumRegs, C2.AddRecCost, C2.NumIVMuls, C2.NumBaseAdds,
196 C2.ScaleCost, C2.ImmCost, C2.SetupCost);
197 }
198
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200199 bool isNumRegsMajorCostOfLSR() const { return true; }
200
201 bool isProfitableLSRChainElement(Instruction *I) const { return false; }
202
203 bool canMacroFuseCmp() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100204
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100205 bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
206 DominatorTree *DT, AssumptionCache *AC,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200207 TargetLibraryInfo *LibInfo) const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100208 return false;
209 }
210
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100211 bool shouldFavorPostInc() const { return false; }
212
Andrew Walbran16937d02019-10-22 13:54:20 +0100213 bool shouldFavorBackedgeIndex(const Loop *L) const { return false; }
214
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200215 bool isLegalMaskedStore(Type *DataType, Align Alignment) const {
216 return false;
217 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100218
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200219 bool isLegalMaskedLoad(Type *DataType, Align Alignment) const {
220 return false;
221 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100222
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200223 bool isLegalNTStore(Type *DataType, Align Alignment) const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100224 // By default, assume nontemporal memory stores are available for stores
225 // that are aligned and have a size that is a power of 2.
226 unsigned DataSize = DL.getTypeStoreSize(DataType);
227 return Alignment >= DataSize && isPowerOf2_32(DataSize);
228 }
229
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200230 bool isLegalNTLoad(Type *DataType, Align Alignment) const {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100231 // By default, assume nontemporal memory loads are available for loads that
232 // are aligned and have a size that is a power of 2.
233 unsigned DataSize = DL.getTypeStoreSize(DataType);
234 return Alignment >= DataSize && isPowerOf2_32(DataSize);
235 }
236
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200237 bool isLegalMaskedScatter(Type *DataType, Align Alignment) const {
238 return false;
239 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100240
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200241 bool isLegalMaskedGather(Type *DataType, Align Alignment) const {
242 return false;
243 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100244
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200245 bool isLegalMaskedCompressStore(Type *DataType) const { return false; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100246
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200247 bool isLegalMaskedExpandLoad(Type *DataType) const { return false; }
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100248
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200249 bool hasDivRemOp(Type *DataType, bool IsSigned) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100250
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200251 bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const {
252 return false;
253 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100254
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200255 bool prefersVectorizedAddressing() const { return true; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100256
257 int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200258 bool HasBaseReg, int64_t Scale,
259 unsigned AddrSpace) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100260 // Guess that all legal addressing mode are free.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200261 if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
262 AddrSpace))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100263 return 0;
264 return -1;
265 }
266
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200267 bool LSRWithInstrQueries() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100268
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200269 bool isTruncateFree(Type *Ty1, Type *Ty2) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100270
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200271 bool isProfitableToHoist(Instruction *I) const { return true; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100272
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200273 bool useAA() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100274
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200275 bool isTypeLegal(Type *Ty) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100276
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200277 unsigned getRegUsageForType(Type *Ty) const { return 1; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100278
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200279 bool shouldBuildLookupTables() const { return true; }
280 bool shouldBuildLookupTablesForConstant(Constant *C) const { return true; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100281
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200282 bool useColdCCForColdCall(Function &F) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100283
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200284 unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
285 bool Insert, bool Extract) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100286 return 0;
287 }
288
289 unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200290 unsigned VF) const {
291 return 0;
292 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100293
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200294 bool supportsEfficientVectorElementLoadStore() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100295
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200296 bool enableAggressiveInterleaving(bool LoopHasReductions) const {
297 return false;
298 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100299
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100300 TTI::MemCmpExpansionOptions enableMemCmpExpansion(bool OptSize,
301 bool IsZeroCmp) const {
302 return {};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100303 }
304
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200305 bool enableInterleavedAccessVectorization() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100306
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200307 bool enableMaskedInterleavedAccessVectorization() const { return false; }
Andrew Walbran16937d02019-10-22 13:54:20 +0100308
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200309 bool isFPVectorizationPotentiallyUnsafe() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100310
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200311 bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
312 unsigned AddressSpace, unsigned Alignment,
313 bool *Fast) const {
314 return false;
315 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100316
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200317 TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100318 return TTI::PSK_Software;
319 }
320
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200321 bool haveFastSqrt(Type *Ty) const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100322
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200323 bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { return true; }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100324
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200325 unsigned getFPOpCost(Type *Ty) const {
326 return TargetTransformInfo::TCC_Basic;
327 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100328
329 int getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, const APInt &Imm,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200330 Type *Ty) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100331 return 0;
332 }
333
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200334 unsigned getIntImmCost(const APInt &Imm, Type *Ty,
335 TTI::TargetCostKind CostKind) const {
336 return TTI::TCC_Basic;
337 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100338
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200339 unsigned getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
340 Type *Ty, TTI::TargetCostKind CostKind,
341 Instruction *Inst = nullptr) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100342 return TTI::TCC_Free;
343 }
344
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200345 unsigned getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
346 const APInt &Imm, Type *Ty,
347 TTI::TargetCostKind CostKind) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100348 return TTI::TCC_Free;
349 }
350
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200351 unsigned getNumberOfRegisters(unsigned ClassID) const { return 8; }
352
353 unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const {
354 return Vector ? 1 : 0;
355 };
356
357 const char *getRegisterClassName(unsigned ClassID) const {
358 switch (ClassID) {
359 default:
360 return "Generic::Unknown Register Class";
361 case 0:
362 return "Generic::ScalarRC";
363 case 1:
364 return "Generic::VectorRC";
365 }
366 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100367
368 unsigned getRegisterBitWidth(bool Vector) const { return 32; }
369
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200370 unsigned getMinVectorRegisterBitWidth() const { return 128; }
371
372 Optional<unsigned> getMaxVScale() const { return None; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100373
374 bool shouldMaximizeVectorBandwidth(bool OptSize) const { return false; }
375
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100376 unsigned getMinimumVF(unsigned ElemWidth) const { return 0; }
377
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200378 unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const { return 0; }
379
380 bool shouldConsiderAddressTypePromotion(
381 const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100382 AllowPromotionWithoutCommonHeader = false;
383 return false;
384 }
385
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200386 unsigned getCacheLineSize() const { return 0; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100387
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200388 llvm::Optional<unsigned>
389 getCacheSize(TargetTransformInfo::CacheLevel Level) const {
390 switch (Level) {
391 case TargetTransformInfo::CacheLevel::L1D:
392 LLVM_FALLTHROUGH;
393 case TargetTransformInfo::CacheLevel::L2D:
394 return llvm::Optional<unsigned>();
395 }
396 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
397 }
398
399 llvm::Optional<unsigned>
400 getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100401 switch (Level) {
402 case TargetTransformInfo::CacheLevel::L1D:
403 LLVM_FALLTHROUGH;
404 case TargetTransformInfo::CacheLevel::L2D:
405 return llvm::Optional<unsigned>();
406 }
407
408 llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
409 }
410
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200411 unsigned getPrefetchDistance() const { return 0; }
412 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
413 unsigned NumStridedMemAccesses,
414 unsigned NumPrefetches, bool HasCall) const {
415 return 1;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100416 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200417 unsigned getMaxPrefetchIterationsAhead() const { return UINT_MAX; }
418 bool enableWritePrefetching() const { return false; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100419
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200420 unsigned getMaxInterleaveFactor(unsigned VF) const { return 1; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100421
422 unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200423 TTI::TargetCostKind CostKind,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100424 TTI::OperandValueKind Opd1Info,
425 TTI::OperandValueKind Opd2Info,
426 TTI::OperandValueProperties Opd1PropInfo,
427 TTI::OperandValueProperties Opd2PropInfo,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200428 ArrayRef<const Value *> Args,
429 const Instruction *CxtI = nullptr) const {
430 // FIXME: A number of transformation tests seem to require these values
431 // which seems a little odd for how arbitary there are.
432 switch (Opcode) {
433 default:
434 break;
435 case Instruction::FDiv:
436 case Instruction::FRem:
437 case Instruction::SDiv:
438 case Instruction::SRem:
439 case Instruction::UDiv:
440 case Instruction::URem:
441 // FIXME: Unlikely to be true for CodeSize.
442 return TTI::TCC_Expensive;
443 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100444 return 1;
445 }
446
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200447 unsigned getShuffleCost(TTI::ShuffleKind Kind, VectorType *Ty, int Index,
448 VectorType *SubTp) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100449 return 1;
450 }
451
452 unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200453 TTI::CastContextHint CCH,
454 TTI::TargetCostKind CostKind,
455 const Instruction *I) const {
456 switch (Opcode) {
457 default:
458 break;
459 case Instruction::IntToPtr: {
460 unsigned SrcSize = Src->getScalarSizeInBits();
461 if (DL.isLegalInteger(SrcSize) &&
462 SrcSize <= DL.getPointerTypeSizeInBits(Dst))
463 return 0;
464 break;
465 }
466 case Instruction::PtrToInt: {
467 unsigned DstSize = Dst->getScalarSizeInBits();
468 if (DL.isLegalInteger(DstSize) &&
469 DstSize >= DL.getPointerTypeSizeInBits(Src))
470 return 0;
471 break;
472 }
473 case Instruction::BitCast:
474 if (Dst == Src || (Dst->isPointerTy() && Src->isPointerTy()))
475 // Identity and pointer-to-pointer casts are free.
476 return 0;
477 break;
478 case Instruction::Trunc: {
479 // trunc to a native type is free (assuming the target has compare and
480 // shift-right of the same width).
481 TypeSize DstSize = DL.getTypeSizeInBits(Dst);
482 if (!DstSize.isScalable() && DL.isLegalInteger(DstSize.getFixedSize()))
483 return 0;
484 break;
485 }
486 }
487 return 1;
488 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100489
490 unsigned getExtractWithExtendCost(unsigned Opcode, Type *Dst,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200491 VectorType *VecTy, unsigned Index) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100492 return 1;
493 }
494
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200495 unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) const {
496 // A phi would be free, unless we're costing the throughput because it
497 // will require a register.
498 if (Opcode == Instruction::PHI && CostKind != TTI::TCK_RecipThroughput)
499 return 0;
500 return 1;
501 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100502
503 unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200504 CmpInst::Predicate VecPred,
505 TTI::TargetCostKind CostKind,
506 const Instruction *I) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100507 return 1;
508 }
509
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200510 unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
511 unsigned Index) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100512 return 1;
513 }
514
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200515 unsigned getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
516 unsigned AddressSpace, TTI::TargetCostKind CostKind,
517 const Instruction *I) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100518 return 1;
519 }
520
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200521 unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
522 unsigned AddressSpace,
523 TTI::TargetCostKind CostKind) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100524 return 1;
525 }
526
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200527 unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
528 const Value *Ptr, bool VariableMask,
529 Align Alignment, TTI::TargetCostKind CostKind,
530 const Instruction *I = nullptr) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100531 return 1;
532 }
533
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200534 unsigned getInterleavedMemoryOpCost(
535 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
536 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
537 bool UseMaskForCond, bool UseMaskForGaps) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100538 return 1;
539 }
540
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200541 unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
542 TTI::TargetCostKind CostKind) const {
543 switch (ICA.getID()) {
544 default:
545 break;
546 case Intrinsic::annotation:
547 case Intrinsic::assume:
548 case Intrinsic::sideeffect:
549 case Intrinsic::pseudoprobe:
550 case Intrinsic::dbg_declare:
551 case Intrinsic::dbg_value:
552 case Intrinsic::dbg_label:
553 case Intrinsic::invariant_start:
554 case Intrinsic::invariant_end:
555 case Intrinsic::launder_invariant_group:
556 case Intrinsic::strip_invariant_group:
557 case Intrinsic::is_constant:
558 case Intrinsic::lifetime_start:
559 case Intrinsic::lifetime_end:
560 case Intrinsic::objectsize:
561 case Intrinsic::ptr_annotation:
562 case Intrinsic::var_annotation:
563 case Intrinsic::experimental_gc_result:
564 case Intrinsic::experimental_gc_relocate:
565 case Intrinsic::coro_alloc:
566 case Intrinsic::coro_begin:
567 case Intrinsic::coro_free:
568 case Intrinsic::coro_end:
569 case Intrinsic::coro_frame:
570 case Intrinsic::coro_size:
571 case Intrinsic::coro_suspend:
572 case Intrinsic::coro_param:
573 case Intrinsic::coro_subfn_addr:
574 // These intrinsics don't actually represent code after lowering.
575 return 0;
576 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100577 return 1;
578 }
579
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200580 unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys,
581 TTI::TargetCostKind CostKind) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100582 return 1;
583 }
584
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200585 unsigned getNumberOfParts(Type *Tp) const { return 0; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100586
587 unsigned getAddressComputationCost(Type *Tp, ScalarEvolution *,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200588 const SCEV *) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100589 return 0;
590 }
591
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200592 unsigned getArithmeticReductionCost(unsigned, VectorType *, bool,
593 TTI::TargetCostKind) const {
594 return 1;
595 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100596
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200597 unsigned getMinMaxReductionCost(VectorType *, VectorType *, bool, bool,
598 TTI::TargetCostKind) const {
599 return 1;
600 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100601
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200602 unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
603 return 0;
604 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100605
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200606 bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100607 return false;
608 }
609
610 unsigned getAtomicMemIntrinsicMaxElementSize() const {
611 // Note for overrides: You must ensure for all element unordered-atomic
612 // memory intrinsics that all power-of-2 element sizes up to, and
613 // including, the return value of this method have a corresponding
614 // runtime lib call. These runtime lib call definitions can be found
615 // in RuntimeLibcalls.h
616 return 0;
617 }
618
619 Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200620 Type *ExpectedType) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100621 return nullptr;
622 }
623
624 Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200625 unsigned SrcAddrSpace, unsigned DestAddrSpace,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100626 unsigned SrcAlign, unsigned DestAlign) const {
627 return Type::getInt8Ty(Context);
628 }
629
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200630 void getMemcpyLoopResidualLoweringType(
631 SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
632 unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
633 unsigned SrcAlign, unsigned DestAlign) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100634 for (unsigned i = 0; i != RemainingBytes; ++i)
635 OpsOut.push_back(Type::getInt8Ty(Context));
636 }
637
638 bool areInlineCompatible(const Function *Caller,
639 const Function *Callee) const {
640 return (Caller->getFnAttribute("target-cpu") ==
641 Callee->getFnAttribute("target-cpu")) &&
642 (Caller->getFnAttribute("target-features") ==
643 Callee->getFnAttribute("target-features"));
644 }
645
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200646 bool areFunctionArgsABICompatible(const Function *Caller,
647 const Function *Callee,
Andrew Walbran16937d02019-10-22 13:54:20 +0100648 SmallPtrSetImpl<Argument *> &Args) const {
649 return (Caller->getFnAttribute("target-cpu") ==
650 Callee->getFnAttribute("target-cpu")) &&
651 (Caller->getFnAttribute("target-features") ==
652 Callee->getFnAttribute("target-features"));
653 }
654
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100655 bool isIndexedLoadLegal(TTI::MemIndexedMode Mode, Type *Ty,
656 const DataLayout &DL) const {
657 return false;
658 }
659
660 bool isIndexedStoreLegal(TTI::MemIndexedMode Mode, Type *Ty,
661 const DataLayout &DL) const {
662 return false;
663 }
664
665 unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const { return 128; }
666
667 bool isLegalToVectorizeLoad(LoadInst *LI) const { return true; }
668
669 bool isLegalToVectorizeStore(StoreInst *SI) const { return true; }
670
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200671 bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100672 unsigned AddrSpace) const {
673 return true;
674 }
675
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200676 bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100677 unsigned AddrSpace) const {
678 return true;
679 }
680
681 unsigned getLoadVectorFactor(unsigned VF, unsigned LoadSize,
682 unsigned ChainSizeInBytes,
683 VectorType *VecTy) const {
684 return VF;
685 }
686
687 unsigned getStoreVectorFactor(unsigned VF, unsigned StoreSize,
688 unsigned ChainSizeInBytes,
689 VectorType *VecTy) const {
690 return VF;
691 }
692
693 bool useReductionIntrinsic(unsigned Opcode, Type *Ty,
694 TTI::ReductionFlags Flags) const {
695 return false;
696 }
697
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200698 bool preferInLoopReduction(unsigned Opcode, Type *Ty,
699 TTI::ReductionFlags Flags) const {
700 return false;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100701 }
702
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200703 bool preferPredicatedReductionSelect(unsigned Opcode, Type *Ty,
704 TTI::ReductionFlags Flags) const {
705 return false;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100706 }
707
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200708 bool shouldExpandReduction(const IntrinsicInst *II) const { return true; }
709
710 unsigned getGISelRematGlobalCost() const { return 1; }
711
712 bool supportsScalableVectors() const { return false; }
713
714 bool hasActiveVectorLength() const { return false; }
715
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100716protected:
717 // Obtain the minimum required size to hold the value (without the sign)
718 // In case of a vector it returns the min required size for one element.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200719 unsigned minRequiredElementSize(const Value *Val, bool &isSigned) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100720 if (isa<ConstantDataVector>(Val) || isa<ConstantVector>(Val)) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200721 const auto *VectorValue = cast<Constant>(Val);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100722
723 // In case of a vector need to pick the max between the min
724 // required size for each element
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200725 auto *VT = cast<FixedVectorType>(Val->getType());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100726
727 // Assume unsigned elements
728 isSigned = false;
729
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200730 // The max required size is the size of the vector element type
731 unsigned MaxRequiredSize =
732 VT->getElementType()->getPrimitiveSizeInBits().getFixedSize();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100733
734 unsigned MinRequiredSize = 0;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200735 for (unsigned i = 0, e = VT->getNumElements(); i < e; ++i) {
736 if (auto *IntElement =
737 dyn_cast<ConstantInt>(VectorValue->getAggregateElement(i))) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100738 bool signedElement = IntElement->getValue().isNegative();
739 // Get the element min required size.
740 unsigned ElementMinRequiredSize =
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200741 IntElement->getValue().getMinSignedBits() - 1;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100742 // In case one element is signed then all the vector is signed.
743 isSigned |= signedElement;
744 // Save the max required bit size between all the elements.
745 MinRequiredSize = std::max(MinRequiredSize, ElementMinRequiredSize);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200746 } else {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100747 // not an int constant element
748 return MaxRequiredSize;
749 }
750 }
751 return MinRequiredSize;
752 }
753
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200754 if (const auto *CI = dyn_cast<ConstantInt>(Val)) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100755 isSigned = CI->getValue().isNegative();
756 return CI->getValue().getMinSignedBits() - 1;
757 }
758
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200759 if (const auto *Cast = dyn_cast<SExtInst>(Val)) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100760 isSigned = true;
761 return Cast->getSrcTy()->getScalarSizeInBits() - 1;
762 }
763
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200764 if (const auto *Cast = dyn_cast<ZExtInst>(Val)) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100765 isSigned = false;
766 return Cast->getSrcTy()->getScalarSizeInBits();
767 }
768
769 isSigned = false;
770 return Val->getType()->getScalarSizeInBits();
771 }
772
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200773 bool isStridedAccess(const SCEV *Ptr) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100774 return Ptr && isa<SCEVAddRecExpr>(Ptr);
775 }
776
777 const SCEVConstant *getConstantStrideStep(ScalarEvolution *SE,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200778 const SCEV *Ptr) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100779 if (!isStridedAccess(Ptr))
780 return nullptr;
781 const SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ptr);
782 return dyn_cast<SCEVConstant>(AddRec->getStepRecurrence(*SE));
783 }
784
785 bool isConstantStridedAccessLessThan(ScalarEvolution *SE, const SCEV *Ptr,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200786 int64_t MergeDistance) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100787 const SCEVConstant *Step = getConstantStrideStep(SE, Ptr);
788 if (!Step)
789 return false;
790 APInt StrideVal = Step->getAPInt();
791 if (StrideVal.getBitWidth() > 64)
792 return false;
793 // FIXME: Need to take absolute value for negative stride case.
794 return StrideVal.getSExtValue() < MergeDistance;
795 }
796};
797
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100798/// CRTP base class for use as a mix-in that aids implementing
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100799/// a TargetTransformInfo-compatible class.
800template <typename T>
801class TargetTransformInfoImplCRTPBase : public TargetTransformInfoImplBase {
802private:
803 typedef TargetTransformInfoImplBase BaseT;
804
805protected:
806 explicit TargetTransformInfoImplCRTPBase(const DataLayout &DL) : BaseT(DL) {}
807
808public:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100809 using BaseT::getGEPCost;
810
811 int getGEPCost(Type *PointeeType, const Value *Ptr,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200812 ArrayRef<const Value *> Operands,
813 TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100814 assert(PointeeType && Ptr && "can't get GEPCost of nullptr");
815 // TODO: will remove this when pointers have an opaque type.
816 assert(Ptr->getType()->getScalarType()->getPointerElementType() ==
817 PointeeType &&
818 "explicit pointee type doesn't match operand's pointee type");
819 auto *BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100820 bool HasBaseReg = (BaseGV == nullptr);
821
822 auto PtrSizeBits = DL.getPointerTypeSizeInBits(Ptr->getType());
823 APInt BaseOffset(PtrSizeBits, 0);
824 int64_t Scale = 0;
825
826 auto GTI = gep_type_begin(PointeeType, Operands);
827 Type *TargetType = nullptr;
828
829 // Handle the case where the GEP instruction has a single operand,
830 // the basis, therefore TargetType is a nullptr.
831 if (Operands.empty())
832 return !BaseGV ? TTI::TCC_Free : TTI::TCC_Basic;
833
834 for (auto I = Operands.begin(); I != Operands.end(); ++I, ++GTI) {
835 TargetType = GTI.getIndexedType();
836 // We assume that the cost of Scalar GEP with constant index and the
837 // cost of Vector GEP with splat constant index are the same.
838 const ConstantInt *ConstIdx = dyn_cast<ConstantInt>(*I);
839 if (!ConstIdx)
840 if (auto Splat = getSplatValue(*I))
841 ConstIdx = dyn_cast<ConstantInt>(Splat);
842 if (StructType *STy = GTI.getStructTypeOrNull()) {
843 // For structures the index is always splat or scalar constant
844 assert(ConstIdx && "Unexpected GEP index");
845 uint64_t Field = ConstIdx->getZExtValue();
846 BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field);
847 } else {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200848 // If this operand is a scalable type, bail out early.
849 // TODO: handle scalable vectors
850 if (isa<ScalableVectorType>(TargetType))
851 return TTI::TCC_Basic;
852 int64_t ElementSize =
853 DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100854 if (ConstIdx) {
855 BaseOffset +=
856 ConstIdx->getValue().sextOrTrunc(PtrSizeBits) * ElementSize;
857 } else {
858 // Needs scale register.
859 if (Scale != 0)
860 // No addressing mode takes two scale registers.
861 return TTI::TCC_Basic;
862 Scale = ElementSize;
863 }
864 }
865 }
866
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100867 if (static_cast<T *>(this)->isLegalAddressingMode(
868 TargetType, const_cast<GlobalValue *>(BaseGV),
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100869 BaseOffset.sextOrTrunc(64).getSExtValue(), HasBaseReg, Scale,
870 Ptr->getType()->getPointerAddressSpace()))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100871 return TTI::TCC_Free;
872 return TTI::TCC_Basic;
873 }
874
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200875 int getUserCost(const User *U, ArrayRef<const Value *> Operands,
876 TTI::TargetCostKind CostKind) {
877 auto *TargetTTI = static_cast<T *>(this);
878 // Handle non-intrinsic calls, invokes, and callbr.
879 // FIXME: Unlikely to be true for anything but CodeSize.
880 auto *CB = dyn_cast<CallBase>(U);
881 if (CB && !isa<IntrinsicInst>(U)) {
882 if (const Function *F = CB->getCalledFunction()) {
883 if (!TargetTTI->isLoweredToCall(F))
884 return TTI::TCC_Basic; // Give a basic cost if it will be lowered
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100885
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200886 return TTI::TCC_Basic * (F->getFunctionType()->getNumParams() + 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100887 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200888 // For indirect or other calls, scale cost by number of arguments.
889 return TTI::TCC_Basic * (CB->arg_size() + 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100890 }
891
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200892 Type *Ty = U->getType();
893 Type *OpTy =
894 U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr;
895 unsigned Opcode = Operator::getOpcode(U);
896 auto *I = dyn_cast<Instruction>(U);
897 switch (Opcode) {
898 default:
899 break;
900 case Instruction::Call: {
901 assert(isa<IntrinsicInst>(U) && "Unexpected non-intrinsic call");
902 auto *Intrinsic = cast<IntrinsicInst>(U);
903 IntrinsicCostAttributes CostAttrs(Intrinsic->getIntrinsicID(), *CB);
904 return TargetTTI->getIntrinsicInstrCost(CostAttrs, CostKind);
905 }
906 case Instruction::Br:
907 case Instruction::Ret:
908 case Instruction::PHI:
909 return TargetTTI->getCFInstrCost(Opcode, CostKind);
910 case Instruction::ExtractValue:
911 case Instruction::Freeze:
912 return TTI::TCC_Free;
913 case Instruction::Alloca:
914 if (cast<AllocaInst>(U)->isStaticAlloca())
915 return TTI::TCC_Free;
916 break;
917 case Instruction::GetElementPtr: {
918 const GEPOperator *GEP = cast<GEPOperator>(U);
919 return TargetTTI->getGEPCost(GEP->getSourceElementType(),
920 GEP->getPointerOperand(),
921 Operands.drop_front());
922 }
923 case Instruction::Add:
924 case Instruction::FAdd:
925 case Instruction::Sub:
926 case Instruction::FSub:
927 case Instruction::Mul:
928 case Instruction::FMul:
929 case Instruction::UDiv:
930 case Instruction::SDiv:
931 case Instruction::FDiv:
932 case Instruction::URem:
933 case Instruction::SRem:
934 case Instruction::FRem:
935 case Instruction::Shl:
936 case Instruction::LShr:
937 case Instruction::AShr:
938 case Instruction::And:
939 case Instruction::Or:
940 case Instruction::Xor:
941 case Instruction::FNeg: {
942 TTI::OperandValueProperties Op1VP = TTI::OP_None;
943 TTI::OperandValueProperties Op2VP = TTI::OP_None;
944 TTI::OperandValueKind Op1VK =
945 TTI::getOperandInfo(U->getOperand(0), Op1VP);
946 TTI::OperandValueKind Op2VK = Opcode != Instruction::FNeg ?
947 TTI::getOperandInfo(U->getOperand(1), Op2VP) : TTI::OK_AnyValue;
948 SmallVector<const Value *, 2> Operands(U->operand_values());
949 return TargetTTI->getArithmeticInstrCost(Opcode, Ty, CostKind,
950 Op1VK, Op2VK,
951 Op1VP, Op2VP, Operands, I);
952 }
953 case Instruction::IntToPtr:
954 case Instruction::PtrToInt:
955 case Instruction::SIToFP:
956 case Instruction::UIToFP:
957 case Instruction::FPToUI:
958 case Instruction::FPToSI:
959 case Instruction::Trunc:
960 case Instruction::FPTrunc:
961 case Instruction::BitCast:
962 case Instruction::FPExt:
963 case Instruction::SExt:
964 case Instruction::ZExt:
965 case Instruction::AddrSpaceCast:
966 return TargetTTI->getCastInstrCost(
967 Opcode, Ty, OpTy, TTI::getCastContextHint(I), CostKind, I);
968 case Instruction::Store: {
969 auto *SI = cast<StoreInst>(U);
970 Type *ValTy = U->getOperand(0)->getType();
971 return TargetTTI->getMemoryOpCost(Opcode, ValTy, SI->getAlign(),
972 SI->getPointerAddressSpace(),
973 CostKind, I);
974 }
975 case Instruction::Load: {
976 auto *LI = cast<LoadInst>(U);
977 return TargetTTI->getMemoryOpCost(Opcode, U->getType(), LI->getAlign(),
978 LI->getPointerAddressSpace(),
979 CostKind, I);
980 }
981 case Instruction::Select: {
982 Type *CondTy = U->getOperand(0)->getType();
983 return TargetTTI->getCmpSelInstrCost(Opcode, U->getType(), CondTy,
984 CmpInst::BAD_ICMP_PREDICATE,
985 CostKind, I);
986 }
987 case Instruction::ICmp:
988 case Instruction::FCmp: {
989 Type *ValTy = U->getOperand(0)->getType();
990 // TODO: Also handle ICmp/FCmp constant expressions.
991 return TargetTTI->getCmpSelInstrCost(Opcode, ValTy, U->getType(),
992 I ? cast<CmpInst>(I)->getPredicate()
993 : CmpInst::BAD_ICMP_PREDICATE,
994 CostKind, I);
995 }
996 case Instruction::InsertElement: {
997 auto *IE = dyn_cast<InsertElementInst>(U);
998 if (!IE)
999 return TTI::TCC_Basic; // FIXME
1000 auto *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
1001 unsigned Idx = CI ? CI->getZExtValue() : -1;
1002 return TargetTTI->getVectorInstrCost(Opcode, Ty, Idx);
1003 }
1004 case Instruction::ShuffleVector: {
1005 auto *Shuffle = dyn_cast<ShuffleVectorInst>(U);
1006 if (!Shuffle)
1007 return TTI::TCC_Basic; // FIXME
1008 auto *VecTy = cast<VectorType>(U->getType());
1009 auto *VecSrcTy = cast<VectorType>(U->getOperand(0)->getType());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001010
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001011 // TODO: Identify and add costs for insert subvector, etc.
1012 int SubIndex;
1013 if (Shuffle->isExtractSubvectorMask(SubIndex))
1014 return TargetTTI->getShuffleCost(TTI::SK_ExtractSubvector, VecSrcTy,
1015 SubIndex, VecTy);
1016 else if (Shuffle->changesLength())
1017 return CostKind == TTI::TCK_RecipThroughput ? -1 : 1;
1018 else if (Shuffle->isIdentity())
1019 return 0;
1020 else if (Shuffle->isReverse())
1021 return TargetTTI->getShuffleCost(TTI::SK_Reverse, VecTy, 0, nullptr);
1022 else if (Shuffle->isSelect())
1023 return TargetTTI->getShuffleCost(TTI::SK_Select, VecTy, 0, nullptr);
1024 else if (Shuffle->isTranspose())
1025 return TargetTTI->getShuffleCost(TTI::SK_Transpose, VecTy, 0, nullptr);
1026 else if (Shuffle->isZeroEltSplat())
1027 return TargetTTI->getShuffleCost(TTI::SK_Broadcast, VecTy, 0, nullptr);
1028 else if (Shuffle->isSingleSource())
1029 return TargetTTI->getShuffleCost(TTI::SK_PermuteSingleSrc, VecTy, 0,
1030 nullptr);
1031
1032 return TargetTTI->getShuffleCost(TTI::SK_PermuteTwoSrc, VecTy, 0,
1033 nullptr);
1034 }
1035 case Instruction::ExtractElement: {
1036 unsigned Idx = -1;
1037 auto *EEI = dyn_cast<ExtractElementInst>(U);
1038 if (!EEI)
1039 return TTI::TCC_Basic; // FIXME
1040
1041 auto *CI = dyn_cast<ConstantInt>(EEI->getOperand(1));
1042 if (CI)
1043 Idx = CI->getZExtValue();
1044
1045 // Try to match a reduction (a series of shufflevector and vector ops
1046 // followed by an extractelement).
1047 unsigned RdxOpcode;
1048 VectorType *RdxType;
1049 bool IsPairwise;
1050 switch (TTI::matchVectorReduction(EEI, RdxOpcode, RdxType, IsPairwise)) {
1051 case TTI::RK_Arithmetic:
1052 return TargetTTI->getArithmeticReductionCost(RdxOpcode, RdxType,
1053 IsPairwise, CostKind);
1054 case TTI::RK_MinMax:
1055 return TargetTTI->getMinMaxReductionCost(
1056 RdxType, cast<VectorType>(CmpInst::makeCmpResultType(RdxType)),
1057 IsPairwise, /*IsUnsigned=*/false, CostKind);
1058 case TTI::RK_UnsignedMinMax:
1059 return TargetTTI->getMinMaxReductionCost(
1060 RdxType, cast<VectorType>(CmpInst::makeCmpResultType(RdxType)),
1061 IsPairwise, /*IsUnsigned=*/true, CostKind);
1062 case TTI::RK_None:
1063 break;
1064 }
1065 return TargetTTI->getVectorInstrCost(Opcode, U->getOperand(0)->getType(),
1066 Idx);
1067 }
1068 }
1069 // By default, just classify everything as 'basic'.
1070 return TTI::TCC_Basic;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001071 }
1072
1073 int getInstructionLatency(const Instruction *I) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001074 SmallVector<const Value *, 4> Operands(I->operand_values());
1075 if (getUserCost(I, Operands, TTI::TCK_Latency) == TTI::TCC_Free)
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001076 return 0;
1077
1078 if (isa<LoadInst>(I))
1079 return 4;
1080
1081 Type *DstTy = I->getType();
1082
1083 // Usually an intrinsic is a simple instruction.
1084 // A real function call is much slower.
1085 if (auto *CI = dyn_cast<CallInst>(I)) {
1086 const Function *F = CI->getCalledFunction();
1087 if (!F || static_cast<T *>(this)->isLoweredToCall(F))
1088 return 40;
1089 // Some intrinsics return a value and a flag, we use the value type
1090 // to decide its latency.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001091 if (StructType *StructTy = dyn_cast<StructType>(DstTy))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001092 DstTy = StructTy->getElementType(0);
1093 // Fall through to simple instructions.
1094 }
1095
1096 if (VectorType *VectorTy = dyn_cast<VectorType>(DstTy))
1097 DstTy = VectorTy->getElementType();
1098 if (DstTy->isFloatingPointTy())
1099 return 3;
1100
1101 return 1;
1102 }
1103};
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001104} // namespace llvm
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001105
1106#endif