1 //===- llvm/Analysis/TargetTransformInfo.cpp ------------------------------===//
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
9 #include "llvm/Analysis/TargetTransformInfo.h"
10 #include "llvm/Analysis/CFG.h"
11 #include "llvm/Analysis/LoopIterator.h"
12 #include "llvm/Analysis/TargetLibraryInfo.h"
13 #include "llvm/Analysis/TargetTransformInfoImpl.h"
14 #include "llvm/IR/CFG.h"
15 #include "llvm/IR/Dominators.h"
16 #include "llvm/IR/Instruction.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/IntrinsicInst.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/IR/Operator.h"
21 #include "llvm/InitializePasses.h"
22 #include "llvm/Support/CommandLine.h"
23 #include <optional>
24 #include <utility>
25
26 using namespace llvm;
27 using namespace PatternMatch;
28
29 #define DEBUG_TYPE "tti"
30
31 static cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false),
32 cl::Hidden,
33 cl::desc("Recognize reduction patterns."));
34
35 static cl::opt<unsigned> CacheLineSize(
36 "cache-line-size", cl::init(0), cl::Hidden,
37 cl::desc("Use this to override the target cache line size when "
38 "specified by the user."));
39
40 static cl::opt<unsigned> MinPageSize(
41 "min-page-size", cl::init(0), cl::Hidden,
42 cl::desc("Use this to override the target's minimum page size."));
43
44 static cl::opt<unsigned> PredictableBranchThreshold(
45 "predictable-branch-threshold", cl::init(99), cl::Hidden,
46 cl::desc(
47 "Use this to override the target's predictable branch threshold (%)."));
48
49 namespace {
50 /// No-op implementation of the TTI interface using the utility base
51 /// classes.
52 ///
53 /// This is used when no target specific information is available.
54 struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> {
NoTTIImpl__anonf4b1d5920111::NoTTIImpl55 explicit NoTTIImpl(const DataLayout &DL)
56 : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {}
57 };
58 } // namespace
59
TargetTransformInfo(std::unique_ptr<const TargetTransformInfoImplBase> Impl)60 TargetTransformInfo::TargetTransformInfo(
61 std::unique_ptr<const TargetTransformInfoImplBase> Impl)
62 : TTIImpl(std::move(Impl)) {}
63
canAnalyze(LoopInfo & LI)64 bool HardwareLoopInfo::canAnalyze(LoopInfo &LI) {
65 // If the loop has irreducible control flow, it can not be converted to
66 // Hardware loop.
67 LoopBlocksRPO RPOT(L);
68 RPOT.perform(&LI);
69 if (containsIrreducibleCFG<const BasicBlock *>(RPOT, LI))
70 return false;
71 return true;
72 }
73
IntrinsicCostAttributes(Intrinsic::ID Id,const CallBase & CI,InstructionCost ScalarizationCost,bool TypeBasedOnly,const TargetLibraryInfo * LibInfo)74 IntrinsicCostAttributes::IntrinsicCostAttributes(
75 Intrinsic::ID Id, const CallBase &CI, InstructionCost ScalarizationCost,
76 bool TypeBasedOnly, const TargetLibraryInfo *LibInfo)
77 : II(dyn_cast<IntrinsicInst>(&CI)), RetTy(CI.getType()), IID(Id),
78 ScalarizationCost(ScalarizationCost), LibInfo(LibInfo) {
79
80 if (const auto *FPMO = dyn_cast<FPMathOperator>(&CI))
81 FMF = FPMO->getFastMathFlags();
82
83 if (!TypeBasedOnly)
84 Arguments.insert(Arguments.begin(), CI.arg_begin(), CI.arg_end());
85 FunctionType *FTy = CI.getCalledFunction()->getFunctionType();
86 ParamTys.insert(ParamTys.begin(), FTy->param_begin(), FTy->param_end());
87 }
88
IntrinsicCostAttributes(Intrinsic::ID Id,Type * RTy,ArrayRef<Type * > Tys,FastMathFlags Flags,const IntrinsicInst * I,InstructionCost ScalarCost)89 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
90 ArrayRef<Type *> Tys,
91 FastMathFlags Flags,
92 const IntrinsicInst *I,
93 InstructionCost ScalarCost)
94 : II(I), RetTy(RTy), IID(Id), FMF(Flags), ScalarizationCost(ScalarCost) {
95 ParamTys.insert(ParamTys.begin(), Tys.begin(), Tys.end());
96 }
97
IntrinsicCostAttributes(Intrinsic::ID Id,Type * Ty,ArrayRef<const Value * > Args)98 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *Ty,
99 ArrayRef<const Value *> Args)
100 : RetTy(Ty), IID(Id) {
101
102 Arguments.insert(Arguments.begin(), Args.begin(), Args.end());
103 ParamTys.reserve(Arguments.size());
104 for (const Value *Argument : Arguments)
105 ParamTys.push_back(Argument->getType());
106 }
107
IntrinsicCostAttributes(Intrinsic::ID Id,Type * RTy,ArrayRef<const Value * > Args,ArrayRef<Type * > Tys,FastMathFlags Flags,const IntrinsicInst * I,InstructionCost ScalarCost,TargetLibraryInfo const * LibInfo)108 IntrinsicCostAttributes::IntrinsicCostAttributes(
109 Intrinsic::ID Id, Type *RTy, ArrayRef<const Value *> Args,
110 ArrayRef<Type *> Tys, FastMathFlags Flags, const IntrinsicInst *I,
111 InstructionCost ScalarCost, TargetLibraryInfo const *LibInfo)
112 : II(I), RetTy(RTy), IID(Id), FMF(Flags), ScalarizationCost(ScalarCost),
113 LibInfo(LibInfo) {
114 ParamTys.insert(ParamTys.begin(), Tys.begin(), Tys.end());
115 Arguments.insert(Arguments.begin(), Args.begin(), Args.end());
116 }
117
HardwareLoopInfo(Loop * L)118 HardwareLoopInfo::HardwareLoopInfo(Loop *L) : L(L) {
119 // Match default options:
120 // - hardware-loop-counter-bitwidth = 32
121 // - hardware-loop-decrement = 1
122 CountType = Type::getInt32Ty(L->getHeader()->getContext());
123 LoopDecrement = ConstantInt::get(CountType, 1);
124 }
125
isHardwareLoopCandidate(ScalarEvolution & SE,LoopInfo & LI,DominatorTree & DT,bool ForceNestedLoop,bool ForceHardwareLoopPHI)126 bool HardwareLoopInfo::isHardwareLoopCandidate(ScalarEvolution &SE,
127 LoopInfo &LI, DominatorTree &DT,
128 bool ForceNestedLoop,
129 bool ForceHardwareLoopPHI) {
130 SmallVector<BasicBlock *, 4> ExitingBlocks;
131 L->getExitingBlocks(ExitingBlocks);
132
133 for (BasicBlock *BB : ExitingBlocks) {
134 // If we pass the updated counter back through a phi, we need to know
135 // which latch the updated value will be coming from.
136 if (!L->isLoopLatch(BB)) {
137 if (ForceHardwareLoopPHI || CounterInReg)
138 continue;
139 }
140
141 const SCEV *EC = SE.getExitCount(L, BB);
142 if (isa<SCEVCouldNotCompute>(EC))
143 continue;
144 if (const SCEVConstant *ConstEC = dyn_cast<SCEVConstant>(EC)) {
145 if (ConstEC->getValue()->isZero())
146 continue;
147 } else if (!SE.isLoopInvariant(EC, L))
148 continue;
149
150 if (SE.getTypeSizeInBits(EC->getType()) > CountType->getBitWidth())
151 continue;
152
153 // If this exiting block is contained in a nested loop, it is not eligible
154 // for insertion of the branch-and-decrement since the inner loop would
155 // end up messing up the value in the CTR.
156 if (!IsNestingLegal && LI.getLoopFor(BB) != L && !ForceNestedLoop)
157 continue;
158
159 // We now have a loop-invariant count of loop iterations (which is not the
160 // constant zero) for which we know that this loop will not exit via this
161 // existing block.
162
163 // We need to make sure that this block will run on every loop iteration.
164 // For this to be true, we must dominate all blocks with backedges. Such
165 // blocks are in-loop predecessors to the header block.
166 bool NotAlways = false;
167 for (BasicBlock *Pred : predecessors(L->getHeader())) {
168 if (!L->contains(Pred))
169 continue;
170
171 if (!DT.dominates(BB, Pred)) {
172 NotAlways = true;
173 break;
174 }
175 }
176
177 if (NotAlways)
178 continue;
179
180 // Make sure this blocks ends with a conditional branch.
181 Instruction *TI = BB->getTerminator();
182 if (!TI)
183 continue;
184
185 if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
186 if (!BI->isConditional())
187 continue;
188
189 ExitBranch = BI;
190 } else
191 continue;
192
193 // Note that this block may not be the loop latch block, even if the loop
194 // has a latch block.
195 ExitBlock = BB;
196 ExitCount = EC;
197 break;
198 }
199
200 if (!ExitBlock)
201 return false;
202 return true;
203 }
204
TargetTransformInfo(const DataLayout & DL)205 TargetTransformInfo::TargetTransformInfo(const DataLayout &DL)
206 : TTIImpl(std::make_unique<NoTTIImpl>(DL)) {}
207
208 TargetTransformInfo::~TargetTransformInfo() = default;
209
TargetTransformInfo(TargetTransformInfo && Arg)210 TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg)
211 : TTIImpl(std::move(Arg.TTIImpl)) {}
212
operator =(TargetTransformInfo && RHS)213 TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) {
214 TTIImpl = std::move(RHS.TTIImpl);
215 return *this;
216 }
217
getInliningThresholdMultiplier() const218 unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
219 return TTIImpl->getInliningThresholdMultiplier();
220 }
221
222 unsigned
getInliningCostBenefitAnalysisSavingsMultiplier() const223 TargetTransformInfo::getInliningCostBenefitAnalysisSavingsMultiplier() const {
224 return TTIImpl->getInliningCostBenefitAnalysisSavingsMultiplier();
225 }
226
227 unsigned
getInliningCostBenefitAnalysisProfitableMultiplier() const228 TargetTransformInfo::getInliningCostBenefitAnalysisProfitableMultiplier()
229 const {
230 return TTIImpl->getInliningCostBenefitAnalysisProfitableMultiplier();
231 }
232
getInliningLastCallToStaticBonus() const233 int TargetTransformInfo::getInliningLastCallToStaticBonus() const {
234 return TTIImpl->getInliningLastCallToStaticBonus();
235 }
236
237 unsigned
adjustInliningThreshold(const CallBase * CB) const238 TargetTransformInfo::adjustInliningThreshold(const CallBase *CB) const {
239 return TTIImpl->adjustInliningThreshold(CB);
240 }
241
getCallerAllocaCost(const CallBase * CB,const AllocaInst * AI) const242 unsigned TargetTransformInfo::getCallerAllocaCost(const CallBase *CB,
243 const AllocaInst *AI) const {
244 return TTIImpl->getCallerAllocaCost(CB, AI);
245 }
246
getInlinerVectorBonusPercent() const247 int TargetTransformInfo::getInlinerVectorBonusPercent() const {
248 return TTIImpl->getInlinerVectorBonusPercent();
249 }
250
getGEPCost(Type * PointeeType,const Value * Ptr,ArrayRef<const Value * > Operands,Type * AccessType,TTI::TargetCostKind CostKind) const251 InstructionCost TargetTransformInfo::getGEPCost(
252 Type *PointeeType, const Value *Ptr, ArrayRef<const Value *> Operands,
253 Type *AccessType, TTI::TargetCostKind CostKind) const {
254 return TTIImpl->getGEPCost(PointeeType, Ptr, Operands, AccessType, CostKind);
255 }
256
getPointersChainCost(ArrayRef<const Value * > Ptrs,const Value * Base,const TTI::PointersChainInfo & Info,Type * AccessTy,TTI::TargetCostKind CostKind) const257 InstructionCost TargetTransformInfo::getPointersChainCost(
258 ArrayRef<const Value *> Ptrs, const Value *Base,
259 const TTI::PointersChainInfo &Info, Type *AccessTy,
260 TTI::TargetCostKind CostKind) const {
261 assert((Base || !Info.isSameBase()) &&
262 "If pointers have same base address it has to be provided.");
263 return TTIImpl->getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
264 }
265
getEstimatedNumberOfCaseClusters(const SwitchInst & SI,unsigned & JTSize,ProfileSummaryInfo * PSI,BlockFrequencyInfo * BFI) const266 unsigned TargetTransformInfo::getEstimatedNumberOfCaseClusters(
267 const SwitchInst &SI, unsigned &JTSize, ProfileSummaryInfo *PSI,
268 BlockFrequencyInfo *BFI) const {
269 return TTIImpl->getEstimatedNumberOfCaseClusters(SI, JTSize, PSI, BFI);
270 }
271
272 InstructionCost
getInstructionCost(const User * U,ArrayRef<const Value * > Operands,enum TargetCostKind CostKind) const273 TargetTransformInfo::getInstructionCost(const User *U,
274 ArrayRef<const Value *> Operands,
275 enum TargetCostKind CostKind) const {
276 InstructionCost Cost = TTIImpl->getInstructionCost(U, Operands, CostKind);
277 assert((CostKind == TTI::TCK_RecipThroughput || Cost >= 0) &&
278 "TTI should not produce negative costs!");
279 return Cost;
280 }
281
getPredictableBranchThreshold() const282 BranchProbability TargetTransformInfo::getPredictableBranchThreshold() const {
283 return PredictableBranchThreshold.getNumOccurrences() > 0
284 ? BranchProbability(PredictableBranchThreshold, 100)
285 : TTIImpl->getPredictableBranchThreshold();
286 }
287
getBranchMispredictPenalty() const288 InstructionCost TargetTransformInfo::getBranchMispredictPenalty() const {
289 return TTIImpl->getBranchMispredictPenalty();
290 }
291
hasBranchDivergence(const Function * F) const292 bool TargetTransformInfo::hasBranchDivergence(const Function *F) const {
293 return TTIImpl->hasBranchDivergence(F);
294 }
295
isSourceOfDivergence(const Value * V) const296 bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
297 if (const auto *Call = dyn_cast<CallBase>(V)) {
298 if (Call->hasFnAttr(Attribute::NoDivergenceSource))
299 return false;
300 }
301 return TTIImpl->isSourceOfDivergence(V);
302 }
303
isAlwaysUniform(const Value * V) const304 bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const {
305 return TTIImpl->isAlwaysUniform(V);
306 }
307
isValidAddrSpaceCast(unsigned FromAS,unsigned ToAS) const308 bool llvm::TargetTransformInfo::isValidAddrSpaceCast(unsigned FromAS,
309 unsigned ToAS) const {
310 return TTIImpl->isValidAddrSpaceCast(FromAS, ToAS);
311 }
312
addrspacesMayAlias(unsigned FromAS,unsigned ToAS) const313 bool llvm::TargetTransformInfo::addrspacesMayAlias(unsigned FromAS,
314 unsigned ToAS) const {
315 return TTIImpl->addrspacesMayAlias(FromAS, ToAS);
316 }
317
getFlatAddressSpace() const318 unsigned TargetTransformInfo::getFlatAddressSpace() const {
319 return TTIImpl->getFlatAddressSpace();
320 }
321
collectFlatAddressOperands(SmallVectorImpl<int> & OpIndexes,Intrinsic::ID IID) const322 bool TargetTransformInfo::collectFlatAddressOperands(
323 SmallVectorImpl<int> &OpIndexes, Intrinsic::ID IID) const {
324 return TTIImpl->collectFlatAddressOperands(OpIndexes, IID);
325 }
326
isNoopAddrSpaceCast(unsigned FromAS,unsigned ToAS) const327 bool TargetTransformInfo::isNoopAddrSpaceCast(unsigned FromAS,
328 unsigned ToAS) const {
329 return TTIImpl->isNoopAddrSpaceCast(FromAS, ToAS);
330 }
331
canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const332 bool TargetTransformInfo::canHaveNonUndefGlobalInitializerInAddressSpace(
333 unsigned AS) const {
334 return TTIImpl->canHaveNonUndefGlobalInitializerInAddressSpace(AS);
335 }
336
getAssumedAddrSpace(const Value * V) const337 unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const {
338 return TTIImpl->getAssumedAddrSpace(V);
339 }
340
isSingleThreaded() const341 bool TargetTransformInfo::isSingleThreaded() const {
342 return TTIImpl->isSingleThreaded();
343 }
344
345 std::pair<const Value *, unsigned>
getPredicatedAddrSpace(const Value * V) const346 TargetTransformInfo::getPredicatedAddrSpace(const Value *V) const {
347 return TTIImpl->getPredicatedAddrSpace(V);
348 }
349
rewriteIntrinsicWithAddressSpace(IntrinsicInst * II,Value * OldV,Value * NewV) const350 Value *TargetTransformInfo::rewriteIntrinsicWithAddressSpace(
351 IntrinsicInst *II, Value *OldV, Value *NewV) const {
352 return TTIImpl->rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
353 }
354
isLoweredToCall(const Function * F) const355 bool TargetTransformInfo::isLoweredToCall(const Function *F) const {
356 return TTIImpl->isLoweredToCall(F);
357 }
358
isHardwareLoopProfitable(Loop * L,ScalarEvolution & SE,AssumptionCache & AC,TargetLibraryInfo * LibInfo,HardwareLoopInfo & HWLoopInfo) const359 bool TargetTransformInfo::isHardwareLoopProfitable(
360 Loop *L, ScalarEvolution &SE, AssumptionCache &AC,
361 TargetLibraryInfo *LibInfo, HardwareLoopInfo &HWLoopInfo) const {
362 return TTIImpl->isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
363 }
364
getEpilogueVectorizationMinVF() const365 unsigned TargetTransformInfo::getEpilogueVectorizationMinVF() const {
366 return TTIImpl->getEpilogueVectorizationMinVF();
367 }
368
preferPredicateOverEpilogue(TailFoldingInfo * TFI) const369 bool TargetTransformInfo::preferPredicateOverEpilogue(
370 TailFoldingInfo *TFI) const {
371 return TTIImpl->preferPredicateOverEpilogue(TFI);
372 }
373
getPreferredTailFoldingStyle(bool IVUpdateMayOverflow) const374 TailFoldingStyle TargetTransformInfo::getPreferredTailFoldingStyle(
375 bool IVUpdateMayOverflow) const {
376 return TTIImpl->getPreferredTailFoldingStyle(IVUpdateMayOverflow);
377 }
378
379 std::optional<Instruction *>
instCombineIntrinsic(InstCombiner & IC,IntrinsicInst & II) const380 TargetTransformInfo::instCombineIntrinsic(InstCombiner &IC,
381 IntrinsicInst &II) const {
382 return TTIImpl->instCombineIntrinsic(IC, II);
383 }
384
simplifyDemandedUseBitsIntrinsic(InstCombiner & IC,IntrinsicInst & II,APInt DemandedMask,KnownBits & Known,bool & KnownBitsComputed) const385 std::optional<Value *> TargetTransformInfo::simplifyDemandedUseBitsIntrinsic(
386 InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
387 bool &KnownBitsComputed) const {
388 return TTIImpl->simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
389 KnownBitsComputed);
390 }
391
simplifyDemandedVectorEltsIntrinsic(InstCombiner & IC,IntrinsicInst & II,APInt DemandedElts,APInt & UndefElts,APInt & UndefElts2,APInt & UndefElts3,std::function<void (Instruction *,unsigned,APInt,APInt &)> SimplifyAndSetOp) const392 std::optional<Value *> TargetTransformInfo::simplifyDemandedVectorEltsIntrinsic(
393 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
394 APInt &UndefElts2, APInt &UndefElts3,
395 std::function<void(Instruction *, unsigned, APInt, APInt &)>
396 SimplifyAndSetOp) const {
397 return TTIImpl->simplifyDemandedVectorEltsIntrinsic(
398 IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
399 SimplifyAndSetOp);
400 }
401
getUnrollingPreferences(Loop * L,ScalarEvolution & SE,UnrollingPreferences & UP,OptimizationRemarkEmitter * ORE) const402 void TargetTransformInfo::getUnrollingPreferences(
403 Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP,
404 OptimizationRemarkEmitter *ORE) const {
405 return TTIImpl->getUnrollingPreferences(L, SE, UP, ORE);
406 }
407
getPeelingPreferences(Loop * L,ScalarEvolution & SE,PeelingPreferences & PP) const408 void TargetTransformInfo::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
409 PeelingPreferences &PP) const {
410 return TTIImpl->getPeelingPreferences(L, SE, PP);
411 }
412
isLegalAddImmediate(int64_t Imm) const413 bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
414 return TTIImpl->isLegalAddImmediate(Imm);
415 }
416
isLegalAddScalableImmediate(int64_t Imm) const417 bool TargetTransformInfo::isLegalAddScalableImmediate(int64_t Imm) const {
418 return TTIImpl->isLegalAddScalableImmediate(Imm);
419 }
420
isLegalICmpImmediate(int64_t Imm) const421 bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
422 return TTIImpl->isLegalICmpImmediate(Imm);
423 }
424
isLegalAddressingMode(Type * Ty,GlobalValue * BaseGV,int64_t BaseOffset,bool HasBaseReg,int64_t Scale,unsigned AddrSpace,Instruction * I,int64_t ScalableOffset) const425 bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
426 int64_t BaseOffset,
427 bool HasBaseReg, int64_t Scale,
428 unsigned AddrSpace,
429 Instruction *I,
430 int64_t ScalableOffset) const {
431 return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
432 Scale, AddrSpace, I, ScalableOffset);
433 }
434
isLSRCostLess(const LSRCost & C1,const LSRCost & C2) const435 bool TargetTransformInfo::isLSRCostLess(const LSRCost &C1,
436 const LSRCost &C2) const {
437 return TTIImpl->isLSRCostLess(C1, C2);
438 }
439
isNumRegsMajorCostOfLSR() const440 bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
441 return TTIImpl->isNumRegsMajorCostOfLSR();
442 }
443
shouldDropLSRSolutionIfLessProfitable() const444 bool TargetTransformInfo::shouldDropLSRSolutionIfLessProfitable() const {
445 return TTIImpl->shouldDropLSRSolutionIfLessProfitable();
446 }
447
isProfitableLSRChainElement(Instruction * I) const448 bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const {
449 return TTIImpl->isProfitableLSRChainElement(I);
450 }
451
canMacroFuseCmp() const452 bool TargetTransformInfo::canMacroFuseCmp() const {
453 return TTIImpl->canMacroFuseCmp();
454 }
455
canSaveCmp(Loop * L,BranchInst ** BI,ScalarEvolution * SE,LoopInfo * LI,DominatorTree * DT,AssumptionCache * AC,TargetLibraryInfo * LibInfo) const456 bool TargetTransformInfo::canSaveCmp(Loop *L, BranchInst **BI,
457 ScalarEvolution *SE, LoopInfo *LI,
458 DominatorTree *DT, AssumptionCache *AC,
459 TargetLibraryInfo *LibInfo) const {
460 return TTIImpl->canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
461 }
462
463 TTI::AddressingModeKind
getPreferredAddressingMode(const Loop * L,ScalarEvolution * SE) const464 TargetTransformInfo::getPreferredAddressingMode(const Loop *L,
465 ScalarEvolution *SE) const {
466 return TTIImpl->getPreferredAddressingMode(L, SE);
467 }
468
isLegalMaskedStore(Type * DataType,Align Alignment,unsigned AddressSpace) const469 bool TargetTransformInfo::isLegalMaskedStore(Type *DataType, Align Alignment,
470 unsigned AddressSpace) const {
471 return TTIImpl->isLegalMaskedStore(DataType, Alignment, AddressSpace);
472 }
473
isLegalMaskedLoad(Type * DataType,Align Alignment,unsigned AddressSpace) const474 bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType, Align Alignment,
475 unsigned AddressSpace) const {
476 return TTIImpl->isLegalMaskedLoad(DataType, Alignment, AddressSpace);
477 }
478
isLegalNTStore(Type * DataType,Align Alignment) const479 bool TargetTransformInfo::isLegalNTStore(Type *DataType,
480 Align Alignment) const {
481 return TTIImpl->isLegalNTStore(DataType, Alignment);
482 }
483
isLegalNTLoad(Type * DataType,Align Alignment) const484 bool TargetTransformInfo::isLegalNTLoad(Type *DataType, Align Alignment) const {
485 return TTIImpl->isLegalNTLoad(DataType, Alignment);
486 }
487
isLegalBroadcastLoad(Type * ElementTy,ElementCount NumElements) const488 bool TargetTransformInfo::isLegalBroadcastLoad(Type *ElementTy,
489 ElementCount NumElements) const {
490 return TTIImpl->isLegalBroadcastLoad(ElementTy, NumElements);
491 }
492
isLegalMaskedGather(Type * DataType,Align Alignment) const493 bool TargetTransformInfo::isLegalMaskedGather(Type *DataType,
494 Align Alignment) const {
495 return TTIImpl->isLegalMaskedGather(DataType, Alignment);
496 }
497
isLegalAltInstr(VectorType * VecTy,unsigned Opcode0,unsigned Opcode1,const SmallBitVector & OpcodeMask) const498 bool TargetTransformInfo::isLegalAltInstr(
499 VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
500 const SmallBitVector &OpcodeMask) const {
501 return TTIImpl->isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask);
502 }
503
isLegalMaskedScatter(Type * DataType,Align Alignment) const504 bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType,
505 Align Alignment) const {
506 return TTIImpl->isLegalMaskedScatter(DataType, Alignment);
507 }
508
forceScalarizeMaskedGather(VectorType * DataType,Align Alignment) const509 bool TargetTransformInfo::forceScalarizeMaskedGather(VectorType *DataType,
510 Align Alignment) const {
511 return TTIImpl->forceScalarizeMaskedGather(DataType, Alignment);
512 }
513
forceScalarizeMaskedScatter(VectorType * DataType,Align Alignment) const514 bool TargetTransformInfo::forceScalarizeMaskedScatter(VectorType *DataType,
515 Align Alignment) const {
516 return TTIImpl->forceScalarizeMaskedScatter(DataType, Alignment);
517 }
518
isLegalMaskedCompressStore(Type * DataType,Align Alignment) const519 bool TargetTransformInfo::isLegalMaskedCompressStore(Type *DataType,
520 Align Alignment) const {
521 return TTIImpl->isLegalMaskedCompressStore(DataType, Alignment);
522 }
523
isLegalMaskedExpandLoad(Type * DataType,Align Alignment) const524 bool TargetTransformInfo::isLegalMaskedExpandLoad(Type *DataType,
525 Align Alignment) const {
526 return TTIImpl->isLegalMaskedExpandLoad(DataType, Alignment);
527 }
528
isLegalStridedLoadStore(Type * DataType,Align Alignment) const529 bool TargetTransformInfo::isLegalStridedLoadStore(Type *DataType,
530 Align Alignment) const {
531 return TTIImpl->isLegalStridedLoadStore(DataType, Alignment);
532 }
533
isLegalInterleavedAccessType(VectorType * VTy,unsigned Factor,Align Alignment,unsigned AddrSpace) const534 bool TargetTransformInfo::isLegalInterleavedAccessType(
535 VectorType *VTy, unsigned Factor, Align Alignment,
536 unsigned AddrSpace) const {
537 return TTIImpl->isLegalInterleavedAccessType(VTy, Factor, Alignment,
538 AddrSpace);
539 }
540
isLegalMaskedVectorHistogram(Type * AddrType,Type * DataType) const541 bool TargetTransformInfo::isLegalMaskedVectorHistogram(Type *AddrType,
542 Type *DataType) const {
543 return TTIImpl->isLegalMaskedVectorHistogram(AddrType, DataType);
544 }
545
enableOrderedReductions() const546 bool TargetTransformInfo::enableOrderedReductions() const {
547 return TTIImpl->enableOrderedReductions();
548 }
549
hasDivRemOp(Type * DataType,bool IsSigned) const550 bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const {
551 return TTIImpl->hasDivRemOp(DataType, IsSigned);
552 }
553
hasVolatileVariant(Instruction * I,unsigned AddrSpace) const554 bool TargetTransformInfo::hasVolatileVariant(Instruction *I,
555 unsigned AddrSpace) const {
556 return TTIImpl->hasVolatileVariant(I, AddrSpace);
557 }
558
prefersVectorizedAddressing() const559 bool TargetTransformInfo::prefersVectorizedAddressing() const {
560 return TTIImpl->prefersVectorizedAddressing();
561 }
562
getScalingFactorCost(Type * Ty,GlobalValue * BaseGV,StackOffset BaseOffset,bool HasBaseReg,int64_t Scale,unsigned AddrSpace) const563 InstructionCost TargetTransformInfo::getScalingFactorCost(
564 Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg,
565 int64_t Scale, unsigned AddrSpace) const {
566 InstructionCost Cost = TTIImpl->getScalingFactorCost(
567 Ty, BaseGV, BaseOffset, HasBaseReg, Scale, AddrSpace);
568 assert(Cost >= 0 && "TTI should not produce negative costs!");
569 return Cost;
570 }
571
LSRWithInstrQueries() const572 bool TargetTransformInfo::LSRWithInstrQueries() const {
573 return TTIImpl->LSRWithInstrQueries();
574 }
575
isTruncateFree(Type * Ty1,Type * Ty2) const576 bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const {
577 return TTIImpl->isTruncateFree(Ty1, Ty2);
578 }
579
isProfitableToHoist(Instruction * I) const580 bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const {
581 return TTIImpl->isProfitableToHoist(I);
582 }
583
useAA() const584 bool TargetTransformInfo::useAA() const { return TTIImpl->useAA(); }
585
isTypeLegal(Type * Ty) const586 bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
587 return TTIImpl->isTypeLegal(Ty);
588 }
589
getRegUsageForType(Type * Ty) const590 unsigned TargetTransformInfo::getRegUsageForType(Type *Ty) const {
591 return TTIImpl->getRegUsageForType(Ty);
592 }
593
shouldBuildLookupTables() const594 bool TargetTransformInfo::shouldBuildLookupTables() const {
595 return TTIImpl->shouldBuildLookupTables();
596 }
597
shouldBuildLookupTablesForConstant(Constant * C) const598 bool TargetTransformInfo::shouldBuildLookupTablesForConstant(
599 Constant *C) const {
600 return TTIImpl->shouldBuildLookupTablesForConstant(C);
601 }
602
shouldBuildRelLookupTables() const603 bool TargetTransformInfo::shouldBuildRelLookupTables() const {
604 return TTIImpl->shouldBuildRelLookupTables();
605 }
606
useColdCCForColdCall(Function & F) const607 bool TargetTransformInfo::useColdCCForColdCall(Function &F) const {
608 return TTIImpl->useColdCCForColdCall(F);
609 }
610
isTargetIntrinsicTriviallyScalarizable(Intrinsic::ID ID) const611 bool TargetTransformInfo::isTargetIntrinsicTriviallyScalarizable(
612 Intrinsic::ID ID) const {
613 return TTIImpl->isTargetIntrinsicTriviallyScalarizable(ID);
614 }
615
isTargetIntrinsicWithScalarOpAtArg(Intrinsic::ID ID,unsigned ScalarOpdIdx) const616 bool TargetTransformInfo::isTargetIntrinsicWithScalarOpAtArg(
617 Intrinsic::ID ID, unsigned ScalarOpdIdx) const {
618 return TTIImpl->isTargetIntrinsicWithScalarOpAtArg(ID, ScalarOpdIdx);
619 }
620
isTargetIntrinsicWithOverloadTypeAtArg(Intrinsic::ID ID,int OpdIdx) const621 bool TargetTransformInfo::isTargetIntrinsicWithOverloadTypeAtArg(
622 Intrinsic::ID ID, int OpdIdx) const {
623 return TTIImpl->isTargetIntrinsicWithOverloadTypeAtArg(ID, OpdIdx);
624 }
625
isTargetIntrinsicWithStructReturnOverloadAtField(Intrinsic::ID ID,int RetIdx) const626 bool TargetTransformInfo::isTargetIntrinsicWithStructReturnOverloadAtField(
627 Intrinsic::ID ID, int RetIdx) const {
628 return TTIImpl->isTargetIntrinsicWithStructReturnOverloadAtField(ID, RetIdx);
629 }
630
getScalarizationOverhead(VectorType * Ty,const APInt & DemandedElts,bool Insert,bool Extract,TTI::TargetCostKind CostKind,bool ForPoisonSrc,ArrayRef<Value * > VL) const631 InstructionCost TargetTransformInfo::getScalarizationOverhead(
632 VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
633 TTI::TargetCostKind CostKind, bool ForPoisonSrc,
634 ArrayRef<Value *> VL) const {
635 return TTIImpl->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract,
636 CostKind, ForPoisonSrc, VL);
637 }
638
getOperandsScalarizationOverhead(ArrayRef<const Value * > Args,ArrayRef<Type * > Tys,TTI::TargetCostKind CostKind) const639 InstructionCost TargetTransformInfo::getOperandsScalarizationOverhead(
640 ArrayRef<const Value *> Args, ArrayRef<Type *> Tys,
641 TTI::TargetCostKind CostKind) const {
642 return TTIImpl->getOperandsScalarizationOverhead(Args, Tys, CostKind);
643 }
644
supportsEfficientVectorElementLoadStore() const645 bool TargetTransformInfo::supportsEfficientVectorElementLoadStore() const {
646 return TTIImpl->supportsEfficientVectorElementLoadStore();
647 }
648
supportsTailCalls() const649 bool TargetTransformInfo::supportsTailCalls() const {
650 return TTIImpl->supportsTailCalls();
651 }
652
supportsTailCallFor(const CallBase * CB) const653 bool TargetTransformInfo::supportsTailCallFor(const CallBase *CB) const {
654 return TTIImpl->supportsTailCallFor(CB);
655 }
656
enableAggressiveInterleaving(bool LoopHasReductions) const657 bool TargetTransformInfo::enableAggressiveInterleaving(
658 bool LoopHasReductions) const {
659 return TTIImpl->enableAggressiveInterleaving(LoopHasReductions);
660 }
661
662 TargetTransformInfo::MemCmpExpansionOptions
enableMemCmpExpansion(bool OptSize,bool IsZeroCmp) const663 TargetTransformInfo::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
664 return TTIImpl->enableMemCmpExpansion(OptSize, IsZeroCmp);
665 }
666
enableSelectOptimize() const667 bool TargetTransformInfo::enableSelectOptimize() const {
668 return TTIImpl->enableSelectOptimize();
669 }
670
shouldTreatInstructionLikeSelect(const Instruction * I) const671 bool TargetTransformInfo::shouldTreatInstructionLikeSelect(
672 const Instruction *I) const {
673 return TTIImpl->shouldTreatInstructionLikeSelect(I);
674 }
675
enableInterleavedAccessVectorization() const676 bool TargetTransformInfo::enableInterleavedAccessVectorization() const {
677 return TTIImpl->enableInterleavedAccessVectorization();
678 }
679
enableMaskedInterleavedAccessVectorization() const680 bool TargetTransformInfo::enableMaskedInterleavedAccessVectorization() const {
681 return TTIImpl->enableMaskedInterleavedAccessVectorization();
682 }
683
isFPVectorizationPotentiallyUnsafe() const684 bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const {
685 return TTIImpl->isFPVectorizationPotentiallyUnsafe();
686 }
687
688 bool
allowsMisalignedMemoryAccesses(LLVMContext & Context,unsigned BitWidth,unsigned AddressSpace,Align Alignment,unsigned * Fast) const689 TargetTransformInfo::allowsMisalignedMemoryAccesses(LLVMContext &Context,
690 unsigned BitWidth,
691 unsigned AddressSpace,
692 Align Alignment,
693 unsigned *Fast) const {
694 return TTIImpl->allowsMisalignedMemoryAccesses(Context, BitWidth,
695 AddressSpace, Alignment, Fast);
696 }
697
698 TargetTransformInfo::PopcntSupportKind
getPopcntSupport(unsigned IntTyWidthInBit) const699 TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const {
700 return TTIImpl->getPopcntSupport(IntTyWidthInBit);
701 }
702
haveFastSqrt(Type * Ty) const703 bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
704 return TTIImpl->haveFastSqrt(Ty);
705 }
706
isExpensiveToSpeculativelyExecute(const Instruction * I) const707 bool TargetTransformInfo::isExpensiveToSpeculativelyExecute(
708 const Instruction *I) const {
709 return TTIImpl->isExpensiveToSpeculativelyExecute(I);
710 }
711
isFCmpOrdCheaperThanFCmpZero(Type * Ty) const712 bool TargetTransformInfo::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const {
713 return TTIImpl->isFCmpOrdCheaperThanFCmpZero(Ty);
714 }
715
getFPOpCost(Type * Ty) const716 InstructionCost TargetTransformInfo::getFPOpCost(Type *Ty) const {
717 InstructionCost Cost = TTIImpl->getFPOpCost(Ty);
718 assert(Cost >= 0 && "TTI should not produce negative costs!");
719 return Cost;
720 }
721
getIntImmCodeSizeCost(unsigned Opcode,unsigned Idx,const APInt & Imm,Type * Ty) const722 InstructionCost TargetTransformInfo::getIntImmCodeSizeCost(unsigned Opcode,
723 unsigned Idx,
724 const APInt &Imm,
725 Type *Ty) const {
726 InstructionCost Cost = TTIImpl->getIntImmCodeSizeCost(Opcode, Idx, Imm, Ty);
727 assert(Cost >= 0 && "TTI should not produce negative costs!");
728 return Cost;
729 }
730
731 InstructionCost
getIntImmCost(const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind) const732 TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty,
733 TTI::TargetCostKind CostKind) const {
734 InstructionCost Cost = TTIImpl->getIntImmCost(Imm, Ty, CostKind);
735 assert(Cost >= 0 && "TTI should not produce negative costs!");
736 return Cost;
737 }
738
getIntImmCostInst(unsigned Opcode,unsigned Idx,const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind,Instruction * Inst) const739 InstructionCost TargetTransformInfo::getIntImmCostInst(
740 unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty,
741 TTI::TargetCostKind CostKind, Instruction *Inst) const {
742 InstructionCost Cost =
743 TTIImpl->getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
744 assert(Cost >= 0 && "TTI should not produce negative costs!");
745 return Cost;
746 }
747
748 InstructionCost
getIntImmCostIntrin(Intrinsic::ID IID,unsigned Idx,const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind) const749 TargetTransformInfo::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
750 const APInt &Imm, Type *Ty,
751 TTI::TargetCostKind CostKind) const {
752 InstructionCost Cost =
753 TTIImpl->getIntImmCostIntrin(IID, Idx, Imm, Ty, CostKind);
754 assert(Cost >= 0 && "TTI should not produce negative costs!");
755 return Cost;
756 }
757
preferToKeepConstantsAttached(const Instruction & Inst,const Function & Fn) const758 bool TargetTransformInfo::preferToKeepConstantsAttached(
759 const Instruction &Inst, const Function &Fn) const {
760 return TTIImpl->preferToKeepConstantsAttached(Inst, Fn);
761 }
762
getNumberOfRegisters(unsigned ClassID) const763 unsigned TargetTransformInfo::getNumberOfRegisters(unsigned ClassID) const {
764 return TTIImpl->getNumberOfRegisters(ClassID);
765 }
766
hasConditionalLoadStoreForType(Type * Ty,bool IsStore) const767 bool TargetTransformInfo::hasConditionalLoadStoreForType(Type *Ty,
768 bool IsStore) const {
769 return TTIImpl->hasConditionalLoadStoreForType(Ty, IsStore);
770 }
771
getRegisterClassForType(bool Vector,Type * Ty) const772 unsigned TargetTransformInfo::getRegisterClassForType(bool Vector,
773 Type *Ty) const {
774 return TTIImpl->getRegisterClassForType(Vector, Ty);
775 }
776
getRegisterClassName(unsigned ClassID) const777 const char *TargetTransformInfo::getRegisterClassName(unsigned ClassID) const {
778 return TTIImpl->getRegisterClassName(ClassID);
779 }
780
getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const781 TypeSize TargetTransformInfo::getRegisterBitWidth(
782 TargetTransformInfo::RegisterKind K) const {
783 return TTIImpl->getRegisterBitWidth(K);
784 }
785
getMinVectorRegisterBitWidth() const786 unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const {
787 return TTIImpl->getMinVectorRegisterBitWidth();
788 }
789
getMaxVScale() const790 std::optional<unsigned> TargetTransformInfo::getMaxVScale() const {
791 return TTIImpl->getMaxVScale();
792 }
793
getVScaleForTuning() const794 std::optional<unsigned> TargetTransformInfo::getVScaleForTuning() const {
795 return TTIImpl->getVScaleForTuning();
796 }
797
isVScaleKnownToBeAPowerOfTwo() const798 bool TargetTransformInfo::isVScaleKnownToBeAPowerOfTwo() const {
799 return TTIImpl->isVScaleKnownToBeAPowerOfTwo();
800 }
801
shouldMaximizeVectorBandwidth(TargetTransformInfo::RegisterKind K) const802 bool TargetTransformInfo::shouldMaximizeVectorBandwidth(
803 TargetTransformInfo::RegisterKind K) const {
804 return TTIImpl->shouldMaximizeVectorBandwidth(K);
805 }
806
getMinimumVF(unsigned ElemWidth,bool IsScalable) const807 ElementCount TargetTransformInfo::getMinimumVF(unsigned ElemWidth,
808 bool IsScalable) const {
809 return TTIImpl->getMinimumVF(ElemWidth, IsScalable);
810 }
811
getMaximumVF(unsigned ElemWidth,unsigned Opcode) const812 unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth,
813 unsigned Opcode) const {
814 return TTIImpl->getMaximumVF(ElemWidth, Opcode);
815 }
816
getStoreMinimumVF(unsigned VF,Type * ScalarMemTy,Type * ScalarValTy) const817 unsigned TargetTransformInfo::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
818 Type *ScalarValTy) const {
819 return TTIImpl->getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy);
820 }
821
shouldConsiderAddressTypePromotion(const Instruction & I,bool & AllowPromotionWithoutCommonHeader) const822 bool TargetTransformInfo::shouldConsiderAddressTypePromotion(
823 const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
824 return TTIImpl->shouldConsiderAddressTypePromotion(
825 I, AllowPromotionWithoutCommonHeader);
826 }
827
getCacheLineSize() const828 unsigned TargetTransformInfo::getCacheLineSize() const {
829 return CacheLineSize.getNumOccurrences() > 0 ? CacheLineSize
830 : TTIImpl->getCacheLineSize();
831 }
832
833 std::optional<unsigned>
getCacheSize(CacheLevel Level) const834 TargetTransformInfo::getCacheSize(CacheLevel Level) const {
835 return TTIImpl->getCacheSize(Level);
836 }
837
838 std::optional<unsigned>
getCacheAssociativity(CacheLevel Level) const839 TargetTransformInfo::getCacheAssociativity(CacheLevel Level) const {
840 return TTIImpl->getCacheAssociativity(Level);
841 }
842
getMinPageSize() const843 std::optional<unsigned> TargetTransformInfo::getMinPageSize() const {
844 return MinPageSize.getNumOccurrences() > 0 ? MinPageSize
845 : TTIImpl->getMinPageSize();
846 }
847
getPrefetchDistance() const848 unsigned TargetTransformInfo::getPrefetchDistance() const {
849 return TTIImpl->getPrefetchDistance();
850 }
851
getMinPrefetchStride(unsigned NumMemAccesses,unsigned NumStridedMemAccesses,unsigned NumPrefetches,bool HasCall) const852 unsigned TargetTransformInfo::getMinPrefetchStride(
853 unsigned NumMemAccesses, unsigned NumStridedMemAccesses,
854 unsigned NumPrefetches, bool HasCall) const {
855 return TTIImpl->getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
856 NumPrefetches, HasCall);
857 }
858
getMaxPrefetchIterationsAhead() const859 unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const {
860 return TTIImpl->getMaxPrefetchIterationsAhead();
861 }
862
enableWritePrefetching() const863 bool TargetTransformInfo::enableWritePrefetching() const {
864 return TTIImpl->enableWritePrefetching();
865 }
866
shouldPrefetchAddressSpace(unsigned AS) const867 bool TargetTransformInfo::shouldPrefetchAddressSpace(unsigned AS) const {
868 return TTIImpl->shouldPrefetchAddressSpace(AS);
869 }
870
getPartialReductionCost(unsigned Opcode,Type * InputTypeA,Type * InputTypeB,Type * AccumType,ElementCount VF,PartialReductionExtendKind OpAExtend,PartialReductionExtendKind OpBExtend,std::optional<unsigned> BinOp,TTI::TargetCostKind CostKind) const871 InstructionCost TargetTransformInfo::getPartialReductionCost(
872 unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
873 ElementCount VF, PartialReductionExtendKind OpAExtend,
874 PartialReductionExtendKind OpBExtend, std::optional<unsigned> BinOp,
875 TTI::TargetCostKind CostKind) const {
876 return TTIImpl->getPartialReductionCost(Opcode, InputTypeA, InputTypeB,
877 AccumType, VF, OpAExtend, OpBExtend,
878 BinOp, CostKind);
879 }
880
getMaxInterleaveFactor(ElementCount VF) const881 unsigned TargetTransformInfo::getMaxInterleaveFactor(ElementCount VF) const {
882 return TTIImpl->getMaxInterleaveFactor(VF);
883 }
884
885 TargetTransformInfo::OperandValueInfo
getOperandInfo(const Value * V)886 TargetTransformInfo::getOperandInfo(const Value *V) {
887 OperandValueKind OpInfo = OK_AnyValue;
888 OperandValueProperties OpProps = OP_None;
889
890 // undef/poison don't materialize constants.
891 if (isa<UndefValue>(V))
892 return {OK_AnyValue, OP_None};
893
894 if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) {
895 if (const auto *CI = dyn_cast<ConstantInt>(V)) {
896 if (CI->getValue().isPowerOf2())
897 OpProps = OP_PowerOf2;
898 else if (CI->getValue().isNegatedPowerOf2())
899 OpProps = OP_NegatedPowerOf2;
900 }
901 return {OK_UniformConstantValue, OpProps};
902 }
903
904 // A broadcast shuffle creates a uniform value.
905 // TODO: Add support for non-zero index broadcasts.
906 // TODO: Add support for different source vector width.
907 if (const auto *ShuffleInst = dyn_cast<ShuffleVectorInst>(V))
908 if (ShuffleInst->isZeroEltSplat())
909 OpInfo = OK_UniformValue;
910
911 const Value *Splat = getSplatValue(V);
912
913 // Check for a splat of a constant or for a non uniform vector of constants
914 // and check if the constant(s) are all powers of two.
915 if (Splat) {
916 // Check for a splat of a uniform value. This is not loop aware, so return
917 // true only for the obviously uniform cases (argument, globalvalue)
918 if (isa<Argument>(Splat) || isa<GlobalValue>(Splat)) {
919 OpInfo = OK_UniformValue;
920 } else if (isa<Constant>(Splat)) {
921 OpInfo = OK_UniformConstantValue;
922 if (auto *CI = dyn_cast<ConstantInt>(Splat)) {
923 if (CI->getValue().isPowerOf2())
924 OpProps = OP_PowerOf2;
925 else if (CI->getValue().isNegatedPowerOf2())
926 OpProps = OP_NegatedPowerOf2;
927 }
928 }
929 } else if (const auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
930 OpInfo = OK_NonUniformConstantValue;
931 bool AllPow2 = true, AllNegPow2 = true;
932 for (uint64_t I = 0, E = CDS->getNumElements(); I != E; ++I) {
933 if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I))) {
934 AllPow2 &= CI->getValue().isPowerOf2();
935 AllNegPow2 &= CI->getValue().isNegatedPowerOf2();
936 if (AllPow2 || AllNegPow2)
937 continue;
938 }
939 AllPow2 = AllNegPow2 = false;
940 break;
941 }
942 OpProps = AllPow2 ? OP_PowerOf2 : OpProps;
943 OpProps = AllNegPow2 ? OP_NegatedPowerOf2 : OpProps;
944 } else if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
945 OpInfo = OK_NonUniformConstantValue;
946 }
947
948 return {OpInfo, OpProps};
949 }
950
getArithmeticInstrCost(unsigned Opcode,Type * Ty,TTI::TargetCostKind CostKind,OperandValueInfo Op1Info,OperandValueInfo Op2Info,ArrayRef<const Value * > Args,const Instruction * CxtI,const TargetLibraryInfo * TLibInfo) const951 InstructionCost TargetTransformInfo::getArithmeticInstrCost(
952 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
953 OperandValueInfo Op1Info, OperandValueInfo Op2Info,
954 ArrayRef<const Value *> Args, const Instruction *CxtI,
955 const TargetLibraryInfo *TLibInfo) const {
956
957 // Use call cost for frem intructions that have platform specific vector math
958 // functions, as those will be replaced with calls later by SelectionDAG or
959 // ReplaceWithVecLib pass.
960 if (TLibInfo && Opcode == Instruction::FRem) {
961 VectorType *VecTy = dyn_cast<VectorType>(Ty);
962 LibFunc Func;
963 if (VecTy &&
964 TLibInfo->getLibFunc(Instruction::FRem, Ty->getScalarType(), Func) &&
965 TLibInfo->isFunctionVectorizable(TLibInfo->getName(Func),
966 VecTy->getElementCount()))
967 return getCallInstrCost(nullptr, VecTy, {VecTy, VecTy}, CostKind);
968 }
969
970 InstructionCost Cost =
971 TTIImpl->getArithmeticInstrCost(Opcode, Ty, CostKind,
972 Op1Info, Op2Info,
973 Args, CxtI);
974 assert(Cost >= 0 && "TTI should not produce negative costs!");
975 return Cost;
976 }
977
getAltInstrCost(VectorType * VecTy,unsigned Opcode0,unsigned Opcode1,const SmallBitVector & OpcodeMask,TTI::TargetCostKind CostKind) const978 InstructionCost TargetTransformInfo::getAltInstrCost(
979 VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
980 const SmallBitVector &OpcodeMask, TTI::TargetCostKind CostKind) const {
981 InstructionCost Cost =
982 TTIImpl->getAltInstrCost(VecTy, Opcode0, Opcode1, OpcodeMask, CostKind);
983 assert(Cost >= 0 && "TTI should not produce negative costs!");
984 return Cost;
985 }
986
getShuffleCost(ShuffleKind Kind,VectorType * DstTy,VectorType * SrcTy,ArrayRef<int> Mask,TTI::TargetCostKind CostKind,int Index,VectorType * SubTp,ArrayRef<const Value * > Args,const Instruction * CxtI) const987 InstructionCost TargetTransformInfo::getShuffleCost(
988 ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, ArrayRef<int> Mask,
989 TTI::TargetCostKind CostKind, int Index, VectorType *SubTp,
990 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
991 assert((Mask.empty() || DstTy->isScalableTy() ||
992 Mask.size() == DstTy->getElementCount().getKnownMinValue()) &&
993 "Expected the Mask to match the return size if given");
994 assert(SrcTy->getScalarType() == DstTy->getScalarType() &&
995 "Expected the same scalar types");
996 InstructionCost Cost = TTIImpl->getShuffleCost(
997 Kind, DstTy, SrcTy, Mask, CostKind, Index, SubTp, Args, CxtI);
998 assert(Cost >= 0 && "TTI should not produce negative costs!");
999 return Cost;
1000 }
1001
1002 TargetTransformInfo::PartialReductionExtendKind
getPartialReductionExtendKind(Instruction * I)1003 TargetTransformInfo::getPartialReductionExtendKind(Instruction *I) {
1004 if (isa<SExtInst>(I))
1005 return PR_SignExtend;
1006 if (isa<ZExtInst>(I))
1007 return PR_ZeroExtend;
1008 return PR_None;
1009 }
1010
1011 TTI::CastContextHint
getCastContextHint(const Instruction * I)1012 TargetTransformInfo::getCastContextHint(const Instruction *I) {
1013 if (!I)
1014 return CastContextHint::None;
1015
1016 auto getLoadStoreKind = [](const Value *V, unsigned LdStOp, unsigned MaskedOp,
1017 unsigned GatScatOp) {
1018 const Instruction *I = dyn_cast<Instruction>(V);
1019 if (!I)
1020 return CastContextHint::None;
1021
1022 if (I->getOpcode() == LdStOp)
1023 return CastContextHint::Normal;
1024
1025 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
1026 if (II->getIntrinsicID() == MaskedOp)
1027 return TTI::CastContextHint::Masked;
1028 if (II->getIntrinsicID() == GatScatOp)
1029 return TTI::CastContextHint::GatherScatter;
1030 }
1031
1032 return TTI::CastContextHint::None;
1033 };
1034
1035 switch (I->getOpcode()) {
1036 case Instruction::ZExt:
1037 case Instruction::SExt:
1038 case Instruction::FPExt:
1039 return getLoadStoreKind(I->getOperand(0), Instruction::Load,
1040 Intrinsic::masked_load, Intrinsic::masked_gather);
1041 case Instruction::Trunc:
1042 case Instruction::FPTrunc:
1043 if (I->hasOneUse())
1044 return getLoadStoreKind(*I->user_begin(), Instruction::Store,
1045 Intrinsic::masked_store,
1046 Intrinsic::masked_scatter);
1047 break;
1048 default:
1049 return CastContextHint::None;
1050 }
1051
1052 return TTI::CastContextHint::None;
1053 }
1054
getCastInstrCost(unsigned Opcode,Type * Dst,Type * Src,CastContextHint CCH,TTI::TargetCostKind CostKind,const Instruction * I) const1055 InstructionCost TargetTransformInfo::getCastInstrCost(
1056 unsigned Opcode, Type *Dst, Type *Src, CastContextHint CCH,
1057 TTI::TargetCostKind CostKind, const Instruction *I) const {
1058 assert((I == nullptr || I->getOpcode() == Opcode) &&
1059 "Opcode should reflect passed instruction.");
1060 InstructionCost Cost =
1061 TTIImpl->getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
1062 assert(Cost >= 0 && "TTI should not produce negative costs!");
1063 return Cost;
1064 }
1065
getExtractWithExtendCost(unsigned Opcode,Type * Dst,VectorType * VecTy,unsigned Index,TTI::TargetCostKind CostKind) const1066 InstructionCost TargetTransformInfo::getExtractWithExtendCost(
1067 unsigned Opcode, Type *Dst, VectorType *VecTy, unsigned Index,
1068 TTI::TargetCostKind CostKind) const {
1069 InstructionCost Cost =
1070 TTIImpl->getExtractWithExtendCost(Opcode, Dst, VecTy, Index, CostKind);
1071 assert(Cost >= 0 && "TTI should not produce negative costs!");
1072 return Cost;
1073 }
1074
getCFInstrCost(unsigned Opcode,TTI::TargetCostKind CostKind,const Instruction * I) const1075 InstructionCost TargetTransformInfo::getCFInstrCost(
1076 unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I) const {
1077 assert((I == nullptr || I->getOpcode() == Opcode) &&
1078 "Opcode should reflect passed instruction.");
1079 InstructionCost Cost = TTIImpl->getCFInstrCost(Opcode, CostKind, I);
1080 assert(Cost >= 0 && "TTI should not produce negative costs!");
1081 return Cost;
1082 }
1083
getCmpSelInstrCost(unsigned Opcode,Type * ValTy,Type * CondTy,CmpInst::Predicate VecPred,TTI::TargetCostKind CostKind,OperandValueInfo Op1Info,OperandValueInfo Op2Info,const Instruction * I) const1084 InstructionCost TargetTransformInfo::getCmpSelInstrCost(
1085 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
1086 TTI::TargetCostKind CostKind, OperandValueInfo Op1Info,
1087 OperandValueInfo Op2Info, const Instruction *I) const {
1088 assert((I == nullptr || I->getOpcode() == Opcode) &&
1089 "Opcode should reflect passed instruction.");
1090 InstructionCost Cost = TTIImpl->getCmpSelInstrCost(
1091 Opcode, ValTy, CondTy, VecPred, CostKind, Op1Info, Op2Info, I);
1092 assert(Cost >= 0 && "TTI should not produce negative costs!");
1093 return Cost;
1094 }
1095
getVectorInstrCost(unsigned Opcode,Type * Val,TTI::TargetCostKind CostKind,unsigned Index,const Value * Op0,const Value * Op1) const1096 InstructionCost TargetTransformInfo::getVectorInstrCost(
1097 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
1098 const Value *Op0, const Value *Op1) const {
1099 assert((Opcode == Instruction::InsertElement ||
1100 Opcode == Instruction::ExtractElement) &&
1101 "Expecting Opcode to be insertelement/extractelement.");
1102 InstructionCost Cost =
1103 TTIImpl->getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1);
1104 assert(Cost >= 0 && "TTI should not produce negative costs!");
1105 return Cost;
1106 }
1107
getVectorInstrCost(unsigned Opcode,Type * Val,TTI::TargetCostKind CostKind,unsigned Index,Value * Scalar,ArrayRef<std::tuple<Value *,User *,int>> ScalarUserAndIdx) const1108 InstructionCost TargetTransformInfo::getVectorInstrCost(
1109 unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
1110 Value *Scalar,
1111 ArrayRef<std::tuple<Value *, User *, int>> ScalarUserAndIdx) const {
1112 assert((Opcode == Instruction::InsertElement ||
1113 Opcode == Instruction::ExtractElement) &&
1114 "Expecting Opcode to be insertelement/extractelement.");
1115 InstructionCost Cost = TTIImpl->getVectorInstrCost(
1116 Opcode, Val, CostKind, Index, Scalar, ScalarUserAndIdx);
1117 assert(Cost >= 0 && "TTI should not produce negative costs!");
1118 return Cost;
1119 }
1120
1121 InstructionCost
getVectorInstrCost(const Instruction & I,Type * Val,TTI::TargetCostKind CostKind,unsigned Index) const1122 TargetTransformInfo::getVectorInstrCost(const Instruction &I, Type *Val,
1123 TTI::TargetCostKind CostKind,
1124 unsigned Index) const {
1125 // FIXME: Assert that Opcode is either InsertElement or ExtractElement.
1126 // This is mentioned in the interface description and respected by all
1127 // callers, but never asserted upon.
1128 InstructionCost Cost = TTIImpl->getVectorInstrCost(I, Val, CostKind, Index);
1129 assert(Cost >= 0 && "TTI should not produce negative costs!");
1130 return Cost;
1131 }
1132
getInsertExtractValueCost(unsigned Opcode,TTI::TargetCostKind CostKind) const1133 InstructionCost TargetTransformInfo::getInsertExtractValueCost(
1134 unsigned Opcode, TTI::TargetCostKind CostKind) const {
1135 assert((Opcode == Instruction::InsertValue ||
1136 Opcode == Instruction::ExtractValue) &&
1137 "Expecting Opcode to be insertvalue/extractvalue.");
1138 InstructionCost Cost = TTIImpl->getInsertExtractValueCost(Opcode, CostKind);
1139 assert(Cost >= 0 && "TTI should not produce negative costs!");
1140 return Cost;
1141 }
1142
getReplicationShuffleCost(Type * EltTy,int ReplicationFactor,int VF,const APInt & DemandedDstElts,TTI::TargetCostKind CostKind) const1143 InstructionCost TargetTransformInfo::getReplicationShuffleCost(
1144 Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts,
1145 TTI::TargetCostKind CostKind) const {
1146 InstructionCost Cost = TTIImpl->getReplicationShuffleCost(
1147 EltTy, ReplicationFactor, VF, DemandedDstElts, CostKind);
1148 assert(Cost >= 0 && "TTI should not produce negative costs!");
1149 return Cost;
1150 }
1151
getMemoryOpCost(unsigned Opcode,Type * Src,Align Alignment,unsigned AddressSpace,TTI::TargetCostKind CostKind,TTI::OperandValueInfo OpInfo,const Instruction * I) const1152 InstructionCost TargetTransformInfo::getMemoryOpCost(
1153 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
1154 TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo,
1155 const Instruction *I) const {
1156 assert((I == nullptr || I->getOpcode() == Opcode) &&
1157 "Opcode should reflect passed instruction.");
1158 InstructionCost Cost = TTIImpl->getMemoryOpCost(
1159 Opcode, Src, Alignment, AddressSpace, CostKind, OpInfo, I);
1160 assert(Cost >= 0 && "TTI should not produce negative costs!");
1161 return Cost;
1162 }
1163
getMaskedMemoryOpCost(unsigned Opcode,Type * Src,Align Alignment,unsigned AddressSpace,TTI::TargetCostKind CostKind) const1164 InstructionCost TargetTransformInfo::getMaskedMemoryOpCost(
1165 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
1166 TTI::TargetCostKind CostKind) const {
1167 InstructionCost Cost = TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment,
1168 AddressSpace, CostKind);
1169 assert(Cost >= 0 && "TTI should not produce negative costs!");
1170 return Cost;
1171 }
1172
getGatherScatterOpCost(unsigned Opcode,Type * DataTy,const Value * Ptr,bool VariableMask,Align Alignment,TTI::TargetCostKind CostKind,const Instruction * I) const1173 InstructionCost TargetTransformInfo::getGatherScatterOpCost(
1174 unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
1175 Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I) const {
1176 InstructionCost Cost = TTIImpl->getGatherScatterOpCost(
1177 Opcode, DataTy, Ptr, VariableMask, Alignment, CostKind, I);
1178 assert((!Cost.isValid() || Cost >= 0) &&
1179 "TTI should not produce negative costs!");
1180 return Cost;
1181 }
1182
getExpandCompressMemoryOpCost(unsigned Opcode,Type * DataTy,bool VariableMask,Align Alignment,TTI::TargetCostKind CostKind,const Instruction * I) const1183 InstructionCost TargetTransformInfo::getExpandCompressMemoryOpCost(
1184 unsigned Opcode, Type *DataTy, bool VariableMask, Align Alignment,
1185 TTI::TargetCostKind CostKind, const Instruction *I) const {
1186 InstructionCost Cost = TTIImpl->getExpandCompressMemoryOpCost(
1187 Opcode, DataTy, VariableMask, Alignment, CostKind, I);
1188 assert(Cost >= 0 && "TTI should not produce negative costs!");
1189 return Cost;
1190 }
1191
getStridedMemoryOpCost(unsigned Opcode,Type * DataTy,const Value * Ptr,bool VariableMask,Align Alignment,TTI::TargetCostKind CostKind,const Instruction * I) const1192 InstructionCost TargetTransformInfo::getStridedMemoryOpCost(
1193 unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
1194 Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I) const {
1195 InstructionCost Cost = TTIImpl->getStridedMemoryOpCost(
1196 Opcode, DataTy, Ptr, VariableMask, Alignment, CostKind, I);
1197 assert(Cost >= 0 && "TTI should not produce negative costs!");
1198 return Cost;
1199 }
1200
getInterleavedMemoryOpCost(unsigned Opcode,Type * VecTy,unsigned Factor,ArrayRef<unsigned> Indices,Align Alignment,unsigned AddressSpace,TTI::TargetCostKind CostKind,bool UseMaskForCond,bool UseMaskForGaps) const1201 InstructionCost TargetTransformInfo::getInterleavedMemoryOpCost(
1202 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
1203 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
1204 bool UseMaskForCond, bool UseMaskForGaps) const {
1205 InstructionCost Cost = TTIImpl->getInterleavedMemoryOpCost(
1206 Opcode, VecTy, Factor, Indices, Alignment, AddressSpace, CostKind,
1207 UseMaskForCond, UseMaskForGaps);
1208 assert(Cost >= 0 && "TTI should not produce negative costs!");
1209 return Cost;
1210 }
1211
1212 InstructionCost
getIntrinsicInstrCost(const IntrinsicCostAttributes & ICA,TTI::TargetCostKind CostKind) const1213 TargetTransformInfo::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
1214 TTI::TargetCostKind CostKind) const {
1215 InstructionCost Cost = TTIImpl->getIntrinsicInstrCost(ICA, CostKind);
1216 assert(Cost >= 0 && "TTI should not produce negative costs!");
1217 return Cost;
1218 }
1219
1220 InstructionCost
getCallInstrCost(Function * F,Type * RetTy,ArrayRef<Type * > Tys,TTI::TargetCostKind CostKind) const1221 TargetTransformInfo::getCallInstrCost(Function *F, Type *RetTy,
1222 ArrayRef<Type *> Tys,
1223 TTI::TargetCostKind CostKind) const {
1224 InstructionCost Cost = TTIImpl->getCallInstrCost(F, RetTy, Tys, CostKind);
1225 assert(Cost >= 0 && "TTI should not produce negative costs!");
1226 return Cost;
1227 }
1228
getNumberOfParts(Type * Tp) const1229 unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const {
1230 return TTIImpl->getNumberOfParts(Tp);
1231 }
1232
1233 InstructionCost
getAddressComputationCost(Type * Tp,ScalarEvolution * SE,const SCEV * Ptr) const1234 TargetTransformInfo::getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
1235 const SCEV *Ptr) const {
1236 InstructionCost Cost = TTIImpl->getAddressComputationCost(Tp, SE, Ptr);
1237 assert(Cost >= 0 && "TTI should not produce negative costs!");
1238 return Cost;
1239 }
1240
getMemcpyCost(const Instruction * I) const1241 InstructionCost TargetTransformInfo::getMemcpyCost(const Instruction *I) const {
1242 InstructionCost Cost = TTIImpl->getMemcpyCost(I);
1243 assert(Cost >= 0 && "TTI should not produce negative costs!");
1244 return Cost;
1245 }
1246
getMaxMemIntrinsicInlineSizeThreshold() const1247 uint64_t TargetTransformInfo::getMaxMemIntrinsicInlineSizeThreshold() const {
1248 return TTIImpl->getMaxMemIntrinsicInlineSizeThreshold();
1249 }
1250
getArithmeticReductionCost(unsigned Opcode,VectorType * Ty,std::optional<FastMathFlags> FMF,TTI::TargetCostKind CostKind) const1251 InstructionCost TargetTransformInfo::getArithmeticReductionCost(
1252 unsigned Opcode, VectorType *Ty, std::optional<FastMathFlags> FMF,
1253 TTI::TargetCostKind CostKind) const {
1254 InstructionCost Cost =
1255 TTIImpl->getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1256 assert(Cost >= 0 && "TTI should not produce negative costs!");
1257 return Cost;
1258 }
1259
getMinMaxReductionCost(Intrinsic::ID IID,VectorType * Ty,FastMathFlags FMF,TTI::TargetCostKind CostKind) const1260 InstructionCost TargetTransformInfo::getMinMaxReductionCost(
1261 Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,
1262 TTI::TargetCostKind CostKind) const {
1263 InstructionCost Cost =
1264 TTIImpl->getMinMaxReductionCost(IID, Ty, FMF, CostKind);
1265 assert(Cost >= 0 && "TTI should not produce negative costs!");
1266 return Cost;
1267 }
1268
getExtendedReductionCost(unsigned Opcode,bool IsUnsigned,Type * ResTy,VectorType * Ty,std::optional<FastMathFlags> FMF,TTI::TargetCostKind CostKind) const1269 InstructionCost TargetTransformInfo::getExtendedReductionCost(
1270 unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *Ty,
1271 std::optional<FastMathFlags> FMF, TTI::TargetCostKind CostKind) const {
1272 return TTIImpl->getExtendedReductionCost(Opcode, IsUnsigned, ResTy, Ty, FMF,
1273 CostKind);
1274 }
1275
getMulAccReductionCost(bool IsUnsigned,Type * ResTy,VectorType * Ty,TTI::TargetCostKind CostKind) const1276 InstructionCost TargetTransformInfo::getMulAccReductionCost(
1277 bool IsUnsigned, Type *ResTy, VectorType *Ty,
1278 TTI::TargetCostKind CostKind) const {
1279 return TTIImpl->getMulAccReductionCost(IsUnsigned, ResTy, Ty, CostKind);
1280 }
1281
1282 InstructionCost
getCostOfKeepingLiveOverCall(ArrayRef<Type * > Tys) const1283 TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
1284 return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
1285 }
1286
getTgtMemIntrinsic(IntrinsicInst * Inst,MemIntrinsicInfo & Info) const1287 bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
1288 MemIntrinsicInfo &Info) const {
1289 return TTIImpl->getTgtMemIntrinsic(Inst, Info);
1290 }
1291
getAtomicMemIntrinsicMaxElementSize() const1292 unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const {
1293 return TTIImpl->getAtomicMemIntrinsicMaxElementSize();
1294 }
1295
getOrCreateResultFromMemIntrinsic(IntrinsicInst * Inst,Type * ExpectedType,bool CanCreate) const1296 Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic(
1297 IntrinsicInst *Inst, Type *ExpectedType, bool CanCreate) const {
1298 return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType,
1299 CanCreate);
1300 }
1301
getMemcpyLoopLoweringType(LLVMContext & Context,Value * Length,unsigned SrcAddrSpace,unsigned DestAddrSpace,Align SrcAlign,Align DestAlign,std::optional<uint32_t> AtomicElementSize) const1302 Type *TargetTransformInfo::getMemcpyLoopLoweringType(
1303 LLVMContext &Context, Value *Length, unsigned SrcAddrSpace,
1304 unsigned DestAddrSpace, Align SrcAlign, Align DestAlign,
1305 std::optional<uint32_t> AtomicElementSize) const {
1306 return TTIImpl->getMemcpyLoopLoweringType(Context, Length, SrcAddrSpace,
1307 DestAddrSpace, SrcAlign, DestAlign,
1308 AtomicElementSize);
1309 }
1310
getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type * > & OpsOut,LLVMContext & Context,unsigned RemainingBytes,unsigned SrcAddrSpace,unsigned DestAddrSpace,Align SrcAlign,Align DestAlign,std::optional<uint32_t> AtomicCpySize) const1311 void TargetTransformInfo::getMemcpyLoopResidualLoweringType(
1312 SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
1313 unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
1314 Align SrcAlign, Align DestAlign,
1315 std::optional<uint32_t> AtomicCpySize) const {
1316 TTIImpl->getMemcpyLoopResidualLoweringType(
1317 OpsOut, Context, RemainingBytes, SrcAddrSpace, DestAddrSpace, SrcAlign,
1318 DestAlign, AtomicCpySize);
1319 }
1320
areInlineCompatible(const Function * Caller,const Function * Callee) const1321 bool TargetTransformInfo::areInlineCompatible(const Function *Caller,
1322 const Function *Callee) const {
1323 return TTIImpl->areInlineCompatible(Caller, Callee);
1324 }
1325
1326 unsigned
getInlineCallPenalty(const Function * F,const CallBase & Call,unsigned DefaultCallPenalty) const1327 TargetTransformInfo::getInlineCallPenalty(const Function *F,
1328 const CallBase &Call,
1329 unsigned DefaultCallPenalty) const {
1330 return TTIImpl->getInlineCallPenalty(F, Call, DefaultCallPenalty);
1331 }
1332
areTypesABICompatible(const Function * Caller,const Function * Callee,const ArrayRef<Type * > & Types) const1333 bool TargetTransformInfo::areTypesABICompatible(
1334 const Function *Caller, const Function *Callee,
1335 const ArrayRef<Type *> &Types) const {
1336 return TTIImpl->areTypesABICompatible(Caller, Callee, Types);
1337 }
1338
isIndexedLoadLegal(MemIndexedMode Mode,Type * Ty) const1339 bool TargetTransformInfo::isIndexedLoadLegal(MemIndexedMode Mode,
1340 Type *Ty) const {
1341 return TTIImpl->isIndexedLoadLegal(Mode, Ty);
1342 }
1343
isIndexedStoreLegal(MemIndexedMode Mode,Type * Ty) const1344 bool TargetTransformInfo::isIndexedStoreLegal(MemIndexedMode Mode,
1345 Type *Ty) const {
1346 return TTIImpl->isIndexedStoreLegal(Mode, Ty);
1347 }
1348
getLoadStoreVecRegBitWidth(unsigned AS) const1349 unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const {
1350 return TTIImpl->getLoadStoreVecRegBitWidth(AS);
1351 }
1352
isLegalToVectorizeLoad(LoadInst * LI) const1353 bool TargetTransformInfo::isLegalToVectorizeLoad(LoadInst *LI) const {
1354 return TTIImpl->isLegalToVectorizeLoad(LI);
1355 }
1356
isLegalToVectorizeStore(StoreInst * SI) const1357 bool TargetTransformInfo::isLegalToVectorizeStore(StoreInst *SI) const {
1358 return TTIImpl->isLegalToVectorizeStore(SI);
1359 }
1360
isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,Align Alignment,unsigned AddrSpace) const1361 bool TargetTransformInfo::isLegalToVectorizeLoadChain(
1362 unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const {
1363 return TTIImpl->isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment,
1364 AddrSpace);
1365 }
1366
isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,Align Alignment,unsigned AddrSpace) const1367 bool TargetTransformInfo::isLegalToVectorizeStoreChain(
1368 unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const {
1369 return TTIImpl->isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment,
1370 AddrSpace);
1371 }
1372
isLegalToVectorizeReduction(const RecurrenceDescriptor & RdxDesc,ElementCount VF) const1373 bool TargetTransformInfo::isLegalToVectorizeReduction(
1374 const RecurrenceDescriptor &RdxDesc, ElementCount VF) const {
1375 return TTIImpl->isLegalToVectorizeReduction(RdxDesc, VF);
1376 }
1377
isElementTypeLegalForScalableVector(Type * Ty) const1378 bool TargetTransformInfo::isElementTypeLegalForScalableVector(Type *Ty) const {
1379 return TTIImpl->isElementTypeLegalForScalableVector(Ty);
1380 }
1381
getLoadVectorFactor(unsigned VF,unsigned LoadSize,unsigned ChainSizeInBytes,VectorType * VecTy) const1382 unsigned TargetTransformInfo::getLoadVectorFactor(unsigned VF,
1383 unsigned LoadSize,
1384 unsigned ChainSizeInBytes,
1385 VectorType *VecTy) const {
1386 return TTIImpl->getLoadVectorFactor(VF, LoadSize, ChainSizeInBytes, VecTy);
1387 }
1388
getStoreVectorFactor(unsigned VF,unsigned StoreSize,unsigned ChainSizeInBytes,VectorType * VecTy) const1389 unsigned TargetTransformInfo::getStoreVectorFactor(unsigned VF,
1390 unsigned StoreSize,
1391 unsigned ChainSizeInBytes,
1392 VectorType *VecTy) const {
1393 return TTIImpl->getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
1394 }
1395
preferFixedOverScalableIfEqualCost() const1396 bool TargetTransformInfo::preferFixedOverScalableIfEqualCost() const {
1397 return TTIImpl->preferFixedOverScalableIfEqualCost();
1398 }
1399
preferInLoopReduction(RecurKind Kind,Type * Ty) const1400 bool TargetTransformInfo::preferInLoopReduction(RecurKind Kind,
1401 Type *Ty) const {
1402 return TTIImpl->preferInLoopReduction(Kind, Ty);
1403 }
1404
preferAlternateOpcodeVectorization() const1405 bool TargetTransformInfo::preferAlternateOpcodeVectorization() const {
1406 return TTIImpl->preferAlternateOpcodeVectorization();
1407 }
1408
preferPredicatedReductionSelect() const1409 bool TargetTransformInfo::preferPredicatedReductionSelect() const {
1410 return TTIImpl->preferPredicatedReductionSelect();
1411 }
1412
preferEpilogueVectorization() const1413 bool TargetTransformInfo::preferEpilogueVectorization() const {
1414 return TTIImpl->preferEpilogueVectorization();
1415 }
1416
1417 TargetTransformInfo::VPLegalization
getVPLegalizationStrategy(const VPIntrinsic & VPI) const1418 TargetTransformInfo::getVPLegalizationStrategy(const VPIntrinsic &VPI) const {
1419 return TTIImpl->getVPLegalizationStrategy(VPI);
1420 }
1421
hasArmWideBranch(bool Thumb) const1422 bool TargetTransformInfo::hasArmWideBranch(bool Thumb) const {
1423 return TTIImpl->hasArmWideBranch(Thumb);
1424 }
1425
getFeatureMask(const Function & F) const1426 uint64_t TargetTransformInfo::getFeatureMask(const Function &F) const {
1427 return TTIImpl->getFeatureMask(F);
1428 }
1429
isMultiversionedFunction(const Function & F) const1430 bool TargetTransformInfo::isMultiversionedFunction(const Function &F) const {
1431 return TTIImpl->isMultiversionedFunction(F);
1432 }
1433
getMaxNumArgs() const1434 unsigned TargetTransformInfo::getMaxNumArgs() const {
1435 return TTIImpl->getMaxNumArgs();
1436 }
1437
shouldExpandReduction(const IntrinsicInst * II) const1438 bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const {
1439 return TTIImpl->shouldExpandReduction(II);
1440 }
1441
1442 TargetTransformInfo::ReductionShuffle
getPreferredExpandedReductionShuffle(const IntrinsicInst * II) const1443 TargetTransformInfo::getPreferredExpandedReductionShuffle(
1444 const IntrinsicInst *II) const {
1445 return TTIImpl->getPreferredExpandedReductionShuffle(II);
1446 }
1447
getGISelRematGlobalCost() const1448 unsigned TargetTransformInfo::getGISelRematGlobalCost() const {
1449 return TTIImpl->getGISelRematGlobalCost();
1450 }
1451
getMinTripCountTailFoldingThreshold() const1452 unsigned TargetTransformInfo::getMinTripCountTailFoldingThreshold() const {
1453 return TTIImpl->getMinTripCountTailFoldingThreshold();
1454 }
1455
supportsScalableVectors() const1456 bool TargetTransformInfo::supportsScalableVectors() const {
1457 return TTIImpl->supportsScalableVectors();
1458 }
1459
enableScalableVectorization() const1460 bool TargetTransformInfo::enableScalableVectorization() const {
1461 return TTIImpl->enableScalableVectorization();
1462 }
1463
hasActiveVectorLength() const1464 bool TargetTransformInfo::hasActiveVectorLength() const {
1465 return TTIImpl->hasActiveVectorLength();
1466 }
1467
isProfitableToSinkOperands(Instruction * I,SmallVectorImpl<Use * > & OpsToSink) const1468 bool TargetTransformInfo::isProfitableToSinkOperands(
1469 Instruction *I, SmallVectorImpl<Use *> &OpsToSink) const {
1470 return TTIImpl->isProfitableToSinkOperands(I, OpsToSink);
1471 }
1472
isVectorShiftByScalarCheap(Type * Ty) const1473 bool TargetTransformInfo::isVectorShiftByScalarCheap(Type *Ty) const {
1474 return TTIImpl->isVectorShiftByScalarCheap(Ty);
1475 }
1476
1477 unsigned
getNumBytesToPadGlobalArray(unsigned Size,Type * ArrayType) const1478 TargetTransformInfo::getNumBytesToPadGlobalArray(unsigned Size,
1479 Type *ArrayType) const {
1480 return TTIImpl->getNumBytesToPadGlobalArray(Size, ArrayType);
1481 }
1482
collectKernelLaunchBounds(const Function & F,SmallVectorImpl<std::pair<StringRef,int64_t>> & LB) const1483 void TargetTransformInfo::collectKernelLaunchBounds(
1484 const Function &F,
1485 SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const {
1486 return TTIImpl->collectKernelLaunchBounds(F, LB);
1487 }
1488
1489 TargetTransformInfoImplBase::~TargetTransformInfoImplBase() = default;
1490
TargetIRAnalysis()1491 TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
1492
TargetIRAnalysis(std::function<Result (const Function &)> TTICallback)1493 TargetIRAnalysis::TargetIRAnalysis(
1494 std::function<Result(const Function &)> TTICallback)
1495 : TTICallback(std::move(TTICallback)) {}
1496
run(const Function & F,FunctionAnalysisManager &)1497 TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F,
1498 FunctionAnalysisManager &) {
1499 assert(!F.isIntrinsic() && "Should not request TTI for intrinsics");
1500 return TTICallback(F);
1501 }
1502
1503 AnalysisKey TargetIRAnalysis::Key;
1504
getDefaultTTI(const Function & F)1505 TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) {
1506 return Result(F.getDataLayout());
1507 }
1508
1509 // Register the basic pass.
1510 INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti",
1511 "Target Transform Information", false, true)
1512 char TargetTransformInfoWrapperPass::ID = 0;
1513
anchor()1514 void TargetTransformInfoWrapperPass::anchor() {}
1515
TargetTransformInfoWrapperPass()1516 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass()
1517 : ImmutablePass(ID) {}
1518
TargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)1519 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass(
1520 TargetIRAnalysis TIRA)
1521 : ImmutablePass(ID), TIRA(std::move(TIRA)) {}
1522
getTTI(const Function & F)1523 TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) {
1524 FunctionAnalysisManager DummyFAM;
1525 TTI = TIRA.run(F, DummyFAM);
1526 return *TTI;
1527 }
1528
1529 ImmutablePass *
createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)1530 llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) {
1531 return new TargetTransformInfoWrapperPass(std::move(TIRA));
1532 }
1533