1 //===- llvm/Analysis/TargetTransformInfo.cpp ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Analysis/TargetTransformInfo.h"
10 #include "llvm/Analysis/CFG.h"
11 #include "llvm/Analysis/LoopIterator.h"
12 #include "llvm/Analysis/TargetTransformInfoImpl.h"
13 #include "llvm/IR/CFG.h"
14 #include "llvm/IR/DataLayout.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/IR/PatternMatch.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include <utility>
26
27 using namespace llvm;
28 using namespace PatternMatch;
29
30 #define DEBUG_TYPE "tti"
31
32 static cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false),
33 cl::Hidden,
34 cl::desc("Recognize reduction patterns."));
35
36 namespace {
37 /// No-op implementation of the TTI interface using the utility base
38 /// classes.
39 ///
40 /// This is used when no target specific information is available.
41 struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> {
NoTTIImpl__anon0797968b0111::NoTTIImpl42 explicit NoTTIImpl(const DataLayout &DL)
43 : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {}
44 };
45 } // namespace
46
canAnalyze(LoopInfo & LI)47 bool HardwareLoopInfo::canAnalyze(LoopInfo &LI) {
48 // If the loop has irreducible control flow, it can not be converted to
49 // Hardware loop.
50 LoopBlocksRPO RPOT(L);
51 RPOT.perform(&LI);
52 if (containsIrreducibleCFG<const BasicBlock *>(RPOT, LI))
53 return false;
54 return true;
55 }
56
IntrinsicCostAttributes(Intrinsic::ID Id,const CallBase & CI,InstructionCost ScalarizationCost)57 IntrinsicCostAttributes::IntrinsicCostAttributes(
58 Intrinsic::ID Id, const CallBase &CI, InstructionCost ScalarizationCost)
59 : II(dyn_cast<IntrinsicInst>(&CI)), RetTy(CI.getType()), IID(Id),
60 ScalarizationCost(ScalarizationCost) {
61
62 if (const auto *FPMO = dyn_cast<FPMathOperator>(&CI))
63 FMF = FPMO->getFastMathFlags();
64
65 Arguments.insert(Arguments.begin(), CI.arg_begin(), CI.arg_end());
66 FunctionType *FTy = CI.getCalledFunction()->getFunctionType();
67 ParamTys.insert(ParamTys.begin(), FTy->param_begin(), FTy->param_end());
68 }
69
IntrinsicCostAttributes(Intrinsic::ID Id,Type * RTy,ArrayRef<Type * > Tys,FastMathFlags Flags,const IntrinsicInst * I,InstructionCost ScalarCost)70 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
71 ArrayRef<Type *> Tys,
72 FastMathFlags Flags,
73 const IntrinsicInst *I,
74 InstructionCost ScalarCost)
75 : II(I), RetTy(RTy), IID(Id), FMF(Flags), ScalarizationCost(ScalarCost) {
76 ParamTys.insert(ParamTys.begin(), Tys.begin(), Tys.end());
77 }
78
IntrinsicCostAttributes(Intrinsic::ID Id,Type * Ty,ArrayRef<const Value * > Args)79 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *Ty,
80 ArrayRef<const Value *> Args)
81 : RetTy(Ty), IID(Id) {
82
83 Arguments.insert(Arguments.begin(), Args.begin(), Args.end());
84 ParamTys.reserve(Arguments.size());
85 for (unsigned Idx = 0, Size = Arguments.size(); Idx != Size; ++Idx)
86 ParamTys.push_back(Arguments[Idx]->getType());
87 }
88
IntrinsicCostAttributes(Intrinsic::ID Id,Type * RTy,ArrayRef<const Value * > Args,ArrayRef<Type * > Tys,FastMathFlags Flags,const IntrinsicInst * I,InstructionCost ScalarCost)89 IntrinsicCostAttributes::IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
90 ArrayRef<const Value *> Args,
91 ArrayRef<Type *> Tys,
92 FastMathFlags Flags,
93 const IntrinsicInst *I,
94 InstructionCost ScalarCost)
95 : II(I), RetTy(RTy), IID(Id), FMF(Flags), ScalarizationCost(ScalarCost) {
96 ParamTys.insert(ParamTys.begin(), Tys.begin(), Tys.end());
97 Arguments.insert(Arguments.begin(), Args.begin(), Args.end());
98 }
99
isHardwareLoopCandidate(ScalarEvolution & SE,LoopInfo & LI,DominatorTree & DT,bool ForceNestedLoop,bool ForceHardwareLoopPHI)100 bool HardwareLoopInfo::isHardwareLoopCandidate(ScalarEvolution &SE,
101 LoopInfo &LI, DominatorTree &DT,
102 bool ForceNestedLoop,
103 bool ForceHardwareLoopPHI) {
104 SmallVector<BasicBlock *, 4> ExitingBlocks;
105 L->getExitingBlocks(ExitingBlocks);
106
107 for (BasicBlock *BB : ExitingBlocks) {
108 // If we pass the updated counter back through a phi, we need to know
109 // which latch the updated value will be coming from.
110 if (!L->isLoopLatch(BB)) {
111 if (ForceHardwareLoopPHI || CounterInReg)
112 continue;
113 }
114
115 const SCEV *EC = SE.getExitCount(L, BB);
116 if (isa<SCEVCouldNotCompute>(EC))
117 continue;
118 if (const SCEVConstant *ConstEC = dyn_cast<SCEVConstant>(EC)) {
119 if (ConstEC->getValue()->isZero())
120 continue;
121 } else if (!SE.isLoopInvariant(EC, L))
122 continue;
123
124 if (SE.getTypeSizeInBits(EC->getType()) > CountType->getBitWidth())
125 continue;
126
127 // If this exiting block is contained in a nested loop, it is not eligible
128 // for insertion of the branch-and-decrement since the inner loop would
129 // end up messing up the value in the CTR.
130 if (!IsNestingLegal && LI.getLoopFor(BB) != L && !ForceNestedLoop)
131 continue;
132
133 // We now have a loop-invariant count of loop iterations (which is not the
134 // constant zero) for which we know that this loop will not exit via this
135 // existing block.
136
137 // We need to make sure that this block will run on every loop iteration.
138 // For this to be true, we must dominate all blocks with backedges. Such
139 // blocks are in-loop predecessors to the header block.
140 bool NotAlways = false;
141 for (BasicBlock *Pred : predecessors(L->getHeader())) {
142 if (!L->contains(Pred))
143 continue;
144
145 if (!DT.dominates(BB, Pred)) {
146 NotAlways = true;
147 break;
148 }
149 }
150
151 if (NotAlways)
152 continue;
153
154 // Make sure this blocks ends with a conditional branch.
155 Instruction *TI = BB->getTerminator();
156 if (!TI)
157 continue;
158
159 if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
160 if (!BI->isConditional())
161 continue;
162
163 ExitBranch = BI;
164 } else
165 continue;
166
167 // Note that this block may not be the loop latch block, even if the loop
168 // has a latch block.
169 ExitBlock = BB;
170 ExitCount = EC;
171 break;
172 }
173
174 if (!ExitBlock)
175 return false;
176 return true;
177 }
178
TargetTransformInfo(const DataLayout & DL)179 TargetTransformInfo::TargetTransformInfo(const DataLayout &DL)
180 : TTIImpl(new Model<NoTTIImpl>(NoTTIImpl(DL))) {}
181
~TargetTransformInfo()182 TargetTransformInfo::~TargetTransformInfo() {}
183
TargetTransformInfo(TargetTransformInfo && Arg)184 TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg)
185 : TTIImpl(std::move(Arg.TTIImpl)) {}
186
operator =(TargetTransformInfo && RHS)187 TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) {
188 TTIImpl = std::move(RHS.TTIImpl);
189 return *this;
190 }
191
getInliningThresholdMultiplier() const192 unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
193 return TTIImpl->getInliningThresholdMultiplier();
194 }
195
196 unsigned
adjustInliningThreshold(const CallBase * CB) const197 TargetTransformInfo::adjustInliningThreshold(const CallBase *CB) const {
198 return TTIImpl->adjustInliningThreshold(CB);
199 }
200
getInlinerVectorBonusPercent() const201 int TargetTransformInfo::getInlinerVectorBonusPercent() const {
202 return TTIImpl->getInlinerVectorBonusPercent();
203 }
204
205 InstructionCost
getGEPCost(Type * PointeeType,const Value * Ptr,ArrayRef<const Value * > Operands,TTI::TargetCostKind CostKind) const206 TargetTransformInfo::getGEPCost(Type *PointeeType, const Value *Ptr,
207 ArrayRef<const Value *> Operands,
208 TTI::TargetCostKind CostKind) const {
209 return TTIImpl->getGEPCost(PointeeType, Ptr, Operands, CostKind);
210 }
211
getEstimatedNumberOfCaseClusters(const SwitchInst & SI,unsigned & JTSize,ProfileSummaryInfo * PSI,BlockFrequencyInfo * BFI) const212 unsigned TargetTransformInfo::getEstimatedNumberOfCaseClusters(
213 const SwitchInst &SI, unsigned &JTSize, ProfileSummaryInfo *PSI,
214 BlockFrequencyInfo *BFI) const {
215 return TTIImpl->getEstimatedNumberOfCaseClusters(SI, JTSize, PSI, BFI);
216 }
217
218 InstructionCost
getUserCost(const User * U,ArrayRef<const Value * > Operands,enum TargetCostKind CostKind) const219 TargetTransformInfo::getUserCost(const User *U,
220 ArrayRef<const Value *> Operands,
221 enum TargetCostKind CostKind) const {
222 InstructionCost Cost = TTIImpl->getUserCost(U, Operands, CostKind);
223 assert((CostKind == TTI::TCK_RecipThroughput || Cost >= 0) &&
224 "TTI should not produce negative costs!");
225 return Cost;
226 }
227
getPredictableBranchThreshold() const228 BranchProbability TargetTransformInfo::getPredictableBranchThreshold() const {
229 return TTIImpl->getPredictableBranchThreshold();
230 }
231
hasBranchDivergence() const232 bool TargetTransformInfo::hasBranchDivergence() const {
233 return TTIImpl->hasBranchDivergence();
234 }
235
useGPUDivergenceAnalysis() const236 bool TargetTransformInfo::useGPUDivergenceAnalysis() const {
237 return TTIImpl->useGPUDivergenceAnalysis();
238 }
239
isSourceOfDivergence(const Value * V) const240 bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
241 return TTIImpl->isSourceOfDivergence(V);
242 }
243
isAlwaysUniform(const Value * V) const244 bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const {
245 return TTIImpl->isAlwaysUniform(V);
246 }
247
getFlatAddressSpace() const248 unsigned TargetTransformInfo::getFlatAddressSpace() const {
249 return TTIImpl->getFlatAddressSpace();
250 }
251
collectFlatAddressOperands(SmallVectorImpl<int> & OpIndexes,Intrinsic::ID IID) const252 bool TargetTransformInfo::collectFlatAddressOperands(
253 SmallVectorImpl<int> &OpIndexes, Intrinsic::ID IID) const {
254 return TTIImpl->collectFlatAddressOperands(OpIndexes, IID);
255 }
256
isNoopAddrSpaceCast(unsigned FromAS,unsigned ToAS) const257 bool TargetTransformInfo::isNoopAddrSpaceCast(unsigned FromAS,
258 unsigned ToAS) const {
259 return TTIImpl->isNoopAddrSpaceCast(FromAS, ToAS);
260 }
261
canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const262 bool TargetTransformInfo::canHaveNonUndefGlobalInitializerInAddressSpace(
263 unsigned AS) const {
264 return TTIImpl->canHaveNonUndefGlobalInitializerInAddressSpace(AS);
265 }
266
getAssumedAddrSpace(const Value * V) const267 unsigned TargetTransformInfo::getAssumedAddrSpace(const Value *V) const {
268 return TTIImpl->getAssumedAddrSpace(V);
269 }
270
rewriteIntrinsicWithAddressSpace(IntrinsicInst * II,Value * OldV,Value * NewV) const271 Value *TargetTransformInfo::rewriteIntrinsicWithAddressSpace(
272 IntrinsicInst *II, Value *OldV, Value *NewV) const {
273 return TTIImpl->rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
274 }
275
isLoweredToCall(const Function * F) const276 bool TargetTransformInfo::isLoweredToCall(const Function *F) const {
277 return TTIImpl->isLoweredToCall(F);
278 }
279
isHardwareLoopProfitable(Loop * L,ScalarEvolution & SE,AssumptionCache & AC,TargetLibraryInfo * LibInfo,HardwareLoopInfo & HWLoopInfo) const280 bool TargetTransformInfo::isHardwareLoopProfitable(
281 Loop *L, ScalarEvolution &SE, AssumptionCache &AC,
282 TargetLibraryInfo *LibInfo, HardwareLoopInfo &HWLoopInfo) const {
283 return TTIImpl->isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
284 }
285
preferPredicateOverEpilogue(Loop * L,LoopInfo * LI,ScalarEvolution & SE,AssumptionCache & AC,TargetLibraryInfo * TLI,DominatorTree * DT,const LoopAccessInfo * LAI) const286 bool TargetTransformInfo::preferPredicateOverEpilogue(
287 Loop *L, LoopInfo *LI, ScalarEvolution &SE, AssumptionCache &AC,
288 TargetLibraryInfo *TLI, DominatorTree *DT,
289 const LoopAccessInfo *LAI) const {
290 return TTIImpl->preferPredicateOverEpilogue(L, LI, SE, AC, TLI, DT, LAI);
291 }
292
emitGetActiveLaneMask() const293 bool TargetTransformInfo::emitGetActiveLaneMask() const {
294 return TTIImpl->emitGetActiveLaneMask();
295 }
296
297 Optional<Instruction *>
instCombineIntrinsic(InstCombiner & IC,IntrinsicInst & II) const298 TargetTransformInfo::instCombineIntrinsic(InstCombiner &IC,
299 IntrinsicInst &II) const {
300 return TTIImpl->instCombineIntrinsic(IC, II);
301 }
302
simplifyDemandedUseBitsIntrinsic(InstCombiner & IC,IntrinsicInst & II,APInt DemandedMask,KnownBits & Known,bool & KnownBitsComputed) const303 Optional<Value *> TargetTransformInfo::simplifyDemandedUseBitsIntrinsic(
304 InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
305 bool &KnownBitsComputed) const {
306 return TTIImpl->simplifyDemandedUseBitsIntrinsic(IC, II, DemandedMask, Known,
307 KnownBitsComputed);
308 }
309
simplifyDemandedVectorEltsIntrinsic(InstCombiner & IC,IntrinsicInst & II,APInt DemandedElts,APInt & UndefElts,APInt & UndefElts2,APInt & UndefElts3,std::function<void (Instruction *,unsigned,APInt,APInt &)> SimplifyAndSetOp) const310 Optional<Value *> TargetTransformInfo::simplifyDemandedVectorEltsIntrinsic(
311 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
312 APInt &UndefElts2, APInt &UndefElts3,
313 std::function<void(Instruction *, unsigned, APInt, APInt &)>
314 SimplifyAndSetOp) const {
315 return TTIImpl->simplifyDemandedVectorEltsIntrinsic(
316 IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
317 SimplifyAndSetOp);
318 }
319
getUnrollingPreferences(Loop * L,ScalarEvolution & SE,UnrollingPreferences & UP,OptimizationRemarkEmitter * ORE) const320 void TargetTransformInfo::getUnrollingPreferences(
321 Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP,
322 OptimizationRemarkEmitter *ORE) const {
323 return TTIImpl->getUnrollingPreferences(L, SE, UP, ORE);
324 }
325
getPeelingPreferences(Loop * L,ScalarEvolution & SE,PeelingPreferences & PP) const326 void TargetTransformInfo::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
327 PeelingPreferences &PP) const {
328 return TTIImpl->getPeelingPreferences(L, SE, PP);
329 }
330
isLegalAddImmediate(int64_t Imm) const331 bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
332 return TTIImpl->isLegalAddImmediate(Imm);
333 }
334
isLegalICmpImmediate(int64_t Imm) const335 bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
336 return TTIImpl->isLegalICmpImmediate(Imm);
337 }
338
isLegalAddressingMode(Type * Ty,GlobalValue * BaseGV,int64_t BaseOffset,bool HasBaseReg,int64_t Scale,unsigned AddrSpace,Instruction * I) const339 bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
340 int64_t BaseOffset,
341 bool HasBaseReg, int64_t Scale,
342 unsigned AddrSpace,
343 Instruction *I) const {
344 return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
345 Scale, AddrSpace, I);
346 }
347
isLSRCostLess(LSRCost & C1,LSRCost & C2) const348 bool TargetTransformInfo::isLSRCostLess(LSRCost &C1, LSRCost &C2) const {
349 return TTIImpl->isLSRCostLess(C1, C2);
350 }
351
isNumRegsMajorCostOfLSR() const352 bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
353 return TTIImpl->isNumRegsMajorCostOfLSR();
354 }
355
isProfitableLSRChainElement(Instruction * I) const356 bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const {
357 return TTIImpl->isProfitableLSRChainElement(I);
358 }
359
canMacroFuseCmp() const360 bool TargetTransformInfo::canMacroFuseCmp() const {
361 return TTIImpl->canMacroFuseCmp();
362 }
363
canSaveCmp(Loop * L,BranchInst ** BI,ScalarEvolution * SE,LoopInfo * LI,DominatorTree * DT,AssumptionCache * AC,TargetLibraryInfo * LibInfo) const364 bool TargetTransformInfo::canSaveCmp(Loop *L, BranchInst **BI,
365 ScalarEvolution *SE, LoopInfo *LI,
366 DominatorTree *DT, AssumptionCache *AC,
367 TargetLibraryInfo *LibInfo) const {
368 return TTIImpl->canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
369 }
370
371 TTI::AddressingModeKind
getPreferredAddressingMode(const Loop * L,ScalarEvolution * SE) const372 TargetTransformInfo::getPreferredAddressingMode(const Loop *L,
373 ScalarEvolution *SE) const {
374 return TTIImpl->getPreferredAddressingMode(L, SE);
375 }
376
isLegalMaskedStore(Type * DataType,Align Alignment) const377 bool TargetTransformInfo::isLegalMaskedStore(Type *DataType,
378 Align Alignment) const {
379 return TTIImpl->isLegalMaskedStore(DataType, Alignment);
380 }
381
isLegalMaskedLoad(Type * DataType,Align Alignment) const382 bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType,
383 Align Alignment) const {
384 return TTIImpl->isLegalMaskedLoad(DataType, Alignment);
385 }
386
isLegalNTStore(Type * DataType,Align Alignment) const387 bool TargetTransformInfo::isLegalNTStore(Type *DataType,
388 Align Alignment) const {
389 return TTIImpl->isLegalNTStore(DataType, Alignment);
390 }
391
isLegalNTLoad(Type * DataType,Align Alignment) const392 bool TargetTransformInfo::isLegalNTLoad(Type *DataType, Align Alignment) const {
393 return TTIImpl->isLegalNTLoad(DataType, Alignment);
394 }
395
isLegalMaskedGather(Type * DataType,Align Alignment) const396 bool TargetTransformInfo::isLegalMaskedGather(Type *DataType,
397 Align Alignment) const {
398 return TTIImpl->isLegalMaskedGather(DataType, Alignment);
399 }
400
isLegalMaskedScatter(Type * DataType,Align Alignment) const401 bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType,
402 Align Alignment) const {
403 return TTIImpl->isLegalMaskedScatter(DataType, Alignment);
404 }
405
isLegalMaskedCompressStore(Type * DataType) const406 bool TargetTransformInfo::isLegalMaskedCompressStore(Type *DataType) const {
407 return TTIImpl->isLegalMaskedCompressStore(DataType);
408 }
409
isLegalMaskedExpandLoad(Type * DataType) const410 bool TargetTransformInfo::isLegalMaskedExpandLoad(Type *DataType) const {
411 return TTIImpl->isLegalMaskedExpandLoad(DataType);
412 }
413
enableOrderedReductions() const414 bool TargetTransformInfo::enableOrderedReductions() const {
415 return TTIImpl->enableOrderedReductions();
416 }
417
hasDivRemOp(Type * DataType,bool IsSigned) const418 bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const {
419 return TTIImpl->hasDivRemOp(DataType, IsSigned);
420 }
421
hasVolatileVariant(Instruction * I,unsigned AddrSpace) const422 bool TargetTransformInfo::hasVolatileVariant(Instruction *I,
423 unsigned AddrSpace) const {
424 return TTIImpl->hasVolatileVariant(I, AddrSpace);
425 }
426
prefersVectorizedAddressing() const427 bool TargetTransformInfo::prefersVectorizedAddressing() const {
428 return TTIImpl->prefersVectorizedAddressing();
429 }
430
getScalingFactorCost(Type * Ty,GlobalValue * BaseGV,int64_t BaseOffset,bool HasBaseReg,int64_t Scale,unsigned AddrSpace) const431 InstructionCost TargetTransformInfo::getScalingFactorCost(
432 Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg,
433 int64_t Scale, unsigned AddrSpace) const {
434 InstructionCost Cost = TTIImpl->getScalingFactorCost(
435 Ty, BaseGV, BaseOffset, HasBaseReg, Scale, AddrSpace);
436 assert(Cost >= 0 && "TTI should not produce negative costs!");
437 return Cost;
438 }
439
LSRWithInstrQueries() const440 bool TargetTransformInfo::LSRWithInstrQueries() const {
441 return TTIImpl->LSRWithInstrQueries();
442 }
443
isTruncateFree(Type * Ty1,Type * Ty2) const444 bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const {
445 return TTIImpl->isTruncateFree(Ty1, Ty2);
446 }
447
isProfitableToHoist(Instruction * I) const448 bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const {
449 return TTIImpl->isProfitableToHoist(I);
450 }
451
useAA() const452 bool TargetTransformInfo::useAA() const { return TTIImpl->useAA(); }
453
isTypeLegal(Type * Ty) const454 bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
455 return TTIImpl->isTypeLegal(Ty);
456 }
457
getRegUsageForType(Type * Ty) const458 InstructionCost TargetTransformInfo::getRegUsageForType(Type *Ty) const {
459 return TTIImpl->getRegUsageForType(Ty);
460 }
461
shouldBuildLookupTables() const462 bool TargetTransformInfo::shouldBuildLookupTables() const {
463 return TTIImpl->shouldBuildLookupTables();
464 }
465
shouldBuildLookupTablesForConstant(Constant * C) const466 bool TargetTransformInfo::shouldBuildLookupTablesForConstant(
467 Constant *C) const {
468 return TTIImpl->shouldBuildLookupTablesForConstant(C);
469 }
470
shouldBuildRelLookupTables() const471 bool TargetTransformInfo::shouldBuildRelLookupTables() const {
472 return TTIImpl->shouldBuildRelLookupTables();
473 }
474
useColdCCForColdCall(Function & F) const475 bool TargetTransformInfo::useColdCCForColdCall(Function &F) const {
476 return TTIImpl->useColdCCForColdCall(F);
477 }
478
479 InstructionCost
getScalarizationOverhead(VectorType * Ty,const APInt & DemandedElts,bool Insert,bool Extract) const480 TargetTransformInfo::getScalarizationOverhead(VectorType *Ty,
481 const APInt &DemandedElts,
482 bool Insert, bool Extract) const {
483 return TTIImpl->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract);
484 }
485
getOperandsScalarizationOverhead(ArrayRef<const Value * > Args,ArrayRef<Type * > Tys) const486 InstructionCost TargetTransformInfo::getOperandsScalarizationOverhead(
487 ArrayRef<const Value *> Args, ArrayRef<Type *> Tys) const {
488 return TTIImpl->getOperandsScalarizationOverhead(Args, Tys);
489 }
490
supportsEfficientVectorElementLoadStore() const491 bool TargetTransformInfo::supportsEfficientVectorElementLoadStore() const {
492 return TTIImpl->supportsEfficientVectorElementLoadStore();
493 }
494
enableAggressiveInterleaving(bool LoopHasReductions) const495 bool TargetTransformInfo::enableAggressiveInterleaving(
496 bool LoopHasReductions) const {
497 return TTIImpl->enableAggressiveInterleaving(LoopHasReductions);
498 }
499
500 TargetTransformInfo::MemCmpExpansionOptions
enableMemCmpExpansion(bool OptSize,bool IsZeroCmp) const501 TargetTransformInfo::enableMemCmpExpansion(bool OptSize, bool IsZeroCmp) const {
502 return TTIImpl->enableMemCmpExpansion(OptSize, IsZeroCmp);
503 }
504
enableInterleavedAccessVectorization() const505 bool TargetTransformInfo::enableInterleavedAccessVectorization() const {
506 return TTIImpl->enableInterleavedAccessVectorization();
507 }
508
enableMaskedInterleavedAccessVectorization() const509 bool TargetTransformInfo::enableMaskedInterleavedAccessVectorization() const {
510 return TTIImpl->enableMaskedInterleavedAccessVectorization();
511 }
512
isFPVectorizationPotentiallyUnsafe() const513 bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const {
514 return TTIImpl->isFPVectorizationPotentiallyUnsafe();
515 }
516
allowsMisalignedMemoryAccesses(LLVMContext & Context,unsigned BitWidth,unsigned AddressSpace,Align Alignment,bool * Fast) const517 bool TargetTransformInfo::allowsMisalignedMemoryAccesses(LLVMContext &Context,
518 unsigned BitWidth,
519 unsigned AddressSpace,
520 Align Alignment,
521 bool *Fast) const {
522 return TTIImpl->allowsMisalignedMemoryAccesses(Context, BitWidth,
523 AddressSpace, Alignment, Fast);
524 }
525
526 TargetTransformInfo::PopcntSupportKind
getPopcntSupport(unsigned IntTyWidthInBit) const527 TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const {
528 return TTIImpl->getPopcntSupport(IntTyWidthInBit);
529 }
530
haveFastSqrt(Type * Ty) const531 bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
532 return TTIImpl->haveFastSqrt(Ty);
533 }
534
isFCmpOrdCheaperThanFCmpZero(Type * Ty) const535 bool TargetTransformInfo::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const {
536 return TTIImpl->isFCmpOrdCheaperThanFCmpZero(Ty);
537 }
538
getFPOpCost(Type * Ty) const539 InstructionCost TargetTransformInfo::getFPOpCost(Type *Ty) const {
540 InstructionCost Cost = TTIImpl->getFPOpCost(Ty);
541 assert(Cost >= 0 && "TTI should not produce negative costs!");
542 return Cost;
543 }
544
getIntImmCodeSizeCost(unsigned Opcode,unsigned Idx,const APInt & Imm,Type * Ty) const545 InstructionCost TargetTransformInfo::getIntImmCodeSizeCost(unsigned Opcode,
546 unsigned Idx,
547 const APInt &Imm,
548 Type *Ty) const {
549 InstructionCost Cost = TTIImpl->getIntImmCodeSizeCost(Opcode, Idx, Imm, Ty);
550 assert(Cost >= 0 && "TTI should not produce negative costs!");
551 return Cost;
552 }
553
554 InstructionCost
getIntImmCost(const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind) const555 TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty,
556 TTI::TargetCostKind CostKind) const {
557 InstructionCost Cost = TTIImpl->getIntImmCost(Imm, Ty, CostKind);
558 assert(Cost >= 0 && "TTI should not produce negative costs!");
559 return Cost;
560 }
561
getIntImmCostInst(unsigned Opcode,unsigned Idx,const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind,Instruction * Inst) const562 InstructionCost TargetTransformInfo::getIntImmCostInst(
563 unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty,
564 TTI::TargetCostKind CostKind, Instruction *Inst) const {
565 InstructionCost Cost =
566 TTIImpl->getIntImmCostInst(Opcode, Idx, Imm, Ty, CostKind, Inst);
567 assert(Cost >= 0 && "TTI should not produce negative costs!");
568 return Cost;
569 }
570
571 InstructionCost
getIntImmCostIntrin(Intrinsic::ID IID,unsigned Idx,const APInt & Imm,Type * Ty,TTI::TargetCostKind CostKind) const572 TargetTransformInfo::getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
573 const APInt &Imm, Type *Ty,
574 TTI::TargetCostKind CostKind) const {
575 InstructionCost Cost =
576 TTIImpl->getIntImmCostIntrin(IID, Idx, Imm, Ty, CostKind);
577 assert(Cost >= 0 && "TTI should not produce negative costs!");
578 return Cost;
579 }
580
getNumberOfRegisters(unsigned ClassID) const581 unsigned TargetTransformInfo::getNumberOfRegisters(unsigned ClassID) const {
582 return TTIImpl->getNumberOfRegisters(ClassID);
583 }
584
getRegisterClassForType(bool Vector,Type * Ty) const585 unsigned TargetTransformInfo::getRegisterClassForType(bool Vector,
586 Type *Ty) const {
587 return TTIImpl->getRegisterClassForType(Vector, Ty);
588 }
589
getRegisterClassName(unsigned ClassID) const590 const char *TargetTransformInfo::getRegisterClassName(unsigned ClassID) const {
591 return TTIImpl->getRegisterClassName(ClassID);
592 }
593
getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const594 TypeSize TargetTransformInfo::getRegisterBitWidth(
595 TargetTransformInfo::RegisterKind K) const {
596 return TTIImpl->getRegisterBitWidth(K);
597 }
598
getMinVectorRegisterBitWidth() const599 unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const {
600 return TTIImpl->getMinVectorRegisterBitWidth();
601 }
602
getMaxVScale() const603 Optional<unsigned> TargetTransformInfo::getMaxVScale() const {
604 return TTIImpl->getMaxVScale();
605 }
606
shouldMaximizeVectorBandwidth() const607 bool TargetTransformInfo::shouldMaximizeVectorBandwidth() const {
608 return TTIImpl->shouldMaximizeVectorBandwidth();
609 }
610
getMinimumVF(unsigned ElemWidth,bool IsScalable) const611 ElementCount TargetTransformInfo::getMinimumVF(unsigned ElemWidth,
612 bool IsScalable) const {
613 return TTIImpl->getMinimumVF(ElemWidth, IsScalable);
614 }
615
getMaximumVF(unsigned ElemWidth,unsigned Opcode) const616 unsigned TargetTransformInfo::getMaximumVF(unsigned ElemWidth,
617 unsigned Opcode) const {
618 return TTIImpl->getMaximumVF(ElemWidth, Opcode);
619 }
620
shouldConsiderAddressTypePromotion(const Instruction & I,bool & AllowPromotionWithoutCommonHeader) const621 bool TargetTransformInfo::shouldConsiderAddressTypePromotion(
622 const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
623 return TTIImpl->shouldConsiderAddressTypePromotion(
624 I, AllowPromotionWithoutCommonHeader);
625 }
626
getCacheLineSize() const627 unsigned TargetTransformInfo::getCacheLineSize() const {
628 return TTIImpl->getCacheLineSize();
629 }
630
631 llvm::Optional<unsigned>
getCacheSize(CacheLevel Level) const632 TargetTransformInfo::getCacheSize(CacheLevel Level) const {
633 return TTIImpl->getCacheSize(Level);
634 }
635
636 llvm::Optional<unsigned>
getCacheAssociativity(CacheLevel Level) const637 TargetTransformInfo::getCacheAssociativity(CacheLevel Level) const {
638 return TTIImpl->getCacheAssociativity(Level);
639 }
640
getPrefetchDistance() const641 unsigned TargetTransformInfo::getPrefetchDistance() const {
642 return TTIImpl->getPrefetchDistance();
643 }
644
getMinPrefetchStride(unsigned NumMemAccesses,unsigned NumStridedMemAccesses,unsigned NumPrefetches,bool HasCall) const645 unsigned TargetTransformInfo::getMinPrefetchStride(
646 unsigned NumMemAccesses, unsigned NumStridedMemAccesses,
647 unsigned NumPrefetches, bool HasCall) const {
648 return TTIImpl->getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
649 NumPrefetches, HasCall);
650 }
651
getMaxPrefetchIterationsAhead() const652 unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const {
653 return TTIImpl->getMaxPrefetchIterationsAhead();
654 }
655
enableWritePrefetching() const656 bool TargetTransformInfo::enableWritePrefetching() const {
657 return TTIImpl->enableWritePrefetching();
658 }
659
getMaxInterleaveFactor(unsigned VF) const660 unsigned TargetTransformInfo::getMaxInterleaveFactor(unsigned VF) const {
661 return TTIImpl->getMaxInterleaveFactor(VF);
662 }
663
664 TargetTransformInfo::OperandValueKind
getOperandInfo(const Value * V,OperandValueProperties & OpProps)665 TargetTransformInfo::getOperandInfo(const Value *V,
666 OperandValueProperties &OpProps) {
667 OperandValueKind OpInfo = OK_AnyValue;
668 OpProps = OP_None;
669
670 if (const auto *CI = dyn_cast<ConstantInt>(V)) {
671 if (CI->getValue().isPowerOf2())
672 OpProps = OP_PowerOf2;
673 return OK_UniformConstantValue;
674 }
675
676 // A broadcast shuffle creates a uniform value.
677 // TODO: Add support for non-zero index broadcasts.
678 // TODO: Add support for different source vector width.
679 if (const auto *ShuffleInst = dyn_cast<ShuffleVectorInst>(V))
680 if (ShuffleInst->isZeroEltSplat())
681 OpInfo = OK_UniformValue;
682
683 const Value *Splat = getSplatValue(V);
684
685 // Check for a splat of a constant or for a non uniform vector of constants
686 // and check if the constant(s) are all powers of two.
687 if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
688 OpInfo = OK_NonUniformConstantValue;
689 if (Splat) {
690 OpInfo = OK_UniformConstantValue;
691 if (auto *CI = dyn_cast<ConstantInt>(Splat))
692 if (CI->getValue().isPowerOf2())
693 OpProps = OP_PowerOf2;
694 } else if (const auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
695 OpProps = OP_PowerOf2;
696 for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
697 if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I)))
698 if (CI->getValue().isPowerOf2())
699 continue;
700 OpProps = OP_None;
701 break;
702 }
703 }
704 }
705
706 // Check for a splat of a uniform value. This is not loop aware, so return
707 // true only for the obviously uniform cases (argument, globalvalue)
708 if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
709 OpInfo = OK_UniformValue;
710
711 return OpInfo;
712 }
713
getArithmeticInstrCost(unsigned Opcode,Type * Ty,TTI::TargetCostKind CostKind,OperandValueKind Opd1Info,OperandValueKind Opd2Info,OperandValueProperties Opd1PropInfo,OperandValueProperties Opd2PropInfo,ArrayRef<const Value * > Args,const Instruction * CxtI) const714 InstructionCost TargetTransformInfo::getArithmeticInstrCost(
715 unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
716 OperandValueKind Opd1Info, OperandValueKind Opd2Info,
717 OperandValueProperties Opd1PropInfo, OperandValueProperties Opd2PropInfo,
718 ArrayRef<const Value *> Args, const Instruction *CxtI) const {
719 InstructionCost Cost =
720 TTIImpl->getArithmeticInstrCost(Opcode, Ty, CostKind, Opd1Info, Opd2Info,
721 Opd1PropInfo, Opd2PropInfo, Args, CxtI);
722 assert(Cost >= 0 && "TTI should not produce negative costs!");
723 return Cost;
724 }
725
getShuffleCost(ShuffleKind Kind,VectorType * Ty,ArrayRef<int> Mask,int Index,VectorType * SubTp) const726 InstructionCost TargetTransformInfo::getShuffleCost(ShuffleKind Kind,
727 VectorType *Ty,
728 ArrayRef<int> Mask,
729 int Index,
730 VectorType *SubTp) const {
731 InstructionCost Cost = TTIImpl->getShuffleCost(Kind, Ty, Mask, Index, SubTp);
732 assert(Cost >= 0 && "TTI should not produce negative costs!");
733 return Cost;
734 }
735
736 TTI::CastContextHint
getCastContextHint(const Instruction * I)737 TargetTransformInfo::getCastContextHint(const Instruction *I) {
738 if (!I)
739 return CastContextHint::None;
740
741 auto getLoadStoreKind = [](const Value *V, unsigned LdStOp, unsigned MaskedOp,
742 unsigned GatScatOp) {
743 const Instruction *I = dyn_cast<Instruction>(V);
744 if (!I)
745 return CastContextHint::None;
746
747 if (I->getOpcode() == LdStOp)
748 return CastContextHint::Normal;
749
750 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
751 if (II->getIntrinsicID() == MaskedOp)
752 return TTI::CastContextHint::Masked;
753 if (II->getIntrinsicID() == GatScatOp)
754 return TTI::CastContextHint::GatherScatter;
755 }
756
757 return TTI::CastContextHint::None;
758 };
759
760 switch (I->getOpcode()) {
761 case Instruction::ZExt:
762 case Instruction::SExt:
763 case Instruction::FPExt:
764 return getLoadStoreKind(I->getOperand(0), Instruction::Load,
765 Intrinsic::masked_load, Intrinsic::masked_gather);
766 case Instruction::Trunc:
767 case Instruction::FPTrunc:
768 if (I->hasOneUse())
769 return getLoadStoreKind(*I->user_begin(), Instruction::Store,
770 Intrinsic::masked_store,
771 Intrinsic::masked_scatter);
772 break;
773 default:
774 return CastContextHint::None;
775 }
776
777 return TTI::CastContextHint::None;
778 }
779
getCastInstrCost(unsigned Opcode,Type * Dst,Type * Src,CastContextHint CCH,TTI::TargetCostKind CostKind,const Instruction * I) const780 InstructionCost TargetTransformInfo::getCastInstrCost(
781 unsigned Opcode, Type *Dst, Type *Src, CastContextHint CCH,
782 TTI::TargetCostKind CostKind, const Instruction *I) const {
783 assert((I == nullptr || I->getOpcode() == Opcode) &&
784 "Opcode should reflect passed instruction.");
785 InstructionCost Cost =
786 TTIImpl->getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
787 assert(Cost >= 0 && "TTI should not produce negative costs!");
788 return Cost;
789 }
790
getExtractWithExtendCost(unsigned Opcode,Type * Dst,VectorType * VecTy,unsigned Index) const791 InstructionCost TargetTransformInfo::getExtractWithExtendCost(
792 unsigned Opcode, Type *Dst, VectorType *VecTy, unsigned Index) const {
793 InstructionCost Cost =
794 TTIImpl->getExtractWithExtendCost(Opcode, Dst, VecTy, Index);
795 assert(Cost >= 0 && "TTI should not produce negative costs!");
796 return Cost;
797 }
798
getCFInstrCost(unsigned Opcode,TTI::TargetCostKind CostKind,const Instruction * I) const799 InstructionCost TargetTransformInfo::getCFInstrCost(
800 unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I) const {
801 assert((I == nullptr || I->getOpcode() == Opcode) &&
802 "Opcode should reflect passed instruction.");
803 InstructionCost Cost = TTIImpl->getCFInstrCost(Opcode, CostKind, I);
804 assert(Cost >= 0 && "TTI should not produce negative costs!");
805 return Cost;
806 }
807
getCmpSelInstrCost(unsigned Opcode,Type * ValTy,Type * CondTy,CmpInst::Predicate VecPred,TTI::TargetCostKind CostKind,const Instruction * I) const808 InstructionCost TargetTransformInfo::getCmpSelInstrCost(
809 unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,
810 TTI::TargetCostKind CostKind, const Instruction *I) const {
811 assert((I == nullptr || I->getOpcode() == Opcode) &&
812 "Opcode should reflect passed instruction.");
813 InstructionCost Cost =
814 TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy, VecPred, CostKind, I);
815 assert(Cost >= 0 && "TTI should not produce negative costs!");
816 return Cost;
817 }
818
getVectorInstrCost(unsigned Opcode,Type * Val,unsigned Index) const819 InstructionCost TargetTransformInfo::getVectorInstrCost(unsigned Opcode,
820 Type *Val,
821 unsigned Index) const {
822 InstructionCost Cost = TTIImpl->getVectorInstrCost(Opcode, Val, Index);
823 assert(Cost >= 0 && "TTI should not produce negative costs!");
824 return Cost;
825 }
826
getMemoryOpCost(unsigned Opcode,Type * Src,Align Alignment,unsigned AddressSpace,TTI::TargetCostKind CostKind,const Instruction * I) const827 InstructionCost TargetTransformInfo::getMemoryOpCost(
828 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
829 TTI::TargetCostKind CostKind, const Instruction *I) const {
830 assert((I == nullptr || I->getOpcode() == Opcode) &&
831 "Opcode should reflect passed instruction.");
832 InstructionCost Cost = TTIImpl->getMemoryOpCost(Opcode, Src, Alignment,
833 AddressSpace, CostKind, I);
834 assert(Cost >= 0 && "TTI should not produce negative costs!");
835 return Cost;
836 }
837
getMaskedMemoryOpCost(unsigned Opcode,Type * Src,Align Alignment,unsigned AddressSpace,TTI::TargetCostKind CostKind) const838 InstructionCost TargetTransformInfo::getMaskedMemoryOpCost(
839 unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
840 TTI::TargetCostKind CostKind) const {
841 InstructionCost Cost = TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment,
842 AddressSpace, CostKind);
843 assert(Cost >= 0 && "TTI should not produce negative costs!");
844 return Cost;
845 }
846
getGatherScatterOpCost(unsigned Opcode,Type * DataTy,const Value * Ptr,bool VariableMask,Align Alignment,TTI::TargetCostKind CostKind,const Instruction * I) const847 InstructionCost TargetTransformInfo::getGatherScatterOpCost(
848 unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
849 Align Alignment, TTI::TargetCostKind CostKind, const Instruction *I) const {
850 InstructionCost Cost = TTIImpl->getGatherScatterOpCost(
851 Opcode, DataTy, Ptr, VariableMask, Alignment, CostKind, I);
852 assert(Cost >= 0 && "TTI should not produce negative costs!");
853 return Cost;
854 }
855
getInterleavedMemoryOpCost(unsigned Opcode,Type * VecTy,unsigned Factor,ArrayRef<unsigned> Indices,Align Alignment,unsigned AddressSpace,TTI::TargetCostKind CostKind,bool UseMaskForCond,bool UseMaskForGaps) const856 InstructionCost TargetTransformInfo::getInterleavedMemoryOpCost(
857 unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
858 Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
859 bool UseMaskForCond, bool UseMaskForGaps) const {
860 InstructionCost Cost = TTIImpl->getInterleavedMemoryOpCost(
861 Opcode, VecTy, Factor, Indices, Alignment, AddressSpace, CostKind,
862 UseMaskForCond, UseMaskForGaps);
863 assert(Cost >= 0 && "TTI should not produce negative costs!");
864 return Cost;
865 }
866
867 InstructionCost
getIntrinsicInstrCost(const IntrinsicCostAttributes & ICA,TTI::TargetCostKind CostKind) const868 TargetTransformInfo::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
869 TTI::TargetCostKind CostKind) const {
870 InstructionCost Cost = TTIImpl->getIntrinsicInstrCost(ICA, CostKind);
871 assert(Cost >= 0 && "TTI should not produce negative costs!");
872 return Cost;
873 }
874
875 InstructionCost
getCallInstrCost(Function * F,Type * RetTy,ArrayRef<Type * > Tys,TTI::TargetCostKind CostKind) const876 TargetTransformInfo::getCallInstrCost(Function *F, Type *RetTy,
877 ArrayRef<Type *> Tys,
878 TTI::TargetCostKind CostKind) const {
879 InstructionCost Cost = TTIImpl->getCallInstrCost(F, RetTy, Tys, CostKind);
880 assert(Cost >= 0 && "TTI should not produce negative costs!");
881 return Cost;
882 }
883
getNumberOfParts(Type * Tp) const884 unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const {
885 return TTIImpl->getNumberOfParts(Tp);
886 }
887
888 InstructionCost
getAddressComputationCost(Type * Tp,ScalarEvolution * SE,const SCEV * Ptr) const889 TargetTransformInfo::getAddressComputationCost(Type *Tp, ScalarEvolution *SE,
890 const SCEV *Ptr) const {
891 InstructionCost Cost = TTIImpl->getAddressComputationCost(Tp, SE, Ptr);
892 assert(Cost >= 0 && "TTI should not produce negative costs!");
893 return Cost;
894 }
895
getMemcpyCost(const Instruction * I) const896 InstructionCost TargetTransformInfo::getMemcpyCost(const Instruction *I) const {
897 InstructionCost Cost = TTIImpl->getMemcpyCost(I);
898 assert(Cost >= 0 && "TTI should not produce negative costs!");
899 return Cost;
900 }
901
getArithmeticReductionCost(unsigned Opcode,VectorType * Ty,Optional<FastMathFlags> FMF,TTI::TargetCostKind CostKind) const902 InstructionCost TargetTransformInfo::getArithmeticReductionCost(
903 unsigned Opcode, VectorType *Ty, Optional<FastMathFlags> FMF,
904 TTI::TargetCostKind CostKind) const {
905 InstructionCost Cost =
906 TTIImpl->getArithmeticReductionCost(Opcode, Ty, FMF, CostKind);
907 assert(Cost >= 0 && "TTI should not produce negative costs!");
908 return Cost;
909 }
910
getMinMaxReductionCost(VectorType * Ty,VectorType * CondTy,bool IsUnsigned,TTI::TargetCostKind CostKind) const911 InstructionCost TargetTransformInfo::getMinMaxReductionCost(
912 VectorType *Ty, VectorType *CondTy, bool IsUnsigned,
913 TTI::TargetCostKind CostKind) const {
914 InstructionCost Cost =
915 TTIImpl->getMinMaxReductionCost(Ty, CondTy, IsUnsigned, CostKind);
916 assert(Cost >= 0 && "TTI should not produce negative costs!");
917 return Cost;
918 }
919
getExtendedAddReductionCost(bool IsMLA,bool IsUnsigned,Type * ResTy,VectorType * Ty,TTI::TargetCostKind CostKind) const920 InstructionCost TargetTransformInfo::getExtendedAddReductionCost(
921 bool IsMLA, bool IsUnsigned, Type *ResTy, VectorType *Ty,
922 TTI::TargetCostKind CostKind) const {
923 return TTIImpl->getExtendedAddReductionCost(IsMLA, IsUnsigned, ResTy, Ty,
924 CostKind);
925 }
926
927 InstructionCost
getCostOfKeepingLiveOverCall(ArrayRef<Type * > Tys) const928 TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
929 return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
930 }
931
getTgtMemIntrinsic(IntrinsicInst * Inst,MemIntrinsicInfo & Info) const932 bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
933 MemIntrinsicInfo &Info) const {
934 return TTIImpl->getTgtMemIntrinsic(Inst, Info);
935 }
936
getAtomicMemIntrinsicMaxElementSize() const937 unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const {
938 return TTIImpl->getAtomicMemIntrinsicMaxElementSize();
939 }
940
getOrCreateResultFromMemIntrinsic(IntrinsicInst * Inst,Type * ExpectedType) const941 Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic(
942 IntrinsicInst *Inst, Type *ExpectedType) const {
943 return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
944 }
945
getMemcpyLoopLoweringType(LLVMContext & Context,Value * Length,unsigned SrcAddrSpace,unsigned DestAddrSpace,unsigned SrcAlign,unsigned DestAlign) const946 Type *TargetTransformInfo::getMemcpyLoopLoweringType(
947 LLVMContext &Context, Value *Length, unsigned SrcAddrSpace,
948 unsigned DestAddrSpace, unsigned SrcAlign, unsigned DestAlign) const {
949 return TTIImpl->getMemcpyLoopLoweringType(Context, Length, SrcAddrSpace,
950 DestAddrSpace, SrcAlign, DestAlign);
951 }
952
getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type * > & OpsOut,LLVMContext & Context,unsigned RemainingBytes,unsigned SrcAddrSpace,unsigned DestAddrSpace,unsigned SrcAlign,unsigned DestAlign) const953 void TargetTransformInfo::getMemcpyLoopResidualLoweringType(
954 SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
955 unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
956 unsigned SrcAlign, unsigned DestAlign) const {
957 TTIImpl->getMemcpyLoopResidualLoweringType(OpsOut, Context, RemainingBytes,
958 SrcAddrSpace, DestAddrSpace,
959 SrcAlign, DestAlign);
960 }
961
areInlineCompatible(const Function * Caller,const Function * Callee) const962 bool TargetTransformInfo::areInlineCompatible(const Function *Caller,
963 const Function *Callee) const {
964 return TTIImpl->areInlineCompatible(Caller, Callee);
965 }
966
areFunctionArgsABICompatible(const Function * Caller,const Function * Callee,SmallPtrSetImpl<Argument * > & Args) const967 bool TargetTransformInfo::areFunctionArgsABICompatible(
968 const Function *Caller, const Function *Callee,
969 SmallPtrSetImpl<Argument *> &Args) const {
970 return TTIImpl->areFunctionArgsABICompatible(Caller, Callee, Args);
971 }
972
isIndexedLoadLegal(MemIndexedMode Mode,Type * Ty) const973 bool TargetTransformInfo::isIndexedLoadLegal(MemIndexedMode Mode,
974 Type *Ty) const {
975 return TTIImpl->isIndexedLoadLegal(Mode, Ty);
976 }
977
isIndexedStoreLegal(MemIndexedMode Mode,Type * Ty) const978 bool TargetTransformInfo::isIndexedStoreLegal(MemIndexedMode Mode,
979 Type *Ty) const {
980 return TTIImpl->isIndexedStoreLegal(Mode, Ty);
981 }
982
getLoadStoreVecRegBitWidth(unsigned AS) const983 unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const {
984 return TTIImpl->getLoadStoreVecRegBitWidth(AS);
985 }
986
isLegalToVectorizeLoad(LoadInst * LI) const987 bool TargetTransformInfo::isLegalToVectorizeLoad(LoadInst *LI) const {
988 return TTIImpl->isLegalToVectorizeLoad(LI);
989 }
990
isLegalToVectorizeStore(StoreInst * SI) const991 bool TargetTransformInfo::isLegalToVectorizeStore(StoreInst *SI) const {
992 return TTIImpl->isLegalToVectorizeStore(SI);
993 }
994
isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,Align Alignment,unsigned AddrSpace) const995 bool TargetTransformInfo::isLegalToVectorizeLoadChain(
996 unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const {
997 return TTIImpl->isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment,
998 AddrSpace);
999 }
1000
isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,Align Alignment,unsigned AddrSpace) const1001 bool TargetTransformInfo::isLegalToVectorizeStoreChain(
1002 unsigned ChainSizeInBytes, Align Alignment, unsigned AddrSpace) const {
1003 return TTIImpl->isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment,
1004 AddrSpace);
1005 }
1006
isLegalToVectorizeReduction(const RecurrenceDescriptor & RdxDesc,ElementCount VF) const1007 bool TargetTransformInfo::isLegalToVectorizeReduction(
1008 const RecurrenceDescriptor &RdxDesc, ElementCount VF) const {
1009 return TTIImpl->isLegalToVectorizeReduction(RdxDesc, VF);
1010 }
1011
isElementTypeLegalForScalableVector(Type * Ty) const1012 bool TargetTransformInfo::isElementTypeLegalForScalableVector(Type *Ty) const {
1013 return TTIImpl->isElementTypeLegalForScalableVector(Ty);
1014 }
1015
getLoadVectorFactor(unsigned VF,unsigned LoadSize,unsigned ChainSizeInBytes,VectorType * VecTy) const1016 unsigned TargetTransformInfo::getLoadVectorFactor(unsigned VF,
1017 unsigned LoadSize,
1018 unsigned ChainSizeInBytes,
1019 VectorType *VecTy) const {
1020 return TTIImpl->getLoadVectorFactor(VF, LoadSize, ChainSizeInBytes, VecTy);
1021 }
1022
getStoreVectorFactor(unsigned VF,unsigned StoreSize,unsigned ChainSizeInBytes,VectorType * VecTy) const1023 unsigned TargetTransformInfo::getStoreVectorFactor(unsigned VF,
1024 unsigned StoreSize,
1025 unsigned ChainSizeInBytes,
1026 VectorType *VecTy) const {
1027 return TTIImpl->getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
1028 }
1029
preferInLoopReduction(unsigned Opcode,Type * Ty,ReductionFlags Flags) const1030 bool TargetTransformInfo::preferInLoopReduction(unsigned Opcode, Type *Ty,
1031 ReductionFlags Flags) const {
1032 return TTIImpl->preferInLoopReduction(Opcode, Ty, Flags);
1033 }
1034
preferPredicatedReductionSelect(unsigned Opcode,Type * Ty,ReductionFlags Flags) const1035 bool TargetTransformInfo::preferPredicatedReductionSelect(
1036 unsigned Opcode, Type *Ty, ReductionFlags Flags) const {
1037 return TTIImpl->preferPredicatedReductionSelect(Opcode, Ty, Flags);
1038 }
1039
1040 TargetTransformInfo::VPLegalization
getVPLegalizationStrategy(const VPIntrinsic & VPI) const1041 TargetTransformInfo::getVPLegalizationStrategy(const VPIntrinsic &VPI) const {
1042 return TTIImpl->getVPLegalizationStrategy(VPI);
1043 }
1044
shouldExpandReduction(const IntrinsicInst * II) const1045 bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const {
1046 return TTIImpl->shouldExpandReduction(II);
1047 }
1048
getGISelRematGlobalCost() const1049 unsigned TargetTransformInfo::getGISelRematGlobalCost() const {
1050 return TTIImpl->getGISelRematGlobalCost();
1051 }
1052
supportsScalableVectors() const1053 bool TargetTransformInfo::supportsScalableVectors() const {
1054 return TTIImpl->supportsScalableVectors();
1055 }
1056
hasActiveVectorLength() const1057 bool TargetTransformInfo::hasActiveVectorLength() const {
1058 return TTIImpl->hasActiveVectorLength();
1059 }
1060
1061 InstructionCost
getInstructionLatency(const Instruction * I) const1062 TargetTransformInfo::getInstructionLatency(const Instruction *I) const {
1063 return TTIImpl->getInstructionLatency(I);
1064 }
1065
1066 InstructionCost
getInstructionThroughput(const Instruction * I) const1067 TargetTransformInfo::getInstructionThroughput(const Instruction *I) const {
1068 TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
1069
1070 switch (I->getOpcode()) {
1071 case Instruction::GetElementPtr:
1072 case Instruction::Ret:
1073 case Instruction::PHI:
1074 case Instruction::Br:
1075 case Instruction::Add:
1076 case Instruction::FAdd:
1077 case Instruction::Sub:
1078 case Instruction::FSub:
1079 case Instruction::Mul:
1080 case Instruction::FMul:
1081 case Instruction::UDiv:
1082 case Instruction::SDiv:
1083 case Instruction::FDiv:
1084 case Instruction::URem:
1085 case Instruction::SRem:
1086 case Instruction::FRem:
1087 case Instruction::Shl:
1088 case Instruction::LShr:
1089 case Instruction::AShr:
1090 case Instruction::And:
1091 case Instruction::Or:
1092 case Instruction::Xor:
1093 case Instruction::FNeg:
1094 case Instruction::Select:
1095 case Instruction::ICmp:
1096 case Instruction::FCmp:
1097 case Instruction::Store:
1098 case Instruction::Load:
1099 case Instruction::ZExt:
1100 case Instruction::SExt:
1101 case Instruction::FPToUI:
1102 case Instruction::FPToSI:
1103 case Instruction::FPExt:
1104 case Instruction::PtrToInt:
1105 case Instruction::IntToPtr:
1106 case Instruction::SIToFP:
1107 case Instruction::UIToFP:
1108 case Instruction::Trunc:
1109 case Instruction::FPTrunc:
1110 case Instruction::BitCast:
1111 case Instruction::AddrSpaceCast:
1112 case Instruction::ExtractElement:
1113 case Instruction::InsertElement:
1114 case Instruction::ExtractValue:
1115 case Instruction::ShuffleVector:
1116 case Instruction::Call:
1117 case Instruction::Switch:
1118 return getUserCost(I, CostKind);
1119 default:
1120 // We don't have any information on this instruction.
1121 return -1;
1122 }
1123 }
1124
~Concept()1125 TargetTransformInfo::Concept::~Concept() {}
1126
TargetIRAnalysis()1127 TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
1128
TargetIRAnalysis(std::function<Result (const Function &)> TTICallback)1129 TargetIRAnalysis::TargetIRAnalysis(
1130 std::function<Result(const Function &)> TTICallback)
1131 : TTICallback(std::move(TTICallback)) {}
1132
run(const Function & F,FunctionAnalysisManager &)1133 TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F,
1134 FunctionAnalysisManager &) {
1135 return TTICallback(F);
1136 }
1137
1138 AnalysisKey TargetIRAnalysis::Key;
1139
getDefaultTTI(const Function & F)1140 TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) {
1141 return Result(F.getParent()->getDataLayout());
1142 }
1143
1144 // Register the basic pass.
1145 INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti",
1146 "Target Transform Information", false, true)
1147 char TargetTransformInfoWrapperPass::ID = 0;
1148
anchor()1149 void TargetTransformInfoWrapperPass::anchor() {}
1150
TargetTransformInfoWrapperPass()1151 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass()
1152 : ImmutablePass(ID) {
1153 initializeTargetTransformInfoWrapperPassPass(
1154 *PassRegistry::getPassRegistry());
1155 }
1156
TargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)1157 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass(
1158 TargetIRAnalysis TIRA)
1159 : ImmutablePass(ID), TIRA(std::move(TIRA)) {
1160 initializeTargetTransformInfoWrapperPassPass(
1161 *PassRegistry::getPassRegistry());
1162 }
1163
getTTI(const Function & F)1164 TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) {
1165 FunctionAnalysisManager DummyFAM;
1166 TTI = TIRA.run(F, DummyFAM);
1167 return *TTI;
1168 }
1169
1170 ImmutablePass *
createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)1171 llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) {
1172 return new TargetTransformInfoWrapperPass(std::move(TIRA));
1173 }
1174