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> { 55 explicit NoTTIImpl(const DataLayout &DL) 56 : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {} 57 }; 58 } // namespace 59 60 TargetTransformInfo::TargetTransformInfo( 61 std::unique_ptr<const TargetTransformInfoImplBase> Impl) 62 : TTIImpl(std::move(Impl)) {} 63 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 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 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 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 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 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 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 205 TargetTransformInfo::TargetTransformInfo(const DataLayout &DL) 206 : TTIImpl(std::make_unique<NoTTIImpl>(DL)) {} 207 208 TargetTransformInfo::~TargetTransformInfo() = default; 209 210 TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg) 211 : TTIImpl(std::move(Arg.TTIImpl)) {} 212 213 TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) { 214 TTIImpl = std::move(RHS.TTIImpl); 215 return *this; 216 } 217 218 unsigned TargetTransformInfo::getInliningThresholdMultiplier() const { 219 return TTIImpl->getInliningThresholdMultiplier(); 220 } 221 222 unsigned 223 TargetTransformInfo::getInliningCostBenefitAnalysisSavingsMultiplier() const { 224 return TTIImpl->getInliningCostBenefitAnalysisSavingsMultiplier(); 225 } 226 227 unsigned 228 TargetTransformInfo::getInliningCostBenefitAnalysisProfitableMultiplier() 229 const { 230 return TTIImpl->getInliningCostBenefitAnalysisProfitableMultiplier(); 231 } 232 233 int TargetTransformInfo::getInliningLastCallToStaticBonus() const { 234 return TTIImpl->getInliningLastCallToStaticBonus(); 235 } 236 237 unsigned 238 TargetTransformInfo::adjustInliningThreshold(const CallBase *CB) const { 239 return TTIImpl->adjustInliningThreshold(CB); 240 } 241 242 unsigned TargetTransformInfo::getCallerAllocaCost(const CallBase *CB, 243 const AllocaInst *AI) const { 244 return TTIImpl->getCallerAllocaCost(CB, AI); 245 } 246 247 int TargetTransformInfo::getInlinerVectorBonusPercent() const { 248 return TTIImpl->getInlinerVectorBonusPercent(); 249 } 250 251 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 257 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 266 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 273 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 282 BranchProbability TargetTransformInfo::getPredictableBranchThreshold() const { 283 return PredictableBranchThreshold.getNumOccurrences() > 0 284 ? BranchProbability(PredictableBranchThreshold, 100) 285 : TTIImpl->getPredictableBranchThreshold(); 286 } 287 288 InstructionCost TargetTransformInfo::getBranchMispredictPenalty() const { 289 return TTIImpl->getBranchMispredictPenalty(); 290 } 291 292 bool TargetTransformInfo::hasBranchDivergence(const Function *F) const { 293 return TTIImpl->hasBranchDivergence(F); 294 } 295 296 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 304 bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const { 305 return TTIImpl->isAlwaysUniform(V); 306 } 307 308 bool llvm::TargetTransformInfo::isValidAddrSpaceCast(unsigned FromAS, 309 unsigned ToAS) const { 310 return TTIImpl->isValidAddrSpaceCast(FromAS, ToAS); 311 } 312 313 bool llvm::TargetTransformInfo::addrspacesMayAlias(unsigned FromAS, 314 unsigned ToAS) const { 315 return TTIImpl->addrspacesMayAlias(FromAS, ToAS); 316 } 317 318 unsigned TargetTransformInfo::getFlatAddressSpace() const { 319 return TTIImpl->getFlatAddressSpace(); 320 } 321 322 bool TargetTransformInfo::collectFlatAddressOperands( 323 SmallVectorImpl<int> &OpIndexes, Intrinsic::ID IID) const { 324 return TTIImpl->collectFlatAddressOperands(OpIndexes, IID); 325 } 326 327 bool TargetTransformInfo::isNoopAddrSpaceCast(unsigned FromAS, 328 unsigned ToAS) const { 329 return TTIImpl->isNoopAddrSpaceCast(FromAS, ToAS); 330 } 331 332 bool TargetTransformInfo::canHaveNonUndefGlobalInitializerInAddressSpace( 333 unsigned AS) const { 334 return TTIImpl->canHaveNonUndefGlobalInitializerInAddressSpace(AS); 335 } 336 337 unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const { 338 return TTIImpl->getAssumedAddrSpace(V); 339 } 340 341 bool TargetTransformInfo::isSingleThreaded() const { 342 return TTIImpl->isSingleThreaded(); 343 } 344 345 std::pair<const Value *, unsigned> 346 TargetTransformInfo::getPredicatedAddrSpace(const Value *V) const { 347 return TTIImpl->getPredicatedAddrSpace(V); 348 } 349 350 Value *TargetTransformInfo::rewriteIntrinsicWithAddressSpace( 351 IntrinsicInst *II, Value *OldV, Value *NewV) const { 352 return TTIImpl->rewriteIntrinsicWithAddressSpace(II, OldV, NewV); 353 } 354 355 bool TargetTransformInfo::isLoweredToCall(const Function *F) const { 356 return TTIImpl->isLoweredToCall(F); 357 } 358 359 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 365 unsigned TargetTransformInfo::getEpilogueVectorizationMinVF() const { 366 return TTIImpl->getEpilogueVectorizationMinVF(); 367 } 368 369 bool TargetTransformInfo::preferPredicateOverEpilogue( 370 TailFoldingInfo *TFI) const { 371 return TTIImpl->preferPredicateOverEpilogue(TFI); 372 } 373 374 TailFoldingStyle TargetTransformInfo::getPreferredTailFoldingStyle( 375 bool IVUpdateMayOverflow) const { 376 return TTIImpl->getPreferredTailFoldingStyle(IVUpdateMayOverflow); 377 } 378 379 std::optional<Instruction *> 380 TargetTransformInfo::instCombineIntrinsic(InstCombiner &IC, 381 IntrinsicInst &II) const { 382 return TTIImpl->instCombineIntrinsic(IC, II); 383 } 384 385 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 392 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 402 void TargetTransformInfo::getUnrollingPreferences( 403 Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP, 404 OptimizationRemarkEmitter *ORE) const { 405 return TTIImpl->getUnrollingPreferences(L, SE, UP, ORE); 406 } 407 408 void TargetTransformInfo::getPeelingPreferences(Loop *L, ScalarEvolution &SE, 409 PeelingPreferences &PP) const { 410 return TTIImpl->getPeelingPreferences(L, SE, PP); 411 } 412 413 bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const { 414 return TTIImpl->isLegalAddImmediate(Imm); 415 } 416 417 bool TargetTransformInfo::isLegalAddScalableImmediate(int64_t Imm) const { 418 return TTIImpl->isLegalAddScalableImmediate(Imm); 419 } 420 421 bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const { 422 return TTIImpl->isLegalICmpImmediate(Imm); 423 } 424 425 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 435 bool TargetTransformInfo::isLSRCostLess(const LSRCost &C1, 436 const LSRCost &C2) const { 437 return TTIImpl->isLSRCostLess(C1, C2); 438 } 439 440 bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const { 441 return TTIImpl->isNumRegsMajorCostOfLSR(); 442 } 443 444 bool TargetTransformInfo::shouldDropLSRSolutionIfLessProfitable() const { 445 return TTIImpl->shouldDropLSRSolutionIfLessProfitable(); 446 } 447 448 bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const { 449 return TTIImpl->isProfitableLSRChainElement(I); 450 } 451 452 bool TargetTransformInfo::canMacroFuseCmp() const { 453 return TTIImpl->canMacroFuseCmp(); 454 } 455 456 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 464 TargetTransformInfo::getPreferredAddressingMode(const Loop *L, 465 ScalarEvolution *SE) const { 466 return TTIImpl->getPreferredAddressingMode(L, SE); 467 } 468 469 bool TargetTransformInfo::isLegalMaskedStore(Type *DataType, Align Alignment, 470 unsigned AddressSpace) const { 471 return TTIImpl->isLegalMaskedStore(DataType, Alignment, AddressSpace); 472 } 473 474 bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType, Align Alignment, 475 unsigned AddressSpace) const { 476 return TTIImpl->isLegalMaskedLoad(DataType, Alignment, AddressSpace); 477 } 478 479 bool TargetTransformInfo::isLegalNTStore(Type *DataType, 480 Align Alignment) const { 481 return TTIImpl->isLegalNTStore(DataType, Alignment); 482 } 483 484 bool TargetTransformInfo::isLegalNTLoad(Type *DataType, Align Alignment) const { 485 return TTIImpl->isLegalNTLoad(DataType, Alignment); 486 } 487 488 bool TargetTransformInfo::isLegalBroadcastLoad(Type *ElementTy, 489 ElementCount NumElements) const { 490 return TTIImpl->isLegalBroadcastLoad(ElementTy, NumElements); 491 } 492 493 bool TargetTransformInfo::isLegalMaskedGather(Type *DataType, 494 Align Alignment) const { 495 return TTIImpl->isLegalMaskedGather(DataType, Alignment); 496 } 497 498 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 504 bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType, 505 Align Alignment) const { 506 return TTIImpl->isLegalMaskedScatter(DataType, Alignment); 507 } 508 509 bool TargetTransformInfo::forceScalarizeMaskedGather(VectorType *DataType, 510 Align Alignment) const { 511 return TTIImpl->forceScalarizeMaskedGather(DataType, Alignment); 512 } 513 514 bool TargetTransformInfo::forceScalarizeMaskedScatter(VectorType *DataType, 515 Align Alignment) const { 516 return TTIImpl->forceScalarizeMaskedScatter(DataType, Alignment); 517 } 518 519 bool TargetTransformInfo::isLegalMaskedCompressStore(Type *DataType, 520 Align Alignment) const { 521 return TTIImpl->isLegalMaskedCompressStore(DataType, Alignment); 522 } 523 524 bool TargetTransformInfo::isLegalMaskedExpandLoad(Type *DataType, 525 Align Alignment) const { 526 return TTIImpl->isLegalMaskedExpandLoad(DataType, Alignment); 527 } 528 529 bool TargetTransformInfo::isLegalStridedLoadStore(Type *DataType, 530 Align Alignment) const { 531 return TTIImpl->isLegalStridedLoadStore(DataType, Alignment); 532 } 533 534 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 541 bool TargetTransformInfo::isLegalMaskedVectorHistogram(Type *AddrType, 542 Type *DataType) const { 543 return TTIImpl->isLegalMaskedVectorHistogram(AddrType, DataType); 544 } 545 546 bool TargetTransformInfo::enableOrderedReductions() const { 547 return TTIImpl->enableOrderedReductions(); 548 } 549 550 bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const { 551 return TTIImpl->hasDivRemOp(DataType, IsSigned); 552 } 553 554 bool TargetTransformInfo::hasVolatileVariant(Instruction *I, 555 unsigned AddrSpace) const { 556 return TTIImpl->hasVolatileVariant(I, AddrSpace); 557 } 558 559 bool TargetTransformInfo::prefersVectorizedAddressing() const { 560 return TTIImpl->prefersVectorizedAddressing(); 561 } 562 563 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 572 bool TargetTransformInfo::LSRWithInstrQueries() const { 573 return TTIImpl->LSRWithInstrQueries(); 574 } 575 576 bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const { 577 return TTIImpl->isTruncateFree(Ty1, Ty2); 578 } 579 580 bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const { 581 return TTIImpl->isProfitableToHoist(I); 582 } 583 584 bool TargetTransformInfo::useAA() const { return TTIImpl->useAA(); } 585 586 bool TargetTransformInfo::isTypeLegal(Type *Ty) const { 587 return TTIImpl->isTypeLegal(Ty); 588 } 589 590 unsigned TargetTransformInfo::getRegUsageForType(Type *Ty) const { 591 return TTIImpl->getRegUsageForType(Ty); 592 } 593 594 bool TargetTransformInfo::shouldBuildLookupTables() const { 595 return TTIImpl->shouldBuildLookupTables(); 596 } 597 598 bool TargetTransformInfo::shouldBuildLookupTablesForConstant( 599 Constant *C) const { 600 return TTIImpl->shouldBuildLookupTablesForConstant(C); 601 } 602 603 bool TargetTransformInfo::shouldBuildRelLookupTables() const { 604 return TTIImpl->shouldBuildRelLookupTables(); 605 } 606 607 bool TargetTransformInfo::useColdCCForColdCall(Function &F) const { 608 return TTIImpl->useColdCCForColdCall(F); 609 } 610 611 bool TargetTransformInfo::isTargetIntrinsicTriviallyScalarizable( 612 Intrinsic::ID ID) const { 613 return TTIImpl->isTargetIntrinsicTriviallyScalarizable(ID); 614 } 615 616 bool TargetTransformInfo::isTargetIntrinsicWithScalarOpAtArg( 617 Intrinsic::ID ID, unsigned ScalarOpdIdx) const { 618 return TTIImpl->isTargetIntrinsicWithScalarOpAtArg(ID, ScalarOpdIdx); 619 } 620 621 bool TargetTransformInfo::isTargetIntrinsicWithOverloadTypeAtArg( 622 Intrinsic::ID ID, int OpdIdx) const { 623 return TTIImpl->isTargetIntrinsicWithOverloadTypeAtArg(ID, OpdIdx); 624 } 625 626 bool TargetTransformInfo::isTargetIntrinsicWithStructReturnOverloadAtField( 627 Intrinsic::ID ID, int RetIdx) const { 628 return TTIImpl->isTargetIntrinsicWithStructReturnOverloadAtField(ID, RetIdx); 629 } 630 631 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 639 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 645 bool TargetTransformInfo::supportsEfficientVectorElementLoadStore() const { 646 return TTIImpl->supportsEfficientVectorElementLoadStore(); 647 } 648 649 bool TargetTransformInfo::supportsTailCalls() const { 650 return TTIImpl->supportsTailCalls(); 651 } 652 653 bool TargetTransformInfo::supportsTailCallFor(const CallBase *CB) const { 654 return TTIImpl->supportsTailCallFor(CB); 655 } 656 657 bool TargetTransformInfo::enableAggressiveInterleaving( 658 bool LoopHasReductions) const { 659 return TTIImpl->enableAggressiveInterleaving(LoopHasReductions); 660 } 661 662 TargetTransformInfo::MemCmpExpansionOptions 663 TargetTransformInfo::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const { 664 return TTIImpl->enableMemCmpExpansion(OptSize, IsZeroCmp); 665 } 666 667 bool TargetTransformInfo::enableSelectOptimize() const { 668 return TTIImpl->enableSelectOptimize(); 669 } 670 671 bool TargetTransformInfo::shouldTreatInstructionLikeSelect( 672 const Instruction *I) const { 673 return TTIImpl->shouldTreatInstructionLikeSelect(I); 674 } 675 676 bool TargetTransformInfo::enableInterleavedAccessVectorization() const { 677 return TTIImpl->enableInterleavedAccessVectorization(); 678 } 679 680 bool TargetTransformInfo::enableMaskedInterleavedAccessVectorization() const { 681 return TTIImpl->enableMaskedInterleavedAccessVectorization(); 682 } 683 684 bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const { 685 return TTIImpl->isFPVectorizationPotentiallyUnsafe(); 686 } 687 688 bool 689 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 699 TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const { 700 return TTIImpl->getPopcntSupport(IntTyWidthInBit); 701 } 702 703 bool TargetTransformInfo::haveFastSqrt(Type *Ty) const { 704 return TTIImpl->haveFastSqrt(Ty); 705 } 706 707 bool TargetTransformInfo::isExpensiveToSpeculativelyExecute( 708 const Instruction *I) const { 709 return TTIImpl->isExpensiveToSpeculativelyExecute(I); 710 } 711 712 bool TargetTransformInfo::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const { 713 return TTIImpl->isFCmpOrdCheaperThanFCmpZero(Ty); 714 } 715 716 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 722 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 732 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 739 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 749 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 758 bool TargetTransformInfo::preferToKeepConstantsAttached( 759 const Instruction &Inst, const Function &Fn) const { 760 return TTIImpl->preferToKeepConstantsAttached(Inst, Fn); 761 } 762 763 unsigned TargetTransformInfo::getNumberOfRegisters(unsigned ClassID) const { 764 return TTIImpl->getNumberOfRegisters(ClassID); 765 } 766 767 bool TargetTransformInfo::hasConditionalLoadStoreForType(Type *Ty, 768 bool IsStore) const { 769 return TTIImpl->hasConditionalLoadStoreForType(Ty, IsStore); 770 } 771 772 unsigned TargetTransformInfo::getRegisterClassForType(bool Vector, 773 Type *Ty) const { 774 return TTIImpl->getRegisterClassForType(Vector, Ty); 775 } 776 777 const char *TargetTransformInfo::getRegisterClassName(unsigned ClassID) const { 778 return TTIImpl->getRegisterClassName(ClassID); 779 } 780 781 TypeSize TargetTransformInfo::getRegisterBitWidth( 782 TargetTransformInfo::RegisterKind K) const { 783 return TTIImpl->getRegisterBitWidth(K); 784 } 785 786 unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const { 787 return TTIImpl->getMinVectorRegisterBitWidth(); 788 } 789 790 std::optional<unsigned> TargetTransformInfo::getMaxVScale() const { 791 return TTIImpl->getMaxVScale(); 792 } 793 794 std::optional<unsigned> TargetTransformInfo::getVScaleForTuning() const { 795 return TTIImpl->getVScaleForTuning(); 796 } 797 798 bool TargetTransformInfo::isVScaleKnownToBeAPowerOfTwo() const { 799 return TTIImpl->isVScaleKnownToBeAPowerOfTwo(); 800 } 801 802 bool TargetTransformInfo::shouldMaximizeVectorBandwidth( 803 TargetTransformInfo::RegisterKind K) const { 804 return TTIImpl->shouldMaximizeVectorBandwidth(K); 805 } 806 807 ElementCount TargetTransformInfo::getMinimumVF(unsigned ElemWidth, 808 bool IsScalable) const { 809 return TTIImpl->getMinimumVF(ElemWidth, IsScalable); 810 } 811 812 unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth, 813 unsigned Opcode) const { 814 return TTIImpl->getMaximumVF(ElemWidth, Opcode); 815 } 816 817 unsigned TargetTransformInfo::getStoreMinimumVF(unsigned VF, Type *ScalarMemTy, 818 Type *ScalarValTy) const { 819 return TTIImpl->getStoreMinimumVF(VF, ScalarMemTy, ScalarValTy); 820 } 821 822 bool TargetTransformInfo::shouldConsiderAddressTypePromotion( 823 const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const { 824 return TTIImpl->shouldConsiderAddressTypePromotion( 825 I, AllowPromotionWithoutCommonHeader); 826 } 827 828 unsigned TargetTransformInfo::getCacheLineSize() const { 829 return CacheLineSize.getNumOccurrences() > 0 ? CacheLineSize 830 : TTIImpl->getCacheLineSize(); 831 } 832 833 std::optional<unsigned> 834 TargetTransformInfo::getCacheSize(CacheLevel Level) const { 835 return TTIImpl->getCacheSize(Level); 836 } 837 838 std::optional<unsigned> 839 TargetTransformInfo::getCacheAssociativity(CacheLevel Level) const { 840 return TTIImpl->getCacheAssociativity(Level); 841 } 842 843 std::optional<unsigned> TargetTransformInfo::getMinPageSize() const { 844 return MinPageSize.getNumOccurrences() > 0 ? MinPageSize 845 : TTIImpl->getMinPageSize(); 846 } 847 848 unsigned TargetTransformInfo::getPrefetchDistance() const { 849 return TTIImpl->getPrefetchDistance(); 850 } 851 852 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 859 unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const { 860 return TTIImpl->getMaxPrefetchIterationsAhead(); 861 } 862 863 bool TargetTransformInfo::enableWritePrefetching() const { 864 return TTIImpl->enableWritePrefetching(); 865 } 866 867 bool TargetTransformInfo::shouldPrefetchAddressSpace(unsigned AS) const { 868 return TTIImpl->shouldPrefetchAddressSpace(AS); 869 } 870 871 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 881 unsigned TargetTransformInfo::getMaxInterleaveFactor(ElementCount VF) const { 882 return TTIImpl->getMaxInterleaveFactor(VF); 883 } 884 885 TargetTransformInfo::OperandValueInfo 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 951 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 978 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 987 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 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 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 1055 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 1066 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 1075 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 1084 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 1096 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 1108 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 1122 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 1133 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 1143 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 1152 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 1164 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 1173 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 1183 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 1192 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 1201 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 1213 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 1221 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 1229 unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const { 1230 return TTIImpl->getNumberOfParts(Tp); 1231 } 1232 1233 InstructionCost 1234 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 1241 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 1247 uint64_t TargetTransformInfo::getMaxMemIntrinsicInlineSizeThreshold() const { 1248 return TTIImpl->getMaxMemIntrinsicInlineSizeThreshold(); 1249 } 1250 1251 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 1260 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 1269 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 1276 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 1283 TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const { 1284 return TTIImpl->getCostOfKeepingLiveOverCall(Tys); 1285 } 1286 1287 bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst, 1288 MemIntrinsicInfo &Info) const { 1289 return TTIImpl->getTgtMemIntrinsic(Inst, Info); 1290 } 1291 1292 unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const { 1293 return TTIImpl->getAtomicMemIntrinsicMaxElementSize(); 1294 } 1295 1296 Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic( 1297 IntrinsicInst *Inst, Type *ExpectedType, bool CanCreate) const { 1298 return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType, 1299 CanCreate); 1300 } 1301 1302 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 1311 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 1321 bool TargetTransformInfo::areInlineCompatible(const Function *Caller, 1322 const Function *Callee) const { 1323 return TTIImpl->areInlineCompatible(Caller, Callee); 1324 } 1325 1326 unsigned 1327 TargetTransformInfo::getInlineCallPenalty(const Function *F, 1328 const CallBase &Call, 1329 unsigned DefaultCallPenalty) const { 1330 return TTIImpl->getInlineCallPenalty(F, Call, DefaultCallPenalty); 1331 } 1332 1333 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 1339 bool TargetTransformInfo::isIndexedLoadLegal(MemIndexedMode Mode, 1340 Type *Ty) const { 1341 return TTIImpl->isIndexedLoadLegal(Mode, Ty); 1342 } 1343 1344 bool TargetTransformInfo::isIndexedStoreLegal(MemIndexedMode Mode, 1345 Type *Ty) const { 1346 return TTIImpl->isIndexedStoreLegal(Mode, Ty); 1347 } 1348 1349 unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const { 1350 return TTIImpl->getLoadStoreVecRegBitWidth(AS); 1351 } 1352 1353 bool TargetTransformInfo::isLegalToVectorizeLoad(LoadInst *LI) const { 1354 return TTIImpl->isLegalToVectorizeLoad(LI); 1355 } 1356 1357 bool TargetTransformInfo::isLegalToVectorizeStore(StoreInst *SI) const { 1358 return TTIImpl->isLegalToVectorizeStore(SI); 1359 } 1360 1361 bool TargetTransformInfo::isLegalToVectorizeLoadChain( 1362 unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const { 1363 return TTIImpl->isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment, 1364 AddrSpace); 1365 } 1366 1367 bool TargetTransformInfo::isLegalToVectorizeStoreChain( 1368 unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const { 1369 return TTIImpl->isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment, 1370 AddrSpace); 1371 } 1372 1373 bool TargetTransformInfo::isLegalToVectorizeReduction( 1374 const RecurrenceDescriptor &RdxDesc, ElementCount VF) const { 1375 return TTIImpl->isLegalToVectorizeReduction(RdxDesc, VF); 1376 } 1377 1378 bool TargetTransformInfo::isElementTypeLegalForScalableVector(Type *Ty) const { 1379 return TTIImpl->isElementTypeLegalForScalableVector(Ty); 1380 } 1381 1382 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 1389 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 1396 bool TargetTransformInfo::preferFixedOverScalableIfEqualCost() const { 1397 return TTIImpl->preferFixedOverScalableIfEqualCost(); 1398 } 1399 1400 bool TargetTransformInfo::preferInLoopReduction(RecurKind Kind, 1401 Type *Ty) const { 1402 return TTIImpl->preferInLoopReduction(Kind, Ty); 1403 } 1404 1405 bool TargetTransformInfo::preferAlternateOpcodeVectorization() const { 1406 return TTIImpl->preferAlternateOpcodeVectorization(); 1407 } 1408 1409 bool TargetTransformInfo::preferPredicatedReductionSelect() const { 1410 return TTIImpl->preferPredicatedReductionSelect(); 1411 } 1412 1413 bool TargetTransformInfo::preferEpilogueVectorization() const { 1414 return TTIImpl->preferEpilogueVectorization(); 1415 } 1416 1417 TargetTransformInfo::VPLegalization 1418 TargetTransformInfo::getVPLegalizationStrategy(const VPIntrinsic &VPI) const { 1419 return TTIImpl->getVPLegalizationStrategy(VPI); 1420 } 1421 1422 bool TargetTransformInfo::hasArmWideBranch(bool Thumb) const { 1423 return TTIImpl->hasArmWideBranch(Thumb); 1424 } 1425 1426 uint64_t TargetTransformInfo::getFeatureMask(const Function &F) const { 1427 return TTIImpl->getFeatureMask(F); 1428 } 1429 1430 bool TargetTransformInfo::isMultiversionedFunction(const Function &F) const { 1431 return TTIImpl->isMultiversionedFunction(F); 1432 } 1433 1434 unsigned TargetTransformInfo::getMaxNumArgs() const { 1435 return TTIImpl->getMaxNumArgs(); 1436 } 1437 1438 bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const { 1439 return TTIImpl->shouldExpandReduction(II); 1440 } 1441 1442 TargetTransformInfo::ReductionShuffle 1443 TargetTransformInfo::getPreferredExpandedReductionShuffle( 1444 const IntrinsicInst *II) const { 1445 return TTIImpl->getPreferredExpandedReductionShuffle(II); 1446 } 1447 1448 unsigned TargetTransformInfo::getGISelRematGlobalCost() const { 1449 return TTIImpl->getGISelRematGlobalCost(); 1450 } 1451 1452 unsigned TargetTransformInfo::getMinTripCountTailFoldingThreshold() const { 1453 return TTIImpl->getMinTripCountTailFoldingThreshold(); 1454 } 1455 1456 bool TargetTransformInfo::supportsScalableVectors() const { 1457 return TTIImpl->supportsScalableVectors(); 1458 } 1459 1460 bool TargetTransformInfo::enableScalableVectorization() const { 1461 return TTIImpl->enableScalableVectorization(); 1462 } 1463 1464 bool TargetTransformInfo::hasActiveVectorLength() const { 1465 return TTIImpl->hasActiveVectorLength(); 1466 } 1467 1468 bool TargetTransformInfo::isProfitableToSinkOperands( 1469 Instruction *I, SmallVectorImpl<Use *> &OpsToSink) const { 1470 return TTIImpl->isProfitableToSinkOperands(I, OpsToSink); 1471 } 1472 1473 bool TargetTransformInfo::isVectorShiftByScalarCheap(Type *Ty) const { 1474 return TTIImpl->isVectorShiftByScalarCheap(Ty); 1475 } 1476 1477 unsigned 1478 TargetTransformInfo::getNumBytesToPadGlobalArray(unsigned Size, 1479 Type *ArrayType) const { 1480 return TTIImpl->getNumBytesToPadGlobalArray(Size, ArrayType); 1481 } 1482 1483 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 1491 TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {} 1492 1493 TargetIRAnalysis::TargetIRAnalysis( 1494 std::function<Result(const Function &)> TTICallback) 1495 : TTICallback(std::move(TTICallback)) {} 1496 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 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 1514 void TargetTransformInfoWrapperPass::anchor() {} 1515 1516 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass() 1517 : ImmutablePass(ID) {} 1518 1519 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass( 1520 TargetIRAnalysis TIRA) 1521 : ImmutablePass(ID), TIRA(std::move(TIRA)) {} 1522 1523 TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) { 1524 FunctionAnalysisManager DummyFAM; 1525 TTI = TIRA.run(F, DummyFAM); 1526 return *TTI; 1527 } 1528 1529 ImmutablePass * 1530 llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) { 1531 return new TargetTransformInfoWrapperPass(std::move(TIRA)); 1532 } 1533