TargetTransformInfo.cpp 45 KB

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