xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/TargetTransformInfo.cpp (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
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/TargetTransformInfoImpl.h"
13 #include "llvm/IR/CFG.h"
14 #include "llvm/IR/Dominators.h"
15 #include "llvm/IR/Instruction.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/IntrinsicInst.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/Operator.h"
20 #include "llvm/IR/PatternMatch.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> PredictableBranchThreshold(
41     "predictable-branch-threshold", cl::init(99), cl::Hidden,
42     cl::desc(
43         "Use this to override the target's predictable branch threshold (%)."));
44 
45 namespace {
46 /// No-op implementation of the TTI interface using the utility base
47 /// classes.
48 ///
49 /// This is used when no target specific information is available.
50 struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> {
51   explicit NoTTIImpl(const DataLayout &DL)
52       : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {}
53 };
54 } // namespace
55 
56 bool HardwareLoopInfo::canAnalyze(LoopInfo &LI) {
57   // If the loop has irreducible control flow, it can not be converted to
58   // Hardware loop.
59   LoopBlocksRPO RPOT(L);
60   RPOT.perform(&LI);
61   if (containsIrreducibleCFG<const BasicBlock *>(RPOT, LI))
62     return false;
63   return true;
64 }
65 
66 IntrinsicCostAttributes::IntrinsicCostAttributes(
67     Intrinsic::ID Id, const CallBase &CI, InstructionCost ScalarizationCost,
68     bool TypeBasedOnly)
69     : II(dyn_cast<IntrinsicInst>(&CI)), RetTy(CI.getType()), IID(Id),
70       ScalarizationCost(ScalarizationCost) {
71 
72   if (const auto *FPMO = dyn_cast<FPMathOperator>(&CI))
73     FMF = FPMO->getFastMathFlags();
74 
75   if (!TypeBasedOnly)
76     Arguments.insert(Arguments.begin(), CI.arg_begin(), CI.arg_end());
77   FunctionType *FTy = CI.getCalledFunction()->getFunctionType();
78   ParamTys.insert(ParamTys.begin(), FTy->param_begin(), FTy->param_end());
79 }
80 
81 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
82                                                  ArrayRef<Type *> Tys,
83                                                  FastMathFlags Flags,
84                                                  const IntrinsicInst *I,
85                                                  InstructionCost ScalarCost)
86     : II(I), RetTy(RTy), IID(Id), FMF(Flags), ScalarizationCost(ScalarCost) {
87   ParamTys.insert(ParamTys.begin(), Tys.begin(), Tys.end());
88 }
89 
90 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *Ty,
91                                                  ArrayRef<const Value *> Args)
92     : RetTy(Ty), IID(Id) {
93 
94   Arguments.insert(Arguments.begin(), Args.begin(), Args.end());
95   ParamTys.reserve(Arguments.size());
96   for (unsigned Idx = 0, Size = Arguments.size(); Idx != Size; ++Idx)
97     ParamTys.push_back(Arguments[Idx]->getType());
98 }
99 
100 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
101                                                  ArrayRef<const Value *> Args,
102                                                  ArrayRef<Type *> Tys,
103                                                  FastMathFlags Flags,
104                                                  const IntrinsicInst *I,
105                                                  InstructionCost ScalarCost)
106     : II(I), RetTy(RTy), IID(Id), FMF(Flags), ScalarizationCost(ScalarCost) {
107   ParamTys.insert(ParamTys.begin(), Tys.begin(), Tys.end());
108   Arguments.insert(Arguments.begin(), Args.begin(), Args.end());
109 }
110 
111 HardwareLoopInfo::HardwareLoopInfo(Loop *L) : L(L) {
112   // Match default options:
113   // - hardware-loop-counter-bitwidth = 32
114   // - hardware-loop-decrement = 1
115   CountType = Type::getInt32Ty(L->getHeader()->getContext());
116   LoopDecrement = ConstantInt::get(CountType, 1);
117 }
118 
119 bool HardwareLoopInfo::isHardwareLoopCandidate(ScalarEvolution &SE,
120                                                LoopInfo &LI, DominatorTree &DT,
121                                                bool ForceNestedLoop,
122                                                bool ForceHardwareLoopPHI) {
123   SmallVector<BasicBlock *, 4> ExitingBlocks;
124   L->getExitingBlocks(ExitingBlocks);
125 
126   for (BasicBlock *BB : ExitingBlocks) {
127     // If we pass the updated counter back through a phi, we need to know
128     // which latch the updated value will be coming from.
129     if (!L->isLoopLatch(BB)) {
130       if (ForceHardwareLoopPHI || CounterInReg)
131         continue;
132     }
133 
134     const SCEV *EC = SE.getExitCount(L, BB);
135     if (isa<SCEVCouldNotCompute>(EC))
136       continue;
137     if (const SCEVConstant *ConstEC = dyn_cast<SCEVConstant>(EC)) {
138       if (ConstEC->getValue()->isZero())
139         continue;
140     } else if (!SE.isLoopInvariant(EC, L))
141       continue;
142 
143     if (SE.getTypeSizeInBits(EC->getType()) > CountType->getBitWidth())
144       continue;
145 
146     // If this exiting block is contained in a nested loop, it is not eligible
147     // for insertion of the branch-and-decrement since the inner loop would
148     // end up messing up the value in the CTR.
149     if (!IsNestingLegal && LI.getLoopFor(BB) != L && !ForceNestedLoop)
150       continue;
151 
152     // We now have a loop-invariant count of loop iterations (which is not the
153     // constant zero) for which we know that this loop will not exit via this
154     // existing block.
155 
156     // We need to make sure that this block will run on every loop iteration.
157     // For this to be true, we must dominate all blocks with backedges. Such
158     // blocks are in-loop predecessors to the header block.
159     bool NotAlways = false;
160     for (BasicBlock *Pred : predecessors(L->getHeader())) {
161       if (!L->contains(Pred))
162         continue;
163 
164       if (!DT.dominates(BB, Pred)) {
165         NotAlways = true;
166         break;
167       }
168     }
169 
170     if (NotAlways)
171       continue;
172 
173     // Make sure this blocks ends with a conditional branch.
174     Instruction *TI = BB->getTerminator();
175     if (!TI)
176       continue;
177 
178     if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
179       if (!BI->isConditional())
180         continue;
181 
182       ExitBranch = BI;
183     } else
184       continue;
185 
186     // Note that this block may not be the loop latch block, even if the loop
187     // has a latch block.
188     ExitBlock = BB;
189     ExitCount = EC;
190     break;
191   }
192 
193   if (!ExitBlock)
194     return false;
195   return true;
196 }
197 
198 TargetTransformInfo::TargetTransformInfo(const DataLayout &DL)
199     : TTIImpl(new Model<NoTTIImpl>(NoTTIImpl(DL))) {}
200 
201 TargetTransformInfo::~TargetTransformInfo() = default;
202 
203 TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg)
204     : TTIImpl(std::move(Arg.TTIImpl)) {}
205 
206 TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) {
207   TTIImpl = std::move(RHS.TTIImpl);
208   return *this;
209 }
210 
211 unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
212   return TTIImpl->getInliningThresholdMultiplier();
213 }
214 
215 unsigned
216 TargetTransformInfo::adjustInliningThreshold(const CallBase *CB) const {
217   return TTIImpl->adjustInliningThreshold(CB);
218 }
219 
220 unsigned TargetTransformInfo::getCallerAllocaCost(const CallBase *CB,
221                                                   const AllocaInst *AI) const {
222   return TTIImpl->getCallerAllocaCost(CB, AI);
223 }
224 
225 int TargetTransformInfo::getInlinerVectorBonusPercent() const {
226   return TTIImpl->getInlinerVectorBonusPercent();
227 }
228 
229 InstructionCost TargetTransformInfo::getGEPCost(
230     Type *PointeeType, const Value *Ptr, ArrayRef<const Value *> Operands,
231     Type *AccessType, TTI::TargetCostKind CostKind) const {
232   return TTIImpl->getGEPCost(PointeeType, Ptr, Operands, AccessType, CostKind);
233 }
234 
235 InstructionCost TargetTransformInfo::getPointersChainCost(
236     ArrayRef<const Value *> Ptrs, const Value *Base,
237     const TTI::PointersChainInfo &Info, Type *AccessTy,
238     TTI::TargetCostKind CostKind) const {
239   assert((Base || !Info.isSameBase()) &&
240          "If pointers have same base address it has to be provided.");
241   return TTIImpl->getPointersChainCost(Ptrs, Base, Info, AccessTy, CostKind);
242 }
243 
244 unsigned TargetTransformInfo::getEstimatedNumberOfCaseClusters(
245     const SwitchInst &SI, unsigned &JTSize, ProfileSummaryInfo *PSI,
246     BlockFrequencyInfo *BFI) const {
247   return TTIImpl->getEstimatedNumberOfCaseClusters(SI, JTSize, PSI, BFI);
248 }
249 
250 InstructionCost
251 TargetTransformInfo::getInstructionCost(const User *U,
252                                         ArrayRef<const Value *> Operands,
253                                         enum TargetCostKind CostKind) const {
254   InstructionCost Cost = TTIImpl->getInstructionCost(U, Operands, CostKind);
255   assert((CostKind == TTI::TCK_RecipThroughput || Cost >= 0) &&
256          "TTI should not produce negative costs!");
257   return Cost;
258 }
259 
260 BranchProbability TargetTransformInfo::getPredictableBranchThreshold() const {
261   return PredictableBranchThreshold.getNumOccurrences() > 0
262              ? BranchProbability(PredictableBranchThreshold, 100)
263              : TTIImpl->getPredictableBranchThreshold();
264 }
265 
266 bool TargetTransformInfo::hasBranchDivergence(const Function *F) const {
267   return TTIImpl->hasBranchDivergence(F);
268 }
269 
270 bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
271   return TTIImpl->isSourceOfDivergence(V);
272 }
273 
274 bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const {
275   return TTIImpl->isAlwaysUniform(V);
276 }
277 
278 bool llvm::TargetTransformInfo::isValidAddrSpaceCast(unsigned FromAS,
279                                                      unsigned ToAS) const {
280   return TTIImpl->isValidAddrSpaceCast(FromAS, ToAS);
281 }
282 
283 bool llvm::TargetTransformInfo::addrspacesMayAlias(unsigned FromAS,
284                                                    unsigned ToAS) const {
285   return TTIImpl->addrspacesMayAlias(FromAS, ToAS);
286 }
287 
288 unsigned TargetTransformInfo::getFlatAddressSpace() const {
289   return TTIImpl->getFlatAddressSpace();
290 }
291 
292 bool TargetTransformInfo::collectFlatAddressOperands(
293     SmallVectorImpl<int> &OpIndexes, Intrinsic::ID IID) const {
294   return TTIImpl->collectFlatAddressOperands(OpIndexes, IID);
295 }
296 
297 bool TargetTransformInfo::isNoopAddrSpaceCast(unsigned FromAS,
298                                               unsigned ToAS) const {
299   return TTIImpl->isNoopAddrSpaceCast(FromAS, ToAS);
300 }
301 
302 bool TargetTransformInfo::canHaveNonUndefGlobalInitializerInAddressSpace(
303     unsigned AS) const {
304   return TTIImpl->canHaveNonUndefGlobalInitializerInAddressSpace(AS);
305 }
306 
307 unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const {
308   return TTIImpl->getAssumedAddrSpace(V);
309 }
310 
311 bool TargetTransformInfo::isSingleThreaded() const {
312   return TTIImpl->isSingleThreaded();
313 }
314 
315 std::pair<const Value *, unsigned>
316 TargetTransformInfo::getPredicatedAddrSpace(const Value *V) const {
317   return TTIImpl->getPredicatedAddrSpace(V);
318 }
319 
320 Value *TargetTransformInfo::rewriteIntrinsicWithAddressSpace(
321     IntrinsicInst *II, Value *OldV, Value *NewV) const {
322   return TTIImpl->rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
323 }
324 
325 bool TargetTransformInfo::isLoweredToCall(const Function *F) const {
326   return TTIImpl->isLoweredToCall(F);
327 }
328 
329 bool TargetTransformInfo::isHardwareLoopProfitable(
330     Loop *L, ScalarEvolution &SE, AssumptionCache &AC,
331     TargetLibraryInfo *LibInfo, HardwareLoopInfo &HWLoopInfo) const {
332   return TTIImpl->isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
333 }
334 
335 bool TargetTransformInfo::preferPredicateOverEpilogue(
336     TailFoldingInfo *TFI) const {
337   return TTIImpl->preferPredicateOverEpilogue(TFI);
338 }
339 
340 TailFoldingStyle TargetTransformInfo::getPreferredTailFoldingStyle(
341     bool IVUpdateMayOverflow) const {
342   return TTIImpl->getPreferredTailFoldingStyle(IVUpdateMayOverflow);
343 }
344 
345 std::optional<Instruction *>
346 TargetTransformInfo::instCombineIntrinsic(InstCombiner &IC,
347                                           IntrinsicInst &II) const {
348   return TTIImpl->instCombineIntrinsic(IC, II);
349 }
350 
351 std::optional<Value *> TargetTransformInfo::simplifyDemandedUseBitsIntrinsic(
352     InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
353     bool &KnownBitsComputed) const {
354   return TTIImpl->simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
355                                                    KnownBitsComputed);
356 }
357 
358 std::optional<Value *> TargetTransformInfo::simplifyDemandedVectorEltsIntrinsic(
359     InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
360     APInt &UndefElts2, APInt &UndefElts3,
361     std::function<void(Instruction *, unsigned, APInt, APInt &)>
362         SimplifyAndSetOp) const {
363   return TTIImpl->simplifyDemandedVectorEltsIntrinsic(
364       IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
365       SimplifyAndSetOp);
366 }
367 
368 void TargetTransformInfo::getUnrollingPreferences(
369     Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP,
370     OptimizationRemarkEmitter *ORE) const {
371   return TTIImpl->getUnrollingPreferences(L, SE, UP, ORE);
372 }
373 
374 void TargetTransformInfo::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
375                                                 PeelingPreferences &PP) const {
376   return TTIImpl->getPeelingPreferences(L, SE, PP);
377 }
378 
379 bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
380   return TTIImpl->isLegalAddImmediate(Imm);
381 }
382 
383 bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
384   return TTIImpl->isLegalICmpImmediate(Imm);
385 }
386 
387 bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
388                                                 int64_t BaseOffset,
389                                                 bool HasBaseReg, int64_t Scale,
390                                                 unsigned AddrSpace,
391                                                 Instruction *I) const {
392   return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
393                                         Scale, AddrSpace, I);
394 }
395 
396 bool TargetTransformInfo::isLSRCostLess(const LSRCost &C1,
397                                         const LSRCost &C2) const {
398   return TTIImpl->isLSRCostLess(C1, C2);
399 }
400 
401 bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
402   return TTIImpl->isNumRegsMajorCostOfLSR();
403 }
404 
405 bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const {
406   return TTIImpl->isProfitableLSRChainElement(I);
407 }
408 
409 bool TargetTransformInfo::canMacroFuseCmp() const {
410   return TTIImpl->canMacroFuseCmp();
411 }
412 
413 bool TargetTransformInfo::canSaveCmp(Loop *L, BranchInst **BI,
414                                      ScalarEvolution *SE, LoopInfo *LI,
415                                      DominatorTree *DT, AssumptionCache *AC,
416                                      TargetLibraryInfo *LibInfo) const {
417   return TTIImpl->canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
418 }
419 
420 TTI::AddressingModeKind
421 TargetTransformInfo::getPreferredAddressingMode(const Loop *L,
422                                                 ScalarEvolution *SE) const {
423   return TTIImpl->getPreferredAddressingMode(L, SE);
424 }
425 
426 bool TargetTransformInfo::isLegalMaskedStore(Type *DataType,
427                                              Align Alignment) const {
428   return TTIImpl->isLegalMaskedStore(DataType, Alignment);
429 }
430 
431 bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType,
432                                             Align Alignment) const {
433   return TTIImpl->isLegalMaskedLoad(DataType, Alignment);
434 }
435 
436 bool TargetTransformInfo::isLegalNTStore(Type *DataType,
437                                          Align Alignment) const {
438   return TTIImpl->isLegalNTStore(DataType, Alignment);
439 }
440 
441 bool TargetTransformInfo::isLegalNTLoad(Type *DataType, Align Alignment) const {
442   return TTIImpl->isLegalNTLoad(DataType, Alignment);
443 }
444 
445 bool TargetTransformInfo::isLegalBroadcastLoad(Type *ElementTy,
446                                                ElementCount NumElements) const {
447   return TTIImpl->isLegalBroadcastLoad(ElementTy, NumElements);
448 }
449 
450 bool TargetTransformInfo::isLegalMaskedGather(Type *DataType,
451                                               Align Alignment) const {
452   return TTIImpl->isLegalMaskedGather(DataType, Alignment);
453 }
454 
455 bool TargetTransformInfo::isLegalAltInstr(
456     VectorType *VecTy, unsigned Opcode0, unsigned Opcode1,
457     const SmallBitVector &OpcodeMask) const {
458   return TTIImpl->isLegalAltInstr(VecTy, Opcode0, Opcode1, OpcodeMask);
459 }
460 
461 bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType,
462                                                Align Alignment) const {
463   return TTIImpl->isLegalMaskedScatter(DataType, Alignment);
464 }
465 
466 bool TargetTransformInfo::forceScalarizeMaskedGather(VectorType *DataType,
467                                                      Align Alignment) const {
468   return TTIImpl->forceScalarizeMaskedGather(DataType, Alignment);
469 }
470 
471 bool TargetTransformInfo::forceScalarizeMaskedScatter(VectorType *DataType,
472                                                       Align Alignment) const {
473   return TTIImpl->forceScalarizeMaskedScatter(DataType, Alignment);
474 }
475 
476 bool TargetTransformInfo::isLegalMaskedCompressStore(Type *DataType) const {
477   return TTIImpl->isLegalMaskedCompressStore(DataType);
478 }
479 
480 bool TargetTransformInfo::isLegalMaskedExpandLoad(Type *DataType) const {
481   return TTIImpl->isLegalMaskedExpandLoad(DataType);
482 }
483 
484 bool TargetTransformInfo::enableOrderedReductions() const {
485   return TTIImpl->enableOrderedReductions();
486 }
487 
488 bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const {
489   return TTIImpl->hasDivRemOp(DataType, IsSigned);
490 }
491 
492 bool TargetTransformInfo::hasVolatileVariant(Instruction *I,
493                                              unsigned AddrSpace) const {
494   return TTIImpl->hasVolatileVariant(I, AddrSpace);
495 }
496 
497 bool TargetTransformInfo::prefersVectorizedAddressing() const {
498   return TTIImpl->prefersVectorizedAddressing();
499 }
500 
501 InstructionCost TargetTransformInfo::getScalingFactorCost(
502     Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg,
503     int64_t Scale, unsigned AddrSpace) const {
504   InstructionCost Cost = TTIImpl->getScalingFactorCost(
505       Ty, BaseGV, BaseOffset, HasBaseReg, Scale, AddrSpace);
506   assert(Cost >= 0 && "TTI should not produce negative costs!");
507   return Cost;
508 }
509 
510 bool TargetTransformInfo::LSRWithInstrQueries() const {
511   return TTIImpl->LSRWithInstrQueries();
512 }
513 
514 bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const {
515   return TTIImpl->isTruncateFree(Ty1, Ty2);
516 }
517 
518 bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const {
519   return TTIImpl->isProfitableToHoist(I);
520 }
521 
522 bool TargetTransformInfo::useAA() const { return TTIImpl->useAA(); }
523 
524 bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
525   return TTIImpl->isTypeLegal(Ty);
526 }
527 
528 unsigned TargetTransformInfo::getRegUsageForType(Type *Ty) const {
529   return TTIImpl->getRegUsageForType(Ty);
530 }
531 
532 bool TargetTransformInfo::shouldBuildLookupTables() const {
533   return TTIImpl->shouldBuildLookupTables();
534 }
535 
536 bool TargetTransformInfo::shouldBuildLookupTablesForConstant(
537     Constant *C) const {
538   return TTIImpl->shouldBuildLookupTablesForConstant(C);
539 }
540 
541 bool TargetTransformInfo::shouldBuildRelLookupTables() const {
542   return TTIImpl->shouldBuildRelLookupTables();
543 }
544 
545 bool TargetTransformInfo::useColdCCForColdCall(Function &F) const {
546   return TTIImpl->useColdCCForColdCall(F);
547 }
548 
549 InstructionCost TargetTransformInfo::getScalarizationOverhead(
550     VectorType *Ty, const APInt &DemandedElts, bool Insert, bool Extract,
551     TTI::TargetCostKind CostKind) const {
552   return TTIImpl->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract,
553                                            CostKind);
554 }
555 
556 InstructionCost TargetTransformInfo::getOperandsScalarizationOverhead(
557     ArrayRef<const Value *> Args, ArrayRef<Type *> Tys,
558     TTI::TargetCostKind CostKind) const {
559   return TTIImpl->getOperandsScalarizationOverhead(Args, Tys, CostKind);
560 }
561 
562 bool TargetTransformInfo::supportsEfficientVectorElementLoadStore() const {
563   return TTIImpl->supportsEfficientVectorElementLoadStore();
564 }
565 
566 bool TargetTransformInfo::supportsTailCalls() const {
567   return TTIImpl->supportsTailCalls();
568 }
569 
570 bool TargetTransformInfo::supportsTailCallFor(const CallBase *CB) const {
571   return TTIImpl->supportsTailCallFor(CB);
572 }
573 
574 bool TargetTransformInfo::enableAggressiveInterleaving(
575     bool LoopHasReductions) const {
576   return TTIImpl->enableAggressiveInterleaving(LoopHasReductions);
577 }
578 
579 TargetTransformInfo::MemCmpExpansionOptions
580 TargetTransformInfo::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
581   return TTIImpl->enableMemCmpExpansion(OptSize, IsZeroCmp);
582 }
583 
584 bool TargetTransformInfo::enableSelectOptimize() const {
585   return TTIImpl->enableSelectOptimize();
586 }
587 
588 bool TargetTransformInfo::enableInterleavedAccessVectorization() const {
589   return TTIImpl->enableInterleavedAccessVectorization();
590 }
591 
592 bool TargetTransformInfo::enableMaskedInterleavedAccessVectorization() const {
593   return TTIImpl->enableMaskedInterleavedAccessVectorization();
594 }
595 
596 bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const {
597   return TTIImpl->isFPVectorizationPotentiallyUnsafe();
598 }
599 
600 bool
601 TargetTransformInfo::allowsMisalignedMemoryAccesses(LLVMContext &Context,
602                                                     unsigned BitWidth,
603                                                     unsigned AddressSpace,
604                                                     Align Alignment,
605                                                     unsigned *Fast) const {
606   return TTIImpl->allowsMisalignedMemoryAccesses(Context, BitWidth,
607                                                  AddressSpace, Alignment, Fast);
608 }
609 
610 TargetTransformInfo::PopcntSupportKind
611 TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const {
612   return TTIImpl->getPopcntSupport(IntTyWidthInBit);
613 }
614 
615 bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
616   return TTIImpl->haveFastSqrt(Ty);
617 }
618 
619 bool TargetTransformInfo::isExpensiveToSpeculativelyExecute(
620     const Instruction *I) const {
621   return TTIImpl->isExpensiveToSpeculativelyExecute(I);
622 }
623 
624 bool TargetTransformInfo::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const {
625   return TTIImpl->isFCmpOrdCheaperThanFCmpZero(Ty);
626 }
627 
628 InstructionCost TargetTransformInfo::getFPOpCost(Type *Ty) const {
629   InstructionCost Cost = TTIImpl->getFPOpCost(Ty);
630   assert(Cost >= 0 && "TTI should not produce negative costs!");
631   return Cost;
632 }
633 
634 InstructionCost TargetTransformInfo::getIntImmCodeSizeCost(unsigned Opcode,
635                                                            unsigned Idx,
636                                                            const APInt &Imm,
637                                                            Type *Ty) const {
638   InstructionCost Cost = TTIImpl->getIntImmCodeSizeCost(Opcode, Idx, Imm, Ty);
639   assert(Cost >= 0 && "TTI should not produce negative costs!");
640   return Cost;
641 }
642 
643 InstructionCost
644 TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty,
645                                    TTI::TargetCostKind CostKind) const {
646   InstructionCost Cost = TTIImpl->getIntImmCost(Imm, Ty, CostKind);
647   assert(Cost >= 0 && "TTI should not produce negative costs!");
648   return Cost;
649 }
650 
651 InstructionCost TargetTransformInfo::getIntImmCostInst(
652     unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty,
653     TTI::TargetCostKind CostKind, Instruction *Inst) const {
654   InstructionCost Cost =
655       TTIImpl->getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
656   assert(Cost >= 0 && "TTI should not produce negative costs!");
657   return Cost;
658 }
659 
660 InstructionCost
661 TargetTransformInfo::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
662                                          const APInt &Imm, Type *Ty,
663                                          TTI::TargetCostKind CostKind) const {
664   InstructionCost Cost =
665       TTIImpl->getIntImmCostIntrin(IID, Idx, Imm, Ty, CostKind);
666   assert(Cost >= 0 && "TTI should not produce negative costs!");
667   return Cost;
668 }
669 
670 unsigned TargetTransformInfo::getNumberOfRegisters(unsigned ClassID) const {
671   return TTIImpl->getNumberOfRegisters(ClassID);
672 }
673 
674 unsigned TargetTransformInfo::getRegisterClassForType(bool Vector,
675                                                       Type *Ty) const {
676   return TTIImpl->getRegisterClassForType(Vector, Ty);
677 }
678 
679 const char *TargetTransformInfo::getRegisterClassName(unsigned ClassID) const {
680   return TTIImpl->getRegisterClassName(ClassID);
681 }
682 
683 TypeSize TargetTransformInfo::getRegisterBitWidth(
684     TargetTransformInfo::RegisterKind K) const {
685   return TTIImpl->getRegisterBitWidth(K);
686 }
687 
688 unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const {
689   return TTIImpl->getMinVectorRegisterBitWidth();
690 }
691 
692 std::optional<unsigned> TargetTransformInfo::getMaxVScale() const {
693   return TTIImpl->getMaxVScale();
694 }
695 
696 std::optional<unsigned> TargetTransformInfo::getVScaleForTuning() const {
697   return TTIImpl->getVScaleForTuning();
698 }
699 
700 bool TargetTransformInfo::isVScaleKnownToBeAPowerOfTwo() const {
701   return TTIImpl->isVScaleKnownToBeAPowerOfTwo();
702 }
703 
704 bool TargetTransformInfo::shouldMaximizeVectorBandwidth(
705     TargetTransformInfo::RegisterKind K) const {
706   return TTIImpl->shouldMaximizeVectorBandwidth(K);
707 }
708 
709 ElementCount TargetTransformInfo::getMinimumVF(unsigned ElemWidth,
710                                                bool IsScalable) const {
711   return TTIImpl->getMinimumVF(ElemWidth, IsScalable);
712 }
713 
714 unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth,
715                                            unsigned Opcode) const {
716   return TTIImpl->getMaximumVF(ElemWidth, Opcode);
717 }
718 
719 unsigned TargetTransformInfo::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
720                                                 Type *ScalarValTy) const {
721   return TTIImpl->getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy);
722 }
723 
724 bool TargetTransformInfo::shouldConsiderAddressTypePromotion(
725     const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
726   return TTIImpl->shouldConsiderAddressTypePromotion(
727       I, AllowPromotionWithoutCommonHeader);
728 }
729 
730 unsigned TargetTransformInfo::getCacheLineSize() const {
731   return CacheLineSize.getNumOccurrences() > 0 ? CacheLineSize
732                                                : TTIImpl->getCacheLineSize();
733 }
734 
735 std::optional<unsigned>
736 TargetTransformInfo::getCacheSize(CacheLevel Level) const {
737   return TTIImpl->getCacheSize(Level);
738 }
739 
740 std::optional<unsigned>
741 TargetTransformInfo::getCacheAssociativity(CacheLevel Level) const {
742   return TTIImpl->getCacheAssociativity(Level);
743 }
744 
745 unsigned TargetTransformInfo::getPrefetchDistance() const {
746   return TTIImpl->getPrefetchDistance();
747 }
748 
749 unsigned TargetTransformInfo::getMinPrefetchStride(
750     unsigned NumMemAccesses, unsigned NumStridedMemAccesses,
751     unsigned NumPrefetches, bool HasCall) const {
752   return TTIImpl->getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
753                                        NumPrefetches, HasCall);
754 }
755 
756 unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const {
757   return TTIImpl->getMaxPrefetchIterationsAhead();
758 }
759 
760 bool TargetTransformInfo::enableWritePrefetching() const {
761   return TTIImpl->enableWritePrefetching();
762 }
763 
764 bool TargetTransformInfo::shouldPrefetchAddressSpace(unsigned AS) const {
765   return TTIImpl->shouldPrefetchAddressSpace(AS);
766 }
767 
768 unsigned TargetTransformInfo::getMaxInterleaveFactor(ElementCount VF) const {
769   return TTIImpl->getMaxInterleaveFactor(VF);
770 }
771 
772 TargetTransformInfo::OperandValueInfo
773 TargetTransformInfo::getOperandInfo(const Value *V) {
774   OperandValueKind OpInfo = OK_AnyValue;
775   OperandValueProperties OpProps = OP_None;
776 
777   if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) {
778     if (const auto *CI = dyn_cast<ConstantInt>(V)) {
779       if (CI->getValue().isPowerOf2())
780         OpProps = OP_PowerOf2;
781       else if (CI->getValue().isNegatedPowerOf2())
782         OpProps = OP_NegatedPowerOf2;
783     }
784     return {OK_UniformConstantValue, OpProps};
785   }
786 
787   // A broadcast shuffle creates a uniform value.
788   // TODO: Add support for non-zero index broadcasts.
789   // TODO: Add support for different source vector width.
790   if (const auto *ShuffleInst = dyn_cast<ShuffleVectorInst>(V))
791     if (ShuffleInst->isZeroEltSplat())
792       OpInfo = OK_UniformValue;
793 
794   const Value *Splat = getSplatValue(V);
795 
796   // Check for a splat of a constant or for a non uniform vector of constants
797   // and check if the constant(s) are all powers of two.
798   if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
799     OpInfo = OK_NonUniformConstantValue;
800     if (Splat) {
801       OpInfo = OK_UniformConstantValue;
802       if (auto *CI = dyn_cast<ConstantInt>(Splat)) {
803         if (CI->getValue().isPowerOf2())
804           OpProps = OP_PowerOf2;
805         else if (CI->getValue().isNegatedPowerOf2())
806           OpProps = OP_NegatedPowerOf2;
807       }
808     } else if (const auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
809       bool AllPow2 = true, AllNegPow2 = true;
810       for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
811         if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I))) {
812           AllPow2 &= CI->getValue().isPowerOf2();
813           AllNegPow2 &= CI->getValue().isNegatedPowerOf2();
814           if (AllPow2 || AllNegPow2)
815             continue;
816         }
817         AllPow2 = AllNegPow2 = false;
818         break;
819       }
820       OpProps = AllPow2 ? OP_PowerOf2 : OpProps;
821       OpProps = AllNegPow2 ? OP_NegatedPowerOf2 : OpProps;
822     }
823   }
824 
825   // Check for a splat of a uniform value. This is not loop aware, so return
826   // true only for the obviously uniform cases (argument, globalvalue)
827   if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
828     OpInfo = OK_UniformValue;
829 
830   return {OpInfo, OpProps};
831 }
832 
833 InstructionCost TargetTransformInfo::getArithmeticInstrCost(
834     unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
835     OperandValueInfo Op1Info, OperandValueInfo Op2Info,
836     ArrayRef<const Value *> Args, const Instruction *CxtI) const {
837   InstructionCost Cost =
838       TTIImpl->getArithmeticInstrCost(Opcode, Ty, CostKind,
839                                       Op1Info, Op2Info,
840                                       Args, CxtI);
841   assert(Cost >= 0 && "TTI should not produce negative costs!");
842   return Cost;
843 }
844 
845 InstructionCost TargetTransformInfo::getShuffleCost(
846     ShuffleKind Kind, VectorType *Ty, ArrayRef<int> Mask,
847     TTI::TargetCostKind CostKind, int Index, VectorType *SubTp,
848     ArrayRef<const Value *> Args) const {
849   InstructionCost Cost =
850       TTIImpl->getShuffleCost(Kind, Ty, Mask, CostKind, Index, SubTp, Args);
851   assert(Cost >= 0 && "TTI should not produce negative costs!");
852   return Cost;
853 }
854 
855 TTI::CastContextHint
856 TargetTransformInfo::getCastContextHint(const Instruction *I) {
857   if (!I)
858     return CastContextHint::None;
859 
860   auto getLoadStoreKind = [](const Value *V, unsigned LdStOp, unsigned MaskedOp,
861                              unsigned GatScatOp) {
862     const Instruction *I = dyn_cast<Instruction>(V);
863     if (!I)
864       return CastContextHint::None;
865 
866     if (I->getOpcode() == LdStOp)
867       return CastContextHint::Normal;
868 
869     if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
870       if (II->getIntrinsicID() == MaskedOp)
871         return TTI::CastContextHint::Masked;
872       if (II->getIntrinsicID() == GatScatOp)
873         return TTI::CastContextHint::GatherScatter;
874     }
875 
876     return TTI::CastContextHint::None;
877   };
878 
879   switch (I->getOpcode()) {
880   case Instruction::ZExt:
881   case Instruction::SExt:
882   case Instruction::FPExt:
883     return getLoadStoreKind(I->getOperand(0), Instruction::Load,
884                             Intrinsic::masked_load, Intrinsic::masked_gather);
885   case Instruction::Trunc:
886   case Instruction::FPTrunc:
887     if (I->hasOneUse())
888       return getLoadStoreKind(*I->user_begin(), Instruction::Store,
889                               Intrinsic::masked_store,
890                               Intrinsic::masked_scatter);
891     break;
892   default:
893     return CastContextHint::None;
894   }
895 
896   return TTI::CastContextHint::None;
897 }
898 
899 InstructionCost TargetTransformInfo::getCastInstrCost(
900     unsigned Opcode, Type *Dst, Type *Src, CastContextHint CCH,
901     TTI::TargetCostKind CostKind, const Instruction *I) const {
902   assert((I == nullptr || I->getOpcode() == Opcode) &&
903          "Opcode should reflect passed instruction.");
904   InstructionCost Cost =
905       TTIImpl->getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
906   assert(Cost >= 0 && "TTI should not produce negative costs!");
907   return Cost;
908 }
909 
910 InstructionCost TargetTransformInfo::getExtractWithExtendCost(
911     unsigned Opcode, Type *Dst, VectorType *VecTy, unsigned Index) const {
912   InstructionCost Cost =
913       TTIImpl->getExtractWithExtendCost(Opcode, Dst, VecTy, Index);
914   assert(Cost >= 0 && "TTI should not produce negative costs!");
915   return Cost;
916 }
917 
918 InstructionCost TargetTransformInfo::getCFInstrCost(
919     unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I) const {
920   assert((I == nullptr || I->getOpcode() == Opcode) &&
921          "Opcode should reflect passed instruction.");
922   InstructionCost Cost = TTIImpl->getCFInstrCost(Opcode, CostKind, I);
923   assert(Cost >= 0 && "TTI should not produce negative costs!");
924   return Cost;
925 }
926 
927 InstructionCost TargetTransformInfo::getCmpSelInstrCost(
928     unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
929     TTI::TargetCostKind CostKind, const Instruction *I) const {
930   assert((I == nullptr || I->getOpcode() == Opcode) &&
931          "Opcode should reflect passed instruction.");
932   InstructionCost Cost =
933       TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
934   assert(Cost >= 0 && "TTI should not produce negative costs!");
935   return Cost;
936 }
937 
938 InstructionCost TargetTransformInfo::getVectorInstrCost(
939     unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index,
940     Value *Op0, Value *Op1) const {
941   // FIXME: Assert that Opcode is either InsertElement or ExtractElement.
942   // This is mentioned in the interface description and respected by all
943   // callers, but never asserted upon.
944   InstructionCost Cost =
945       TTIImpl->getVectorInstrCost(Opcode, Val, CostKind, Index, Op0, Op1);
946   assert(Cost >= 0 && "TTI should not produce negative costs!");
947   return Cost;
948 }
949 
950 InstructionCost
951 TargetTransformInfo::getVectorInstrCost(const Instruction &I, Type *Val,
952                                         TTI::TargetCostKind CostKind,
953                                         unsigned Index) const {
954   // FIXME: Assert that Opcode is either InsertElement or ExtractElement.
955   // This is mentioned in the interface description and respected by all
956   // callers, but never asserted upon.
957   InstructionCost Cost = TTIImpl->getVectorInstrCost(I, Val, CostKind, Index);
958   assert(Cost >= 0 && "TTI should not produce negative costs!");
959   return Cost;
960 }
961 
962 InstructionCost TargetTransformInfo::getReplicationShuffleCost(
963     Type *EltTy, int ReplicationFactor, int VF, const APInt &DemandedDstElts,
964     TTI::TargetCostKind CostKind) {
965   InstructionCost Cost = TTIImpl->getReplicationShuffleCost(
966       EltTy, ReplicationFactor, VF, DemandedDstElts, CostKind);
967   assert(Cost >= 0 && "TTI should not produce negative costs!");
968   return Cost;
969 }
970 
971 InstructionCost TargetTransformInfo::getMemoryOpCost(
972     unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
973     TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo,
974     const Instruction *I) const {
975   assert((I == nullptr || I->getOpcode() == Opcode) &&
976          "Opcode should reflect passed instruction.");
977   InstructionCost Cost = TTIImpl->getMemoryOpCost(
978       Opcode, Src, Alignment, AddressSpace, CostKind, OpInfo, I);
979   assert(Cost >= 0 && "TTI should not produce negative costs!");
980   return Cost;
981 }
982 
983 InstructionCost TargetTransformInfo::getMaskedMemoryOpCost(
984     unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
985     TTI::TargetCostKind CostKind) const {
986   InstructionCost Cost = TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment,
987                                                         AddressSpace, CostKind);
988   assert(Cost >= 0 && "TTI should not produce negative costs!");
989   return Cost;
990 }
991 
992 InstructionCost TargetTransformInfo::getGatherScatterOpCost(
993     unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
994     Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I) const {
995   InstructionCost Cost = TTIImpl->getGatherScatterOpCost(
996       Opcode, DataTy, Ptr, VariableMask, Alignment, CostKind, I);
997   assert(Cost >= 0 && "TTI should not produce negative costs!");
998   return Cost;
999 }
1000 
1001 InstructionCost TargetTransformInfo::getInterleavedMemoryOpCost(
1002     unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
1003     Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
1004     bool UseMaskForCond, bool UseMaskForGaps) const {
1005   InstructionCost Cost = TTIImpl->getInterleavedMemoryOpCost(
1006       Opcode, VecTy, Factor, Indices, Alignment, AddressSpace, CostKind,
1007       UseMaskForCond, UseMaskForGaps);
1008   assert(Cost >= 0 && "TTI should not produce negative costs!");
1009   return Cost;
1010 }
1011 
1012 InstructionCost
1013 TargetTransformInfo::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
1014                                            TTI::TargetCostKind CostKind) const {
1015   InstructionCost Cost = TTIImpl->getIntrinsicInstrCost(ICA, CostKind);
1016   assert(Cost >= 0 && "TTI should not produce negative costs!");
1017   return Cost;
1018 }
1019 
1020 InstructionCost
1021 TargetTransformInfo::getCallInstrCost(Function *F, Type *RetTy,
1022                                       ArrayRef<Type *> Tys,
1023                                       TTI::TargetCostKind CostKind) const {
1024   InstructionCost Cost = TTIImpl->getCallInstrCost(F, RetTy, Tys, CostKind);
1025   assert(Cost >= 0 && "TTI should not produce negative costs!");
1026   return Cost;
1027 }
1028 
1029 unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const {
1030   return TTIImpl->getNumberOfParts(Tp);
1031 }
1032 
1033 InstructionCost
1034 TargetTransformInfo::getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
1035                                                const SCEV *Ptr) const {
1036   InstructionCost Cost = TTIImpl->getAddressComputationCost(Tp, SE, Ptr);
1037   assert(Cost >= 0 && "TTI should not produce negative costs!");
1038   return Cost;
1039 }
1040 
1041 InstructionCost TargetTransformInfo::getMemcpyCost(const Instruction *I) const {
1042   InstructionCost Cost = TTIImpl->getMemcpyCost(I);
1043   assert(Cost >= 0 && "TTI should not produce negative costs!");
1044   return Cost;
1045 }
1046 
1047 uint64_t TargetTransformInfo::getMaxMemIntrinsicInlineSizeThreshold() const {
1048   return TTIImpl->getMaxMemIntrinsicInlineSizeThreshold();
1049 }
1050 
1051 InstructionCost TargetTransformInfo::getArithmeticReductionCost(
1052     unsigned Opcode, VectorType *Ty, std::optional<FastMathFlags> FMF,
1053     TTI::TargetCostKind CostKind) const {
1054   InstructionCost Cost =
1055       TTIImpl->getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
1056   assert(Cost >= 0 && "TTI should not produce negative costs!");
1057   return Cost;
1058 }
1059 
1060 InstructionCost TargetTransformInfo::getMinMaxReductionCost(
1061     Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,
1062     TTI::TargetCostKind CostKind) const {
1063   InstructionCost Cost =
1064       TTIImpl->getMinMaxReductionCost(IID, Ty, FMF, CostKind);
1065   assert(Cost >= 0 && "TTI should not produce negative costs!");
1066   return Cost;
1067 }
1068 
1069 InstructionCost TargetTransformInfo::getExtendedReductionCost(
1070     unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *Ty,
1071     FastMathFlags FMF, TTI::TargetCostKind CostKind) const {
1072   return TTIImpl->getExtendedReductionCost(Opcode, IsUnsigned, ResTy, Ty, FMF,
1073                                            CostKind);
1074 }
1075 
1076 InstructionCost TargetTransformInfo::getMulAccReductionCost(
1077     bool IsUnsigned, Type *ResTy, VectorType *Ty,
1078     TTI::TargetCostKind CostKind) const {
1079   return TTIImpl->getMulAccReductionCost(IsUnsigned, ResTy, Ty, CostKind);
1080 }
1081 
1082 InstructionCost
1083 TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
1084   return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
1085 }
1086 
1087 bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
1088                                              MemIntrinsicInfo &Info) const {
1089   return TTIImpl->getTgtMemIntrinsic(Inst, Info);
1090 }
1091 
1092 unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const {
1093   return TTIImpl->getAtomicMemIntrinsicMaxElementSize();
1094 }
1095 
1096 Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic(
1097     IntrinsicInst *Inst, Type *ExpectedType) const {
1098   return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
1099 }
1100 
1101 Type *TargetTransformInfo::getMemcpyLoopLoweringType(
1102     LLVMContext &Context, Value *Length, unsigned SrcAddrSpace,
1103     unsigned DestAddrSpace, unsigned SrcAlign, unsigned DestAlign,
1104     std::optional<uint32_t> AtomicElementSize) const {
1105   return TTIImpl->getMemcpyLoopLoweringType(Context, Length, SrcAddrSpace,
1106                                             DestAddrSpace, SrcAlign, DestAlign,
1107                                             AtomicElementSize);
1108 }
1109 
1110 void TargetTransformInfo::getMemcpyLoopResidualLoweringType(
1111     SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
1112     unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
1113     unsigned SrcAlign, unsigned DestAlign,
1114     std::optional<uint32_t> AtomicCpySize) const {
1115   TTIImpl->getMemcpyLoopResidualLoweringType(
1116       OpsOut, Context, RemainingBytes, SrcAddrSpace, DestAddrSpace, SrcAlign,
1117       DestAlign, AtomicCpySize);
1118 }
1119 
1120 bool TargetTransformInfo::areInlineCompatible(const Function *Caller,
1121                                               const Function *Callee) const {
1122   return TTIImpl->areInlineCompatible(Caller, Callee);
1123 }
1124 
1125 bool TargetTransformInfo::areTypesABICompatible(
1126     const Function *Caller, const Function *Callee,
1127     const ArrayRef<Type *> &Types) const {
1128   return TTIImpl->areTypesABICompatible(Caller, Callee, Types);
1129 }
1130 
1131 bool TargetTransformInfo::isIndexedLoadLegal(MemIndexedMode Mode,
1132                                              Type *Ty) const {
1133   return TTIImpl->isIndexedLoadLegal(Mode, Ty);
1134 }
1135 
1136 bool TargetTransformInfo::isIndexedStoreLegal(MemIndexedMode Mode,
1137                                               Type *Ty) const {
1138   return TTIImpl->isIndexedStoreLegal(Mode, Ty);
1139 }
1140 
1141 unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const {
1142   return TTIImpl->getLoadStoreVecRegBitWidth(AS);
1143 }
1144 
1145 bool TargetTransformInfo::isLegalToVectorizeLoad(LoadInst *LI) const {
1146   return TTIImpl->isLegalToVectorizeLoad(LI);
1147 }
1148 
1149 bool TargetTransformInfo::isLegalToVectorizeStore(StoreInst *SI) const {
1150   return TTIImpl->isLegalToVectorizeStore(SI);
1151 }
1152 
1153 bool TargetTransformInfo::isLegalToVectorizeLoadChain(
1154     unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const {
1155   return TTIImpl->isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment,
1156                                               AddrSpace);
1157 }
1158 
1159 bool TargetTransformInfo::isLegalToVectorizeStoreChain(
1160     unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const {
1161   return TTIImpl->isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment,
1162                                                AddrSpace);
1163 }
1164 
1165 bool TargetTransformInfo::isLegalToVectorizeReduction(
1166     const RecurrenceDescriptor &RdxDesc, ElementCount VF) const {
1167   return TTIImpl->isLegalToVectorizeReduction(RdxDesc, VF);
1168 }
1169 
1170 bool TargetTransformInfo::isElementTypeLegalForScalableVector(Type *Ty) const {
1171   return TTIImpl->isElementTypeLegalForScalableVector(Ty);
1172 }
1173 
1174 unsigned TargetTransformInfo::getLoadVectorFactor(unsigned VF,
1175                                                   unsigned LoadSize,
1176                                                   unsigned ChainSizeInBytes,
1177                                                   VectorType *VecTy) const {
1178   return TTIImpl->getLoadVectorFactor(VF, LoadSize, ChainSizeInBytes, VecTy);
1179 }
1180 
1181 unsigned TargetTransformInfo::getStoreVectorFactor(unsigned VF,
1182                                                    unsigned StoreSize,
1183                                                    unsigned ChainSizeInBytes,
1184                                                    VectorType *VecTy) const {
1185   return TTIImpl->getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
1186 }
1187 
1188 bool TargetTransformInfo::preferInLoopReduction(unsigned Opcode, Type *Ty,
1189                                                 ReductionFlags Flags) const {
1190   return TTIImpl->preferInLoopReduction(Opcode, Ty, Flags);
1191 }
1192 
1193 bool TargetTransformInfo::preferPredicatedReductionSelect(
1194     unsigned Opcode, Type *Ty, ReductionFlags Flags) const {
1195   return TTIImpl->preferPredicatedReductionSelect(Opcode, Ty, Flags);
1196 }
1197 
1198 bool TargetTransformInfo::preferEpilogueVectorization() const {
1199   return TTIImpl->preferEpilogueVectorization();
1200 }
1201 
1202 TargetTransformInfo::VPLegalization
1203 TargetTransformInfo::getVPLegalizationStrategy(const VPIntrinsic &VPI) const {
1204   return TTIImpl->getVPLegalizationStrategy(VPI);
1205 }
1206 
1207 bool TargetTransformInfo::hasArmWideBranch(bool Thumb) const {
1208   return TTIImpl->hasArmWideBranch(Thumb);
1209 }
1210 
1211 unsigned TargetTransformInfo::getMaxNumArgs() const {
1212   return TTIImpl->getMaxNumArgs();
1213 }
1214 
1215 bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const {
1216   return TTIImpl->shouldExpandReduction(II);
1217 }
1218 
1219 unsigned TargetTransformInfo::getGISelRematGlobalCost() const {
1220   return TTIImpl->getGISelRematGlobalCost();
1221 }
1222 
1223 unsigned TargetTransformInfo::getMinTripCountTailFoldingThreshold() const {
1224   return TTIImpl->getMinTripCountTailFoldingThreshold();
1225 }
1226 
1227 bool TargetTransformInfo::supportsScalableVectors() const {
1228   return TTIImpl->supportsScalableVectors();
1229 }
1230 
1231 bool TargetTransformInfo::enableScalableVectorization() const {
1232   return TTIImpl->enableScalableVectorization();
1233 }
1234 
1235 bool TargetTransformInfo::hasActiveVectorLength(unsigned Opcode, Type *DataType,
1236                                                 Align Alignment) const {
1237   return TTIImpl->hasActiveVectorLength(Opcode, DataType, Alignment);
1238 }
1239 
1240 TargetTransformInfo::Concept::~Concept() = default;
1241 
1242 TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
1243 
1244 TargetIRAnalysis::TargetIRAnalysis(
1245     std::function<Result(const Function &)> TTICallback)
1246     : TTICallback(std::move(TTICallback)) {}
1247 
1248 TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F,
1249                                                FunctionAnalysisManager &) {
1250   return TTICallback(F);
1251 }
1252 
1253 AnalysisKey TargetIRAnalysis::Key;
1254 
1255 TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) {
1256   return Result(F.getParent()->getDataLayout());
1257 }
1258 
1259 // Register the basic pass.
1260 INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti",
1261                 "Target Transform Information", false, true)
1262 char TargetTransformInfoWrapperPass::ID = 0;
1263 
1264 void TargetTransformInfoWrapperPass::anchor() {}
1265 
1266 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass()
1267     : ImmutablePass(ID) {
1268   initializeTargetTransformInfoWrapperPassPass(
1269       *PassRegistry::getPassRegistry());
1270 }
1271 
1272 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass(
1273     TargetIRAnalysis TIRA)
1274     : ImmutablePass(ID), TIRA(std::move(TIRA)) {
1275   initializeTargetTransformInfoWrapperPassPass(
1276       *PassRegistry::getPassRegistry());
1277 }
1278 
1279 TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) {
1280   FunctionAnalysisManager DummyFAM;
1281   TTI = TIRA.run(F, DummyFAM);
1282   return *TTI;
1283 }
1284 
1285 ImmutablePass *
1286 llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) {
1287   return new TargetTransformInfoWrapperPass(std::move(TIRA));
1288 }
1289