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