1139f7f9bSDimitry Andric //===- llvm/Analysis/TargetTransformInfo.cpp ------------------------------===//
2139f7f9bSDimitry Andric //
3139f7f9bSDimitry Andric // The LLVM Compiler Infrastructure
4139f7f9bSDimitry Andric //
5139f7f9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
6139f7f9bSDimitry Andric // License. See LICENSE.TXT for details.
7139f7f9bSDimitry Andric //
8139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
9139f7f9bSDimitry Andric
10139f7f9bSDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
11ff0cc061SDimitry Andric #include "llvm/Analysis/TargetTransformInfoImpl.h"
1291bc56edSDimitry Andric #include "llvm/IR/CallSite.h"
13139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
14139f7f9bSDimitry Andric #include "llvm/IR/Instruction.h"
15139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h"
1691bc56edSDimitry Andric #include "llvm/IR/IntrinsicInst.h"
17ff0cc061SDimitry Andric #include "llvm/IR/Module.h"
1891bc56edSDimitry Andric #include "llvm/IR/Operator.h"
192cab237bSDimitry Andric #include "llvm/IR/PatternMatch.h"
20c4394386SDimitry Andric #include "llvm/Support/CommandLine.h"
21139f7f9bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
223ca95b02SDimitry Andric #include <utility>
23139f7f9bSDimitry Andric
24139f7f9bSDimitry Andric using namespace llvm;
252cab237bSDimitry Andric using namespace PatternMatch;
26139f7f9bSDimitry Andric
2791bc56edSDimitry Andric #define DEBUG_TYPE "tti"
2891bc56edSDimitry Andric
292cab237bSDimitry Andric static cl::opt<bool> EnableReduxCost("costmodel-reduxcost", cl::init(false),
302cab237bSDimitry Andric cl::Hidden,
312cab237bSDimitry Andric cl::desc("Recognize reduction patterns."));
32c4394386SDimitry Andric
33ff0cc061SDimitry Andric namespace {
344ba319b5SDimitry Andric /// No-op implementation of the TTI interface using the utility base
35ff0cc061SDimitry Andric /// classes.
36ff0cc061SDimitry Andric ///
37ff0cc061SDimitry Andric /// This is used when no target specific information is available.
38ff0cc061SDimitry Andric struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> {
NoTTIImpl__anonec99ff370111::NoTTIImpl39875ed548SDimitry Andric explicit NoTTIImpl(const DataLayout &DL)
40ff0cc061SDimitry Andric : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {}
41ff0cc061SDimitry Andric };
42139f7f9bSDimitry Andric }
43139f7f9bSDimitry Andric
TargetTransformInfo(const DataLayout & DL)44875ed548SDimitry Andric TargetTransformInfo::TargetTransformInfo(const DataLayout &DL)
45ff0cc061SDimitry Andric : TTIImpl(new Model<NoTTIImpl>(NoTTIImpl(DL))) {}
46139f7f9bSDimitry Andric
~TargetTransformInfo()47ff0cc061SDimitry Andric TargetTransformInfo::~TargetTransformInfo() {}
48139f7f9bSDimitry Andric
TargetTransformInfo(TargetTransformInfo && Arg)49ff0cc061SDimitry Andric TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg)
50ff0cc061SDimitry Andric : TTIImpl(std::move(Arg.TTIImpl)) {}
51ff0cc061SDimitry Andric
operator =(TargetTransformInfo && RHS)52ff0cc061SDimitry Andric TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) {
53ff0cc061SDimitry Andric TTIImpl = std::move(RHS.TTIImpl);
54ff0cc061SDimitry Andric return *this;
55139f7f9bSDimitry Andric }
56139f7f9bSDimitry Andric
getOperationCost(unsigned Opcode,Type * Ty,Type * OpTy) const577d523365SDimitry Andric int TargetTransformInfo::getOperationCost(unsigned Opcode, Type *Ty,
58139f7f9bSDimitry Andric Type *OpTy) const {
597d523365SDimitry Andric int Cost = TTIImpl->getOperationCost(Opcode, Ty, OpTy);
607d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
617d523365SDimitry Andric return Cost;
62139f7f9bSDimitry Andric }
63139f7f9bSDimitry Andric
getCallCost(FunctionType * FTy,int NumArgs) const647d523365SDimitry Andric int TargetTransformInfo::getCallCost(FunctionType *FTy, int NumArgs) const {
657d523365SDimitry Andric int Cost = TTIImpl->getCallCost(FTy, NumArgs);
667d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
677d523365SDimitry Andric return Cost;
68139f7f9bSDimitry Andric }
69139f7f9bSDimitry Andric
getCallCost(const Function * F,ArrayRef<const Value * > Arguments) const707d523365SDimitry Andric int TargetTransformInfo::getCallCost(const Function *F,
71ff0cc061SDimitry Andric ArrayRef<const Value *> Arguments) const {
727d523365SDimitry Andric int Cost = TTIImpl->getCallCost(F, Arguments);
737d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
747d523365SDimitry Andric return Cost;
75139f7f9bSDimitry Andric }
76139f7f9bSDimitry Andric
getInliningThresholdMultiplier() const773ca95b02SDimitry Andric unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
783ca95b02SDimitry Andric return TTIImpl->getInliningThresholdMultiplier();
793ca95b02SDimitry Andric }
803ca95b02SDimitry Andric
getGEPCost(Type * PointeeType,const Value * Ptr,ArrayRef<const Value * > Operands) const813ca95b02SDimitry Andric int TargetTransformInfo::getGEPCost(Type *PointeeType, const Value *Ptr,
823ca95b02SDimitry Andric ArrayRef<const Value *> Operands) const {
833ca95b02SDimitry Andric return TTIImpl->getGEPCost(PointeeType, Ptr, Operands);
843ca95b02SDimitry Andric }
853ca95b02SDimitry Andric
getExtCost(const Instruction * I,const Value * Src) const86b40b48b8SDimitry Andric int TargetTransformInfo::getExtCost(const Instruction *I,
87b40b48b8SDimitry Andric const Value *Src) const {
88b40b48b8SDimitry Andric return TTIImpl->getExtCost(I, Src);
89b40b48b8SDimitry Andric }
90b40b48b8SDimitry Andric
getIntrinsicCost(Intrinsic::ID IID,Type * RetTy,ArrayRef<const Value * > Arguments) const917d523365SDimitry Andric int TargetTransformInfo::getIntrinsicCost(
927d523365SDimitry Andric Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) const {
937d523365SDimitry Andric int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments);
947d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
957d523365SDimitry Andric return Cost;
96139f7f9bSDimitry Andric }
97139f7f9bSDimitry Andric
98f37b6182SDimitry Andric unsigned
getEstimatedNumberOfCaseClusters(const SwitchInst & SI,unsigned & JTSize) const99f37b6182SDimitry Andric TargetTransformInfo::getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
100f37b6182SDimitry Andric unsigned &JTSize) const {
101f37b6182SDimitry Andric return TTIImpl->getEstimatedNumberOfCaseClusters(SI, JTSize);
102f37b6182SDimitry Andric }
103f37b6182SDimitry Andric
getUserCost(const User * U,ArrayRef<const Value * > Operands) const104a580b014SDimitry Andric int TargetTransformInfo::getUserCost(const User *U,
105a580b014SDimitry Andric ArrayRef<const Value *> Operands) const {
106a580b014SDimitry Andric int Cost = TTIImpl->getUserCost(U, Operands);
1077d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
1087d523365SDimitry Andric return Cost;
109139f7f9bSDimitry Andric }
110139f7f9bSDimitry Andric
hasBranchDivergence() const111f785676fSDimitry Andric bool TargetTransformInfo::hasBranchDivergence() const {
112ff0cc061SDimitry Andric return TTIImpl->hasBranchDivergence();
113ff0cc061SDimitry Andric }
114ff0cc061SDimitry Andric
isSourceOfDivergence(const Value * V) const115ff0cc061SDimitry Andric bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
116ff0cc061SDimitry Andric return TTIImpl->isSourceOfDivergence(V);
117f785676fSDimitry Andric }
118f785676fSDimitry Andric
isAlwaysUniform(const Value * V) const11924d58133SDimitry Andric bool llvm::TargetTransformInfo::isAlwaysUniform(const Value *V) const {
12024d58133SDimitry Andric return TTIImpl->isAlwaysUniform(V);
12124d58133SDimitry Andric }
12224d58133SDimitry Andric
getFlatAddressSpace() const1237a7e6055SDimitry Andric unsigned TargetTransformInfo::getFlatAddressSpace() const {
1247a7e6055SDimitry Andric return TTIImpl->getFlatAddressSpace();
1257a7e6055SDimitry Andric }
1267a7e6055SDimitry Andric
isLoweredToCall(const Function * F) const127139f7f9bSDimitry Andric bool TargetTransformInfo::isLoweredToCall(const Function *F) const {
128ff0cc061SDimitry Andric return TTIImpl->isLoweredToCall(F);
129139f7f9bSDimitry Andric }
130139f7f9bSDimitry Andric
getUnrollingPreferences(Loop * L,ScalarEvolution & SE,UnrollingPreferences & UP) const131ff0cc061SDimitry Andric void TargetTransformInfo::getUnrollingPreferences(
132a580b014SDimitry Andric Loop *L, ScalarEvolution &SE, UnrollingPreferences &UP) const {
133a580b014SDimitry Andric return TTIImpl->getUnrollingPreferences(L, SE, UP);
134f785676fSDimitry Andric }
135f785676fSDimitry Andric
isLegalAddImmediate(int64_t Imm) const136139f7f9bSDimitry Andric bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
137ff0cc061SDimitry Andric return TTIImpl->isLegalAddImmediate(Imm);
138139f7f9bSDimitry Andric }
139139f7f9bSDimitry Andric
isLegalICmpImmediate(int64_t Imm) const140139f7f9bSDimitry Andric bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
141ff0cc061SDimitry Andric return TTIImpl->isLegalICmpImmediate(Imm);
142139f7f9bSDimitry Andric }
143139f7f9bSDimitry Andric
isLegalAddressingMode(Type * Ty,GlobalValue * BaseGV,int64_t BaseOffset,bool HasBaseReg,int64_t Scale,unsigned AddrSpace,Instruction * I) const144139f7f9bSDimitry Andric bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
145139f7f9bSDimitry Andric int64_t BaseOffset,
146139f7f9bSDimitry Andric bool HasBaseReg,
14797bc6c73SDimitry Andric int64_t Scale,
1482cab237bSDimitry Andric unsigned AddrSpace,
1492cab237bSDimitry Andric Instruction *I) const {
150ff0cc061SDimitry Andric return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
1512cab237bSDimitry Andric Scale, AddrSpace, I);
152139f7f9bSDimitry Andric }
153139f7f9bSDimitry Andric
isLSRCostLess(LSRCost & C1,LSRCost & C2) const154db17bf38SDimitry Andric bool TargetTransformInfo::isLSRCostLess(LSRCost &C1, LSRCost &C2) const {
155db17bf38SDimitry Andric return TTIImpl->isLSRCostLess(C1, C2);
156db17bf38SDimitry Andric }
157db17bf38SDimitry Andric
canMacroFuseCmp() const1584ba319b5SDimitry Andric bool TargetTransformInfo::canMacroFuseCmp() const {
1594ba319b5SDimitry Andric return TTIImpl->canMacroFuseCmp();
1604ba319b5SDimitry Andric }
1614ba319b5SDimitry Andric
shouldFavorPostInc() const1624ba319b5SDimitry Andric bool TargetTransformInfo::shouldFavorPostInc() const {
1634ba319b5SDimitry Andric return TTIImpl->shouldFavorPostInc();
1644ba319b5SDimitry Andric }
1654ba319b5SDimitry Andric
isLegalMaskedStore(Type * DataType) const1667d523365SDimitry Andric bool TargetTransformInfo::isLegalMaskedStore(Type *DataType) const {
1677d523365SDimitry Andric return TTIImpl->isLegalMaskedStore(DataType);
168ff0cc061SDimitry Andric }
169ff0cc061SDimitry Andric
isLegalMaskedLoad(Type * DataType) const1707d523365SDimitry Andric bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType) const {
1717d523365SDimitry Andric return TTIImpl->isLegalMaskedLoad(DataType);
1727d523365SDimitry Andric }
1737d523365SDimitry Andric
isLegalMaskedGather(Type * DataType) const1747d523365SDimitry Andric bool TargetTransformInfo::isLegalMaskedGather(Type *DataType) const {
1757d523365SDimitry Andric return TTIImpl->isLegalMaskedGather(DataType);
1767d523365SDimitry Andric }
1777d523365SDimitry Andric
isLegalMaskedScatter(Type * DataType) const1787d523365SDimitry Andric bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType) const {
1792cab237bSDimitry Andric return TTIImpl->isLegalMaskedScatter(DataType);
1802cab237bSDimitry Andric }
1812cab237bSDimitry Andric
hasDivRemOp(Type * DataType,bool IsSigned) const1822cab237bSDimitry Andric bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const {
1832cab237bSDimitry Andric return TTIImpl->hasDivRemOp(DataType, IsSigned);
1842cab237bSDimitry Andric }
1852cab237bSDimitry Andric
hasVolatileVariant(Instruction * I,unsigned AddrSpace) const1862cab237bSDimitry Andric bool TargetTransformInfo::hasVolatileVariant(Instruction *I,
1872cab237bSDimitry Andric unsigned AddrSpace) const {
1882cab237bSDimitry Andric return TTIImpl->hasVolatileVariant(I, AddrSpace);
189ff0cc061SDimitry Andric }
190ff0cc061SDimitry Andric
prefersVectorizedAddressing() const191302affcbSDimitry Andric bool TargetTransformInfo::prefersVectorizedAddressing() const {
192302affcbSDimitry Andric return TTIImpl->prefersVectorizedAddressing();
193302affcbSDimitry Andric }
194302affcbSDimitry Andric
getScalingFactorCost(Type * Ty,GlobalValue * BaseGV,int64_t BaseOffset,bool HasBaseReg,int64_t Scale,unsigned AddrSpace) const195f785676fSDimitry Andric int TargetTransformInfo::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
196f785676fSDimitry Andric int64_t BaseOffset,
197f785676fSDimitry Andric bool HasBaseReg,
19897bc6c73SDimitry Andric int64_t Scale,
19997bc6c73SDimitry Andric unsigned AddrSpace) const {
2007d523365SDimitry Andric int Cost = TTIImpl->getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg,
20197bc6c73SDimitry Andric Scale, AddrSpace);
2027d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
2037d523365SDimitry Andric return Cost;
204f785676fSDimitry Andric }
205f785676fSDimitry Andric
LSRWithInstrQueries() const2062cab237bSDimitry Andric bool TargetTransformInfo::LSRWithInstrQueries() const {
2072cab237bSDimitry Andric return TTIImpl->LSRWithInstrQueries();
208d88c1a5aSDimitry Andric }
209d88c1a5aSDimitry Andric
isTruncateFree(Type * Ty1,Type * Ty2) const210139f7f9bSDimitry Andric bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const {
211ff0cc061SDimitry Andric return TTIImpl->isTruncateFree(Ty1, Ty2);
212ff0cc061SDimitry Andric }
213ff0cc061SDimitry Andric
isProfitableToHoist(Instruction * I) const214ff0cc061SDimitry Andric bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const {
215ff0cc061SDimitry Andric return TTIImpl->isProfitableToHoist(I);
216139f7f9bSDimitry Andric }
217139f7f9bSDimitry Andric
useAA() const2184ba319b5SDimitry Andric bool TargetTransformInfo::useAA() const { return TTIImpl->useAA(); }
2194ba319b5SDimitry Andric
isTypeLegal(Type * Ty) const220139f7f9bSDimitry Andric bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
221ff0cc061SDimitry Andric return TTIImpl->isTypeLegal(Ty);
222139f7f9bSDimitry Andric }
223139f7f9bSDimitry Andric
getJumpBufAlignment() const224139f7f9bSDimitry Andric unsigned TargetTransformInfo::getJumpBufAlignment() const {
225ff0cc061SDimitry Andric return TTIImpl->getJumpBufAlignment();
226139f7f9bSDimitry Andric }
227139f7f9bSDimitry Andric
getJumpBufSize() const228139f7f9bSDimitry Andric unsigned TargetTransformInfo::getJumpBufSize() const {
229ff0cc061SDimitry Andric return TTIImpl->getJumpBufSize();
230139f7f9bSDimitry Andric }
231139f7f9bSDimitry Andric
shouldBuildLookupTables() const232139f7f9bSDimitry Andric bool TargetTransformInfo::shouldBuildLookupTables() const {
233ff0cc061SDimitry Andric return TTIImpl->shouldBuildLookupTables();
234ff0cc061SDimitry Andric }
shouldBuildLookupTablesForConstant(Constant * C) const235d88c1a5aSDimitry Andric bool TargetTransformInfo::shouldBuildLookupTablesForConstant(Constant *C) const {
236d88c1a5aSDimitry Andric return TTIImpl->shouldBuildLookupTablesForConstant(C);
237d88c1a5aSDimitry Andric }
238ff0cc061SDimitry Andric
useColdCCForColdCall(Function & F) const2394ba319b5SDimitry Andric bool TargetTransformInfo::useColdCCForColdCall(Function &F) const {
2404ba319b5SDimitry Andric return TTIImpl->useColdCCForColdCall(F);
2414ba319b5SDimitry Andric }
2424ba319b5SDimitry Andric
2437a7e6055SDimitry Andric unsigned TargetTransformInfo::
getScalarizationOverhead(Type * Ty,bool Insert,bool Extract) const2447a7e6055SDimitry Andric getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const {
2457a7e6055SDimitry Andric return TTIImpl->getScalarizationOverhead(Ty, Insert, Extract);
2467a7e6055SDimitry Andric }
2477a7e6055SDimitry Andric
2487a7e6055SDimitry Andric unsigned TargetTransformInfo::
getOperandsScalarizationOverhead(ArrayRef<const Value * > Args,unsigned VF) const2497a7e6055SDimitry Andric getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
2507a7e6055SDimitry Andric unsigned VF) const {
2517a7e6055SDimitry Andric return TTIImpl->getOperandsScalarizationOverhead(Args, VF);
2527a7e6055SDimitry Andric }
2537a7e6055SDimitry Andric
supportsEfficientVectorElementLoadStore() const2547a7e6055SDimitry Andric bool TargetTransformInfo::supportsEfficientVectorElementLoadStore() const {
2557a7e6055SDimitry Andric return TTIImpl->supportsEfficientVectorElementLoadStore();
2567a7e6055SDimitry Andric }
2577a7e6055SDimitry Andric
enableAggressiveInterleaving(bool LoopHasReductions) const258ff0cc061SDimitry Andric bool TargetTransformInfo::enableAggressiveInterleaving(bool LoopHasReductions) const {
259ff0cc061SDimitry Andric return TTIImpl->enableAggressiveInterleaving(LoopHasReductions);
260139f7f9bSDimitry Andric }
261139f7f9bSDimitry Andric
2622cab237bSDimitry Andric const TargetTransformInfo::MemCmpExpansionOptions *
enableMemCmpExpansion(bool IsZeroCmp) const2632cab237bSDimitry Andric TargetTransformInfo::enableMemCmpExpansion(bool IsZeroCmp) const {
2642cab237bSDimitry Andric return TTIImpl->enableMemCmpExpansion(IsZeroCmp);
265f9448bf3SDimitry Andric }
266f9448bf3SDimitry Andric
enableInterleavedAccessVectorization() const2677d523365SDimitry Andric bool TargetTransformInfo::enableInterleavedAccessVectorization() const {
2687d523365SDimitry Andric return TTIImpl->enableInterleavedAccessVectorization();
2697d523365SDimitry Andric }
2707d523365SDimitry Andric
enableMaskedInterleavedAccessVectorization() const271*b5893f02SDimitry Andric bool TargetTransformInfo::enableMaskedInterleavedAccessVectorization() const {
272*b5893f02SDimitry Andric return TTIImpl->enableMaskedInterleavedAccessVectorization();
273*b5893f02SDimitry Andric }
274*b5893f02SDimitry Andric
isFPVectorizationPotentiallyUnsafe() const2753ca95b02SDimitry Andric bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const {
2763ca95b02SDimitry Andric return TTIImpl->isFPVectorizationPotentiallyUnsafe();
2773ca95b02SDimitry Andric }
2783ca95b02SDimitry Andric
allowsMisalignedMemoryAccesses(LLVMContext & Context,unsigned BitWidth,unsigned AddressSpace,unsigned Alignment,bool * Fast) const279d88c1a5aSDimitry Andric bool TargetTransformInfo::allowsMisalignedMemoryAccesses(LLVMContext &Context,
280d88c1a5aSDimitry Andric unsigned BitWidth,
2813ca95b02SDimitry Andric unsigned AddressSpace,
2823ca95b02SDimitry Andric unsigned Alignment,
2833ca95b02SDimitry Andric bool *Fast) const {
284d88c1a5aSDimitry Andric return TTIImpl->allowsMisalignedMemoryAccesses(Context, BitWidth, AddressSpace,
2853ca95b02SDimitry Andric Alignment, Fast);
2863ca95b02SDimitry Andric }
2873ca95b02SDimitry Andric
288139f7f9bSDimitry Andric TargetTransformInfo::PopcntSupportKind
getPopcntSupport(unsigned IntTyWidthInBit) const289139f7f9bSDimitry Andric TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const {
290ff0cc061SDimitry Andric return TTIImpl->getPopcntSupport(IntTyWidthInBit);
291139f7f9bSDimitry Andric }
292139f7f9bSDimitry Andric
haveFastSqrt(Type * Ty) const293f785676fSDimitry Andric bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
294ff0cc061SDimitry Andric return TTIImpl->haveFastSqrt(Ty);
295ff0cc061SDimitry Andric }
296ff0cc061SDimitry Andric
isFCmpOrdCheaperThanFCmpZero(Type * Ty) const2972cab237bSDimitry Andric bool TargetTransformInfo::isFCmpOrdCheaperThanFCmpZero(Type *Ty) const {
2982cab237bSDimitry Andric return TTIImpl->isFCmpOrdCheaperThanFCmpZero(Ty);
2992cab237bSDimitry Andric }
3002cab237bSDimitry Andric
getFPOpCost(Type * Ty) const3017d523365SDimitry Andric int TargetTransformInfo::getFPOpCost(Type *Ty) const {
3027d523365SDimitry Andric int Cost = TTIImpl->getFPOpCost(Ty);
3037d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
3047d523365SDimitry Andric return Cost;
305f785676fSDimitry Andric }
306f785676fSDimitry Andric
getIntImmCodeSizeCost(unsigned Opcode,unsigned Idx,const APInt & Imm,Type * Ty) const3073ca95b02SDimitry Andric int TargetTransformInfo::getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx,
3083ca95b02SDimitry Andric const APInt &Imm,
3093ca95b02SDimitry Andric Type *Ty) const {
3103ca95b02SDimitry Andric int Cost = TTIImpl->getIntImmCodeSizeCost(Opcode, Idx, Imm, Ty);
3113ca95b02SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
3123ca95b02SDimitry Andric return Cost;
3133ca95b02SDimitry Andric }
3143ca95b02SDimitry Andric
getIntImmCost(const APInt & Imm,Type * Ty) const3157d523365SDimitry Andric int TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const {
3167d523365SDimitry Andric int Cost = TTIImpl->getIntImmCost(Imm, Ty);
3177d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
3187d523365SDimitry Andric return Cost;
319139f7f9bSDimitry Andric }
320139f7f9bSDimitry Andric
getIntImmCost(unsigned Opcode,unsigned Idx,const APInt & Imm,Type * Ty) const3217d523365SDimitry Andric int TargetTransformInfo::getIntImmCost(unsigned Opcode, unsigned Idx,
32291bc56edSDimitry Andric const APInt &Imm, Type *Ty) const {
3237d523365SDimitry Andric int Cost = TTIImpl->getIntImmCost(Opcode, Idx, Imm, Ty);
3247d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
3257d523365SDimitry Andric return Cost;
32691bc56edSDimitry Andric }
32791bc56edSDimitry Andric
getIntImmCost(Intrinsic::ID IID,unsigned Idx,const APInt & Imm,Type * Ty) const3287d523365SDimitry Andric int TargetTransformInfo::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
32991bc56edSDimitry Andric const APInt &Imm, Type *Ty) const {
3307d523365SDimitry Andric int Cost = TTIImpl->getIntImmCost(IID, Idx, Imm, Ty);
3317d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
3327d523365SDimitry Andric return Cost;
33391bc56edSDimitry Andric }
33491bc56edSDimitry Andric
getNumberOfRegisters(bool Vector) const335139f7f9bSDimitry Andric unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const {
336ff0cc061SDimitry Andric return TTIImpl->getNumberOfRegisters(Vector);
337139f7f9bSDimitry Andric }
338139f7f9bSDimitry Andric
getRegisterBitWidth(bool Vector) const339139f7f9bSDimitry Andric unsigned TargetTransformInfo::getRegisterBitWidth(bool Vector) const {
340ff0cc061SDimitry Andric return TTIImpl->getRegisterBitWidth(Vector);
341139f7f9bSDimitry Andric }
342139f7f9bSDimitry Andric
getMinVectorRegisterBitWidth() const3435517e702SDimitry Andric unsigned TargetTransformInfo::getMinVectorRegisterBitWidth() const {
3445517e702SDimitry Andric return TTIImpl->getMinVectorRegisterBitWidth();
3455517e702SDimitry Andric }
3465517e702SDimitry Andric
shouldMaximizeVectorBandwidth(bool OptSize) const3474ba319b5SDimitry Andric bool TargetTransformInfo::shouldMaximizeVectorBandwidth(bool OptSize) const {
3484ba319b5SDimitry Andric return TTIImpl->shouldMaximizeVectorBandwidth(OptSize);
3494ba319b5SDimitry Andric }
3504ba319b5SDimitry Andric
getMinimumVF(unsigned ElemWidth) const3514ba319b5SDimitry Andric unsigned TargetTransformInfo::getMinimumVF(unsigned ElemWidth) const {
3524ba319b5SDimitry Andric return TTIImpl->getMinimumVF(ElemWidth);
3534ba319b5SDimitry Andric }
3544ba319b5SDimitry Andric
shouldConsiderAddressTypePromotion(const Instruction & I,bool & AllowPromotionWithoutCommonHeader) const3557a7e6055SDimitry Andric bool TargetTransformInfo::shouldConsiderAddressTypePromotion(
3567a7e6055SDimitry Andric const Instruction &I, bool &AllowPromotionWithoutCommonHeader) const {
3577a7e6055SDimitry Andric return TTIImpl->shouldConsiderAddressTypePromotion(
3587a7e6055SDimitry Andric I, AllowPromotionWithoutCommonHeader);
3597a7e6055SDimitry Andric }
3607a7e6055SDimitry Andric
getCacheLineSize() const3613ca95b02SDimitry Andric unsigned TargetTransformInfo::getCacheLineSize() const {
3623ca95b02SDimitry Andric return TTIImpl->getCacheLineSize();
3633ca95b02SDimitry Andric }
3643ca95b02SDimitry Andric
getCacheSize(CacheLevel Level) const3652cab237bSDimitry Andric llvm::Optional<unsigned> TargetTransformInfo::getCacheSize(CacheLevel Level)
3662cab237bSDimitry Andric const {
3672cab237bSDimitry Andric return TTIImpl->getCacheSize(Level);
3682cab237bSDimitry Andric }
3692cab237bSDimitry Andric
getCacheAssociativity(CacheLevel Level) const3702cab237bSDimitry Andric llvm::Optional<unsigned> TargetTransformInfo::getCacheAssociativity(
3712cab237bSDimitry Andric CacheLevel Level) const {
3722cab237bSDimitry Andric return TTIImpl->getCacheAssociativity(Level);
3732cab237bSDimitry Andric }
3742cab237bSDimitry Andric
getPrefetchDistance() const3753ca95b02SDimitry Andric unsigned TargetTransformInfo::getPrefetchDistance() const {
3763ca95b02SDimitry Andric return TTIImpl->getPrefetchDistance();
3773ca95b02SDimitry Andric }
3783ca95b02SDimitry Andric
getMinPrefetchStride() const3793ca95b02SDimitry Andric unsigned TargetTransformInfo::getMinPrefetchStride() const {
3803ca95b02SDimitry Andric return TTIImpl->getMinPrefetchStride();
3813ca95b02SDimitry Andric }
3823ca95b02SDimitry Andric
getMaxPrefetchIterationsAhead() const3833ca95b02SDimitry Andric unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const {
3843ca95b02SDimitry Andric return TTIImpl->getMaxPrefetchIterationsAhead();
3853ca95b02SDimitry Andric }
3863ca95b02SDimitry Andric
getMaxInterleaveFactor(unsigned VF) const387ff0cc061SDimitry Andric unsigned TargetTransformInfo::getMaxInterleaveFactor(unsigned VF) const {
388ff0cc061SDimitry Andric return TTIImpl->getMaxInterleaveFactor(VF);
389139f7f9bSDimitry Andric }
390139f7f9bSDimitry Andric
391*b5893f02SDimitry Andric TargetTransformInfo::OperandValueKind
getOperandInfo(Value * V,OperandValueProperties & OpProps)392*b5893f02SDimitry Andric TargetTransformInfo::getOperandInfo(Value *V, OperandValueProperties &OpProps) {
393*b5893f02SDimitry Andric OperandValueKind OpInfo = OK_AnyValue;
394*b5893f02SDimitry Andric OpProps = OP_None;
395*b5893f02SDimitry Andric
396*b5893f02SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(V)) {
397*b5893f02SDimitry Andric if (CI->getValue().isPowerOf2())
398*b5893f02SDimitry Andric OpProps = OP_PowerOf2;
399*b5893f02SDimitry Andric return OK_UniformConstantValue;
400*b5893f02SDimitry Andric }
401*b5893f02SDimitry Andric
402*b5893f02SDimitry Andric // A broadcast shuffle creates a uniform value.
403*b5893f02SDimitry Andric // TODO: Add support for non-zero index broadcasts.
404*b5893f02SDimitry Andric // TODO: Add support for different source vector width.
405*b5893f02SDimitry Andric if (auto *ShuffleInst = dyn_cast<ShuffleVectorInst>(V))
406*b5893f02SDimitry Andric if (ShuffleInst->isZeroEltSplat())
407*b5893f02SDimitry Andric OpInfo = OK_UniformValue;
408*b5893f02SDimitry Andric
409*b5893f02SDimitry Andric const Value *Splat = getSplatValue(V);
410*b5893f02SDimitry Andric
411*b5893f02SDimitry Andric // Check for a splat of a constant or for a non uniform vector of constants
412*b5893f02SDimitry Andric // and check if the constant(s) are all powers of two.
413*b5893f02SDimitry Andric if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
414*b5893f02SDimitry Andric OpInfo = OK_NonUniformConstantValue;
415*b5893f02SDimitry Andric if (Splat) {
416*b5893f02SDimitry Andric OpInfo = OK_UniformConstantValue;
417*b5893f02SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(Splat))
418*b5893f02SDimitry Andric if (CI->getValue().isPowerOf2())
419*b5893f02SDimitry Andric OpProps = OP_PowerOf2;
420*b5893f02SDimitry Andric } else if (auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
421*b5893f02SDimitry Andric OpProps = OP_PowerOf2;
422*b5893f02SDimitry Andric for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
423*b5893f02SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I)))
424*b5893f02SDimitry Andric if (CI->getValue().isPowerOf2())
425*b5893f02SDimitry Andric continue;
426*b5893f02SDimitry Andric OpProps = OP_None;
427*b5893f02SDimitry Andric break;
428*b5893f02SDimitry Andric }
429*b5893f02SDimitry Andric }
430*b5893f02SDimitry Andric }
431*b5893f02SDimitry Andric
432*b5893f02SDimitry Andric // Check for a splat of a uniform value. This is not loop aware, so return
433*b5893f02SDimitry Andric // true only for the obviously uniform cases (argument, globalvalue)
434*b5893f02SDimitry Andric if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
435*b5893f02SDimitry Andric OpInfo = OK_UniformValue;
436*b5893f02SDimitry Andric
437*b5893f02SDimitry Andric return OpInfo;
438*b5893f02SDimitry Andric }
439*b5893f02SDimitry Andric
getArithmeticInstrCost(unsigned Opcode,Type * Ty,OperandValueKind Opd1Info,OperandValueKind Opd2Info,OperandValueProperties Opd1PropInfo,OperandValueProperties Opd2PropInfo,ArrayRef<const Value * > Args) const4407d523365SDimitry Andric int TargetTransformInfo::getArithmeticInstrCost(
441ff0cc061SDimitry Andric unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
442ff0cc061SDimitry Andric OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo,
443f1a29dd3SDimitry Andric OperandValueProperties Opd2PropInfo,
444f1a29dd3SDimitry Andric ArrayRef<const Value *> Args) const {
4457d523365SDimitry Andric int Cost = TTIImpl->getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
446f1a29dd3SDimitry Andric Opd1PropInfo, Opd2PropInfo, Args);
4477d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4487d523365SDimitry Andric return Cost;
449139f7f9bSDimitry Andric }
450139f7f9bSDimitry Andric
getShuffleCost(ShuffleKind Kind,Type * Ty,int Index,Type * SubTp) const4517d523365SDimitry Andric int TargetTransformInfo::getShuffleCost(ShuffleKind Kind, Type *Ty, int Index,
4527d523365SDimitry Andric Type *SubTp) const {
4537d523365SDimitry Andric int Cost = TTIImpl->getShuffleCost(Kind, Ty, Index, SubTp);
4547d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4557d523365SDimitry Andric return Cost;
456139f7f9bSDimitry Andric }
457139f7f9bSDimitry Andric
getCastInstrCost(unsigned Opcode,Type * Dst,Type * Src,const Instruction * I) const4587d523365SDimitry Andric int TargetTransformInfo::getCastInstrCost(unsigned Opcode, Type *Dst,
4597a7e6055SDimitry Andric Type *Src, const Instruction *I) const {
4607a7e6055SDimitry Andric assert ((I == nullptr || I->getOpcode() == Opcode) &&
4617a7e6055SDimitry Andric "Opcode should reflect passed instruction.");
4627a7e6055SDimitry Andric int Cost = TTIImpl->getCastInstrCost(Opcode, Dst, Src, I);
4637d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4647d523365SDimitry Andric return Cost;
465139f7f9bSDimitry Andric }
466139f7f9bSDimitry Andric
getExtractWithExtendCost(unsigned Opcode,Type * Dst,VectorType * VecTy,unsigned Index) const4673ca95b02SDimitry Andric int TargetTransformInfo::getExtractWithExtendCost(unsigned Opcode, Type *Dst,
4683ca95b02SDimitry Andric VectorType *VecTy,
4693ca95b02SDimitry Andric unsigned Index) const {
4703ca95b02SDimitry Andric int Cost = TTIImpl->getExtractWithExtendCost(Opcode, Dst, VecTy, Index);
4713ca95b02SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4723ca95b02SDimitry Andric return Cost;
4733ca95b02SDimitry Andric }
4743ca95b02SDimitry Andric
getCFInstrCost(unsigned Opcode) const4757d523365SDimitry Andric int TargetTransformInfo::getCFInstrCost(unsigned Opcode) const {
4767d523365SDimitry Andric int Cost = TTIImpl->getCFInstrCost(Opcode);
4777d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4787d523365SDimitry Andric return Cost;
479139f7f9bSDimitry Andric }
480139f7f9bSDimitry Andric
getCmpSelInstrCost(unsigned Opcode,Type * ValTy,Type * CondTy,const Instruction * I) const4817d523365SDimitry Andric int TargetTransformInfo::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
4827a7e6055SDimitry Andric Type *CondTy, const Instruction *I) const {
4837a7e6055SDimitry Andric assert ((I == nullptr || I->getOpcode() == Opcode) &&
4847a7e6055SDimitry Andric "Opcode should reflect passed instruction.");
4857a7e6055SDimitry Andric int Cost = TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy, I);
4867d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4877d523365SDimitry Andric return Cost;
488139f7f9bSDimitry Andric }
489139f7f9bSDimitry Andric
getVectorInstrCost(unsigned Opcode,Type * Val,unsigned Index) const4907d523365SDimitry Andric int TargetTransformInfo::getVectorInstrCost(unsigned Opcode, Type *Val,
491139f7f9bSDimitry Andric unsigned Index) const {
4927d523365SDimitry Andric int Cost = TTIImpl->getVectorInstrCost(Opcode, Val, Index);
4937d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
4947d523365SDimitry Andric return Cost;
495139f7f9bSDimitry Andric }
496139f7f9bSDimitry Andric
getMemoryOpCost(unsigned Opcode,Type * Src,unsigned Alignment,unsigned AddressSpace,const Instruction * I) const4977d523365SDimitry Andric int TargetTransformInfo::getMemoryOpCost(unsigned Opcode, Type *Src,
498139f7f9bSDimitry Andric unsigned Alignment,
4997a7e6055SDimitry Andric unsigned AddressSpace,
5007a7e6055SDimitry Andric const Instruction *I) const {
5017a7e6055SDimitry Andric assert ((I == nullptr || I->getOpcode() == Opcode) &&
5027a7e6055SDimitry Andric "Opcode should reflect passed instruction.");
5037a7e6055SDimitry Andric int Cost = TTIImpl->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, I);
5047d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5057d523365SDimitry Andric return Cost;
506139f7f9bSDimitry Andric }
507139f7f9bSDimitry Andric
getMaskedMemoryOpCost(unsigned Opcode,Type * Src,unsigned Alignment,unsigned AddressSpace) const5087d523365SDimitry Andric int TargetTransformInfo::getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
509ff0cc061SDimitry Andric unsigned Alignment,
510ff0cc061SDimitry Andric unsigned AddressSpace) const {
5117d523365SDimitry Andric int Cost =
5127d523365SDimitry Andric TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
5137d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5147d523365SDimitry Andric return Cost;
515ff0cc061SDimitry Andric }
516ff0cc061SDimitry Andric
getGatherScatterOpCost(unsigned Opcode,Type * DataTy,Value * Ptr,bool VariableMask,unsigned Alignment) const5177d523365SDimitry Andric int TargetTransformInfo::getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
5187d523365SDimitry Andric Value *Ptr, bool VariableMask,
5197d523365SDimitry Andric unsigned Alignment) const {
5207d523365SDimitry Andric int Cost = TTIImpl->getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask,
5217d523365SDimitry Andric Alignment);
5227d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5237d523365SDimitry Andric return Cost;
5247d523365SDimitry Andric }
5257d523365SDimitry Andric
getInterleavedMemoryOpCost(unsigned Opcode,Type * VecTy,unsigned Factor,ArrayRef<unsigned> Indices,unsigned Alignment,unsigned AddressSpace,bool UseMaskForCond,bool UseMaskForGaps) const5267d523365SDimitry Andric int TargetTransformInfo::getInterleavedMemoryOpCost(
52797bc6c73SDimitry Andric unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
528*b5893f02SDimitry Andric unsigned Alignment, unsigned AddressSpace, bool UseMaskForCond,
529*b5893f02SDimitry Andric bool UseMaskForGaps) const {
5307d523365SDimitry Andric int Cost = TTIImpl->getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
531*b5893f02SDimitry Andric Alignment, AddressSpace,
532*b5893f02SDimitry Andric UseMaskForCond,
533*b5893f02SDimitry Andric UseMaskForGaps);
5347d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5357d523365SDimitry Andric return Cost;
53697bc6c73SDimitry Andric }
53797bc6c73SDimitry Andric
getIntrinsicInstrCost(Intrinsic::ID ID,Type * RetTy,ArrayRef<Type * > Tys,FastMathFlags FMF,unsigned ScalarizationCostPassed) const5387d523365SDimitry Andric int TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
5397a7e6055SDimitry Andric ArrayRef<Type *> Tys, FastMathFlags FMF,
5407a7e6055SDimitry Andric unsigned ScalarizationCostPassed) const {
5417a7e6055SDimitry Andric int Cost = TTIImpl->getIntrinsicInstrCost(ID, RetTy, Tys, FMF,
5427a7e6055SDimitry Andric ScalarizationCostPassed);
5437d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5447d523365SDimitry Andric return Cost;
545ff0cc061SDimitry Andric }
546ff0cc061SDimitry Andric
getIntrinsicInstrCost(Intrinsic::ID ID,Type * RetTy,ArrayRef<Value * > Args,FastMathFlags FMF,unsigned VF) const5477d523365SDimitry Andric int TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
5487a7e6055SDimitry Andric ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) const {
5497a7e6055SDimitry Andric int Cost = TTIImpl->getIntrinsicInstrCost(ID, RetTy, Args, FMF, VF);
5507d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5517d523365SDimitry Andric return Cost;
5527d523365SDimitry Andric }
5537d523365SDimitry Andric
getCallInstrCost(Function * F,Type * RetTy,ArrayRef<Type * > Tys) const5547d523365SDimitry Andric int TargetTransformInfo::getCallInstrCost(Function *F, Type *RetTy,
555ff0cc061SDimitry Andric ArrayRef<Type *> Tys) const {
5567d523365SDimitry Andric int Cost = TTIImpl->getCallInstrCost(F, RetTy, Tys);
5577d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5587d523365SDimitry Andric return Cost;
559139f7f9bSDimitry Andric }
560139f7f9bSDimitry Andric
getNumberOfParts(Type * Tp) const561139f7f9bSDimitry Andric unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const {
562ff0cc061SDimitry Andric return TTIImpl->getNumberOfParts(Tp);
563139f7f9bSDimitry Andric }
564139f7f9bSDimitry Andric
getAddressComputationCost(Type * Tp,ScalarEvolution * SE,const SCEV * Ptr) const5657d523365SDimitry Andric int TargetTransformInfo::getAddressComputationCost(Type *Tp,
56695ec533aSDimitry Andric ScalarEvolution *SE,
56795ec533aSDimitry Andric const SCEV *Ptr) const {
56895ec533aSDimitry Andric int Cost = TTIImpl->getAddressComputationCost(Tp, SE, Ptr);
5697d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5707d523365SDimitry Andric return Cost;
571f785676fSDimitry Andric }
572f785676fSDimitry Andric
getArithmeticReductionCost(unsigned Opcode,Type * Ty,bool IsPairwiseForm) const5732cab237bSDimitry Andric int TargetTransformInfo::getArithmeticReductionCost(unsigned Opcode, Type *Ty,
574ff0cc061SDimitry Andric bool IsPairwiseForm) const {
5752cab237bSDimitry Andric int Cost = TTIImpl->getArithmeticReductionCost(Opcode, Ty, IsPairwiseForm);
5762cab237bSDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5772cab237bSDimitry Andric return Cost;
5782cab237bSDimitry Andric }
5792cab237bSDimitry Andric
getMinMaxReductionCost(Type * Ty,Type * CondTy,bool IsPairwiseForm,bool IsUnsigned) const5802cab237bSDimitry Andric int TargetTransformInfo::getMinMaxReductionCost(Type *Ty, Type *CondTy,
5812cab237bSDimitry Andric bool IsPairwiseForm,
5822cab237bSDimitry Andric bool IsUnsigned) const {
5832cab237bSDimitry Andric int Cost =
5842cab237bSDimitry Andric TTIImpl->getMinMaxReductionCost(Ty, CondTy, IsPairwiseForm, IsUnsigned);
5857d523365SDimitry Andric assert(Cost >= 0 && "TTI should not produce negative costs!");
5867d523365SDimitry Andric return Cost;
587139f7f9bSDimitry Andric }
588139f7f9bSDimitry Andric
58991bc56edSDimitry Andric unsigned
getCostOfKeepingLiveOverCall(ArrayRef<Type * > Tys) const590ff0cc061SDimitry Andric TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
591ff0cc061SDimitry Andric return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
592139f7f9bSDimitry Andric }
593139f7f9bSDimitry Andric
getTgtMemIntrinsic(IntrinsicInst * Inst,MemIntrinsicInfo & Info) const594ff0cc061SDimitry Andric bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
595ff0cc061SDimitry Andric MemIntrinsicInfo &Info) const {
596ff0cc061SDimitry Andric return TTIImpl->getTgtMemIntrinsic(Inst, Info);
59791bc56edSDimitry Andric }
598139f7f9bSDimitry Andric
getAtomicMemIntrinsicMaxElementSize() const599db17bf38SDimitry Andric unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const {
600db17bf38SDimitry Andric return TTIImpl->getAtomicMemIntrinsicMaxElementSize();
601db17bf38SDimitry Andric }
602db17bf38SDimitry Andric
getOrCreateResultFromMemIntrinsic(IntrinsicInst * Inst,Type * ExpectedType) const603ff0cc061SDimitry Andric Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic(
604ff0cc061SDimitry Andric IntrinsicInst *Inst, Type *ExpectedType) const {
605ff0cc061SDimitry Andric return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
606139f7f9bSDimitry Andric }
607139f7f9bSDimitry Andric
getMemcpyLoopLoweringType(LLVMContext & Context,Value * Length,unsigned SrcAlign,unsigned DestAlign) const608c4394386SDimitry Andric Type *TargetTransformInfo::getMemcpyLoopLoweringType(LLVMContext &Context,
609c4394386SDimitry Andric Value *Length,
610c4394386SDimitry Andric unsigned SrcAlign,
611c4394386SDimitry Andric unsigned DestAlign) const {
612c4394386SDimitry Andric return TTIImpl->getMemcpyLoopLoweringType(Context, Length, SrcAlign,
613c4394386SDimitry Andric DestAlign);
614c4394386SDimitry Andric }
615c4394386SDimitry Andric
getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type * > & OpsOut,LLVMContext & Context,unsigned RemainingBytes,unsigned SrcAlign,unsigned DestAlign) const616c4394386SDimitry Andric void TargetTransformInfo::getMemcpyLoopResidualLoweringType(
617c4394386SDimitry Andric SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
618c4394386SDimitry Andric unsigned RemainingBytes, unsigned SrcAlign, unsigned DestAlign) const {
619c4394386SDimitry Andric TTIImpl->getMemcpyLoopResidualLoweringType(OpsOut, Context, RemainingBytes,
620c4394386SDimitry Andric SrcAlign, DestAlign);
621c4394386SDimitry Andric }
622c4394386SDimitry Andric
areInlineCompatible(const Function * Caller,const Function * Callee) const6237d523365SDimitry Andric bool TargetTransformInfo::areInlineCompatible(const Function *Caller,
6247d523365SDimitry Andric const Function *Callee) const {
6257d523365SDimitry Andric return TTIImpl->areInlineCompatible(Caller, Callee);
6263dac3a9bSDimitry Andric }
6273dac3a9bSDimitry Andric
areFunctionArgsABICompatible(const Function * Caller,const Function * Callee,SmallPtrSetImpl<Argument * > & Args) const628*b5893f02SDimitry Andric bool TargetTransformInfo::areFunctionArgsABICompatible(
629*b5893f02SDimitry Andric const Function *Caller, const Function *Callee,
630*b5893f02SDimitry Andric SmallPtrSetImpl<Argument *> &Args) const {
631*b5893f02SDimitry Andric return TTIImpl->areFunctionArgsABICompatible(Caller, Callee, Args);
632*b5893f02SDimitry Andric }
633*b5893f02SDimitry Andric
isIndexedLoadLegal(MemIndexedMode Mode,Type * Ty) const6344ba319b5SDimitry Andric bool TargetTransformInfo::isIndexedLoadLegal(MemIndexedMode Mode,
6354ba319b5SDimitry Andric Type *Ty) const {
6364ba319b5SDimitry Andric return TTIImpl->isIndexedLoadLegal(Mode, Ty);
6374ba319b5SDimitry Andric }
6384ba319b5SDimitry Andric
isIndexedStoreLegal(MemIndexedMode Mode,Type * Ty) const6394ba319b5SDimitry Andric bool TargetTransformInfo::isIndexedStoreLegal(MemIndexedMode Mode,
6404ba319b5SDimitry Andric Type *Ty) const {
6414ba319b5SDimitry Andric return TTIImpl->isIndexedStoreLegal(Mode, Ty);
6424ba319b5SDimitry Andric }
6434ba319b5SDimitry Andric
getLoadStoreVecRegBitWidth(unsigned AS) const644d88c1a5aSDimitry Andric unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const {
645d88c1a5aSDimitry Andric return TTIImpl->getLoadStoreVecRegBitWidth(AS);
646d88c1a5aSDimitry Andric }
647d88c1a5aSDimitry Andric
isLegalToVectorizeLoad(LoadInst * LI) const648d88c1a5aSDimitry Andric bool TargetTransformInfo::isLegalToVectorizeLoad(LoadInst *LI) const {
649d88c1a5aSDimitry Andric return TTIImpl->isLegalToVectorizeLoad(LI);
650d88c1a5aSDimitry Andric }
651d88c1a5aSDimitry Andric
isLegalToVectorizeStore(StoreInst * SI) const652d88c1a5aSDimitry Andric bool TargetTransformInfo::isLegalToVectorizeStore(StoreInst *SI) const {
653d88c1a5aSDimitry Andric return TTIImpl->isLegalToVectorizeStore(SI);
654d88c1a5aSDimitry Andric }
655d88c1a5aSDimitry Andric
isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,unsigned Alignment,unsigned AddrSpace) const656d88c1a5aSDimitry Andric bool TargetTransformInfo::isLegalToVectorizeLoadChain(
657d88c1a5aSDimitry Andric unsigned ChainSizeInBytes, unsigned Alignment, unsigned AddrSpace) const {
658d88c1a5aSDimitry Andric return TTIImpl->isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment,
659d88c1a5aSDimitry Andric AddrSpace);
660d88c1a5aSDimitry Andric }
661d88c1a5aSDimitry Andric
isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,unsigned Alignment,unsigned AddrSpace) const662d88c1a5aSDimitry Andric bool TargetTransformInfo::isLegalToVectorizeStoreChain(
663d88c1a5aSDimitry Andric unsigned ChainSizeInBytes, unsigned Alignment, unsigned AddrSpace) const {
664d88c1a5aSDimitry Andric return TTIImpl->isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment,
665d88c1a5aSDimitry Andric AddrSpace);
666d88c1a5aSDimitry Andric }
667d88c1a5aSDimitry Andric
getLoadVectorFactor(unsigned VF,unsigned LoadSize,unsigned ChainSizeInBytes,VectorType * VecTy) const668d88c1a5aSDimitry Andric unsigned TargetTransformInfo::getLoadVectorFactor(unsigned VF,
669d88c1a5aSDimitry Andric unsigned LoadSize,
670d88c1a5aSDimitry Andric unsigned ChainSizeInBytes,
671d88c1a5aSDimitry Andric VectorType *VecTy) const {
672d88c1a5aSDimitry Andric return TTIImpl->getLoadVectorFactor(VF, LoadSize, ChainSizeInBytes, VecTy);
673d88c1a5aSDimitry Andric }
674d88c1a5aSDimitry Andric
getStoreVectorFactor(unsigned VF,unsigned StoreSize,unsigned ChainSizeInBytes,VectorType * VecTy) const675d88c1a5aSDimitry Andric unsigned TargetTransformInfo::getStoreVectorFactor(unsigned VF,
676d88c1a5aSDimitry Andric unsigned StoreSize,
677d88c1a5aSDimitry Andric unsigned ChainSizeInBytes,
678d88c1a5aSDimitry Andric VectorType *VecTy) const {
679d88c1a5aSDimitry Andric return TTIImpl->getStoreVectorFactor(VF, StoreSize, ChainSizeInBytes, VecTy);
680d88c1a5aSDimitry Andric }
681d88c1a5aSDimitry Andric
useReductionIntrinsic(unsigned Opcode,Type * Ty,ReductionFlags Flags) const6825517e702SDimitry Andric bool TargetTransformInfo::useReductionIntrinsic(unsigned Opcode,
6835517e702SDimitry Andric Type *Ty, ReductionFlags Flags) const {
6845517e702SDimitry Andric return TTIImpl->useReductionIntrinsic(Opcode, Ty, Flags);
6855517e702SDimitry Andric }
6865517e702SDimitry Andric
shouldExpandReduction(const IntrinsicInst * II) const6875517e702SDimitry Andric bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const {
6885517e702SDimitry Andric return TTIImpl->shouldExpandReduction(II);
6895517e702SDimitry Andric }
6905517e702SDimitry Andric
getInstructionLatency(const Instruction * I) const6912cab237bSDimitry Andric int TargetTransformInfo::getInstructionLatency(const Instruction *I) const {
6922cab237bSDimitry Andric return TTIImpl->getInstructionLatency(I);
6932cab237bSDimitry Andric }
6942cab237bSDimitry Andric
matchPairwiseShuffleMask(ShuffleVectorInst * SI,bool IsLeft,unsigned Level)6952cab237bSDimitry Andric static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft,
6962cab237bSDimitry Andric unsigned Level) {
6972cab237bSDimitry Andric // We don't need a shuffle if we just want to have element 0 in position 0 of
6982cab237bSDimitry Andric // the vector.
6992cab237bSDimitry Andric if (!SI && Level == 0 && IsLeft)
7002cab237bSDimitry Andric return true;
7012cab237bSDimitry Andric else if (!SI)
7022cab237bSDimitry Andric return false;
7032cab237bSDimitry Andric
7042cab237bSDimitry Andric SmallVector<int, 32> Mask(SI->getType()->getVectorNumElements(), -1);
7052cab237bSDimitry Andric
7062cab237bSDimitry Andric // Build a mask of 0, 2, ... (left) or 1, 3, ... (right) depending on whether
7072cab237bSDimitry Andric // we look at the left or right side.
7082cab237bSDimitry Andric for (unsigned i = 0, e = (1 << Level), val = !IsLeft; i != e; ++i, val += 2)
7092cab237bSDimitry Andric Mask[i] = val;
7102cab237bSDimitry Andric
7112cab237bSDimitry Andric SmallVector<int, 16> ActualMask = SI->getShuffleMask();
7122cab237bSDimitry Andric return Mask == ActualMask;
7132cab237bSDimitry Andric }
7142cab237bSDimitry Andric
7152cab237bSDimitry Andric namespace {
7162cab237bSDimitry Andric /// Kind of the reduction data.
7172cab237bSDimitry Andric enum ReductionKind {
7182cab237bSDimitry Andric RK_None, /// Not a reduction.
7192cab237bSDimitry Andric RK_Arithmetic, /// Binary reduction data.
7202cab237bSDimitry Andric RK_MinMax, /// Min/max reduction data.
7212cab237bSDimitry Andric RK_UnsignedMinMax, /// Unsigned min/max reduction data.
7222cab237bSDimitry Andric };
7232cab237bSDimitry Andric /// Contains opcode + LHS/RHS parts of the reduction operations.
7242cab237bSDimitry Andric struct ReductionData {
7252cab237bSDimitry Andric ReductionData() = delete;
ReductionData__anonec99ff370211::ReductionData7262cab237bSDimitry Andric ReductionData(ReductionKind Kind, unsigned Opcode, Value *LHS, Value *RHS)
7272cab237bSDimitry Andric : Opcode(Opcode), LHS(LHS), RHS(RHS), Kind(Kind) {
7282cab237bSDimitry Andric assert(Kind != RK_None && "expected binary or min/max reduction only.");
7292cab237bSDimitry Andric }
7302cab237bSDimitry Andric unsigned Opcode = 0;
7312cab237bSDimitry Andric Value *LHS = nullptr;
7322cab237bSDimitry Andric Value *RHS = nullptr;
7332cab237bSDimitry Andric ReductionKind Kind = RK_None;
hasSameData__anonec99ff370211::ReductionData7342cab237bSDimitry Andric bool hasSameData(ReductionData &RD) const {
7352cab237bSDimitry Andric return Kind == RD.Kind && Opcode == RD.Opcode;
7362cab237bSDimitry Andric }
7372cab237bSDimitry Andric };
7382cab237bSDimitry Andric } // namespace
7392cab237bSDimitry Andric
getReductionData(Instruction * I)7402cab237bSDimitry Andric static Optional<ReductionData> getReductionData(Instruction *I) {
7412cab237bSDimitry Andric Value *L, *R;
7422cab237bSDimitry Andric if (m_BinOp(m_Value(L), m_Value(R)).match(I))
7432cab237bSDimitry Andric return ReductionData(RK_Arithmetic, I->getOpcode(), L, R);
7442cab237bSDimitry Andric if (auto *SI = dyn_cast<SelectInst>(I)) {
7452cab237bSDimitry Andric if (m_SMin(m_Value(L), m_Value(R)).match(SI) ||
7462cab237bSDimitry Andric m_SMax(m_Value(L), m_Value(R)).match(SI) ||
7472cab237bSDimitry Andric m_OrdFMin(m_Value(L), m_Value(R)).match(SI) ||
7482cab237bSDimitry Andric m_OrdFMax(m_Value(L), m_Value(R)).match(SI) ||
7492cab237bSDimitry Andric m_UnordFMin(m_Value(L), m_Value(R)).match(SI) ||
7502cab237bSDimitry Andric m_UnordFMax(m_Value(L), m_Value(R)).match(SI)) {
7512cab237bSDimitry Andric auto *CI = cast<CmpInst>(SI->getCondition());
7522cab237bSDimitry Andric return ReductionData(RK_MinMax, CI->getOpcode(), L, R);
7532cab237bSDimitry Andric }
7542cab237bSDimitry Andric if (m_UMin(m_Value(L), m_Value(R)).match(SI) ||
7552cab237bSDimitry Andric m_UMax(m_Value(L), m_Value(R)).match(SI)) {
7562cab237bSDimitry Andric auto *CI = cast<CmpInst>(SI->getCondition());
7572cab237bSDimitry Andric return ReductionData(RK_UnsignedMinMax, CI->getOpcode(), L, R);
7582cab237bSDimitry Andric }
7592cab237bSDimitry Andric }
7602cab237bSDimitry Andric return llvm::None;
7612cab237bSDimitry Andric }
7622cab237bSDimitry Andric
matchPairwiseReductionAtLevel(Instruction * I,unsigned Level,unsigned NumLevels)7632cab237bSDimitry Andric static ReductionKind matchPairwiseReductionAtLevel(Instruction *I,
7642cab237bSDimitry Andric unsigned Level,
7652cab237bSDimitry Andric unsigned NumLevels) {
7662cab237bSDimitry Andric // Match one level of pairwise operations.
7672cab237bSDimitry Andric // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef,
7682cab237bSDimitry Andric // <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef>
7692cab237bSDimitry Andric // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef,
7702cab237bSDimitry Andric // <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
7712cab237bSDimitry Andric // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1
7722cab237bSDimitry Andric if (!I)
7732cab237bSDimitry Andric return RK_None;
7742cab237bSDimitry Andric
7752cab237bSDimitry Andric assert(I->getType()->isVectorTy() && "Expecting a vector type");
7762cab237bSDimitry Andric
7772cab237bSDimitry Andric Optional<ReductionData> RD = getReductionData(I);
7782cab237bSDimitry Andric if (!RD)
7792cab237bSDimitry Andric return RK_None;
7802cab237bSDimitry Andric
7812cab237bSDimitry Andric ShuffleVectorInst *LS = dyn_cast<ShuffleVectorInst>(RD->LHS);
7822cab237bSDimitry Andric if (!LS && Level)
7832cab237bSDimitry Andric return RK_None;
7842cab237bSDimitry Andric ShuffleVectorInst *RS = dyn_cast<ShuffleVectorInst>(RD->RHS);
7852cab237bSDimitry Andric if (!RS && Level)
7862cab237bSDimitry Andric return RK_None;
7872cab237bSDimitry Andric
7882cab237bSDimitry Andric // On level 0 we can omit one shufflevector instruction.
7892cab237bSDimitry Andric if (!Level && !RS && !LS)
7902cab237bSDimitry Andric return RK_None;
7912cab237bSDimitry Andric
7922cab237bSDimitry Andric // Shuffle inputs must match.
7932cab237bSDimitry Andric Value *NextLevelOpL = LS ? LS->getOperand(0) : nullptr;
7942cab237bSDimitry Andric Value *NextLevelOpR = RS ? RS->getOperand(0) : nullptr;
7952cab237bSDimitry Andric Value *NextLevelOp = nullptr;
7962cab237bSDimitry Andric if (NextLevelOpR && NextLevelOpL) {
7972cab237bSDimitry Andric // If we have two shuffles their operands must match.
7982cab237bSDimitry Andric if (NextLevelOpL != NextLevelOpR)
7992cab237bSDimitry Andric return RK_None;
8002cab237bSDimitry Andric
8012cab237bSDimitry Andric NextLevelOp = NextLevelOpL;
8022cab237bSDimitry Andric } else if (Level == 0 && (NextLevelOpR || NextLevelOpL)) {
8032cab237bSDimitry Andric // On the first level we can omit the shufflevector <0, undef,...>. So the
8042cab237bSDimitry Andric // input to the other shufflevector <1, undef> must match with one of the
8052cab237bSDimitry Andric // inputs to the current binary operation.
8062cab237bSDimitry Andric // Example:
8072cab237bSDimitry Andric // %NextLevelOpL = shufflevector %R, <1, undef ...>
8082cab237bSDimitry Andric // %BinOp = fadd %NextLevelOpL, %R
8092cab237bSDimitry Andric if (NextLevelOpL && NextLevelOpL != RD->RHS)
8102cab237bSDimitry Andric return RK_None;
8112cab237bSDimitry Andric else if (NextLevelOpR && NextLevelOpR != RD->LHS)
8122cab237bSDimitry Andric return RK_None;
8132cab237bSDimitry Andric
8142cab237bSDimitry Andric NextLevelOp = NextLevelOpL ? RD->RHS : RD->LHS;
8152cab237bSDimitry Andric } else
8162cab237bSDimitry Andric return RK_None;
8172cab237bSDimitry Andric
8182cab237bSDimitry Andric // Check that the next levels binary operation exists and matches with the
8192cab237bSDimitry Andric // current one.
8202cab237bSDimitry Andric if (Level + 1 != NumLevels) {
8212cab237bSDimitry Andric Optional<ReductionData> NextLevelRD =
8222cab237bSDimitry Andric getReductionData(cast<Instruction>(NextLevelOp));
8232cab237bSDimitry Andric if (!NextLevelRD || !RD->hasSameData(*NextLevelRD))
8242cab237bSDimitry Andric return RK_None;
8252cab237bSDimitry Andric }
8262cab237bSDimitry Andric
8272cab237bSDimitry Andric // Shuffle mask for pairwise operation must match.
8282cab237bSDimitry Andric if (matchPairwiseShuffleMask(LS, /*IsLeft=*/true, Level)) {
8292cab237bSDimitry Andric if (!matchPairwiseShuffleMask(RS, /*IsLeft=*/false, Level))
8302cab237bSDimitry Andric return RK_None;
8312cab237bSDimitry Andric } else if (matchPairwiseShuffleMask(RS, /*IsLeft=*/true, Level)) {
8322cab237bSDimitry Andric if (!matchPairwiseShuffleMask(LS, /*IsLeft=*/false, Level))
8332cab237bSDimitry Andric return RK_None;
8342cab237bSDimitry Andric } else {
8352cab237bSDimitry Andric return RK_None;
8362cab237bSDimitry Andric }
8372cab237bSDimitry Andric
8382cab237bSDimitry Andric if (++Level == NumLevels)
8392cab237bSDimitry Andric return RD->Kind;
8402cab237bSDimitry Andric
8412cab237bSDimitry Andric // Match next level.
8422cab237bSDimitry Andric return matchPairwiseReductionAtLevel(cast<Instruction>(NextLevelOp), Level,
8432cab237bSDimitry Andric NumLevels);
8442cab237bSDimitry Andric }
8452cab237bSDimitry Andric
matchPairwiseReduction(const ExtractElementInst * ReduxRoot,unsigned & Opcode,Type * & Ty)8462cab237bSDimitry Andric static ReductionKind matchPairwiseReduction(const ExtractElementInst *ReduxRoot,
8472cab237bSDimitry Andric unsigned &Opcode, Type *&Ty) {
8482cab237bSDimitry Andric if (!EnableReduxCost)
8492cab237bSDimitry Andric return RK_None;
8502cab237bSDimitry Andric
8512cab237bSDimitry Andric // Need to extract the first element.
8522cab237bSDimitry Andric ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1));
8532cab237bSDimitry Andric unsigned Idx = ~0u;
8542cab237bSDimitry Andric if (CI)
8552cab237bSDimitry Andric Idx = CI->getZExtValue();
8562cab237bSDimitry Andric if (Idx != 0)
8572cab237bSDimitry Andric return RK_None;
8582cab237bSDimitry Andric
8592cab237bSDimitry Andric auto *RdxStart = dyn_cast<Instruction>(ReduxRoot->getOperand(0));
8602cab237bSDimitry Andric if (!RdxStart)
8612cab237bSDimitry Andric return RK_None;
8622cab237bSDimitry Andric Optional<ReductionData> RD = getReductionData(RdxStart);
8632cab237bSDimitry Andric if (!RD)
8642cab237bSDimitry Andric return RK_None;
8652cab237bSDimitry Andric
8662cab237bSDimitry Andric Type *VecTy = RdxStart->getType();
8672cab237bSDimitry Andric unsigned NumVecElems = VecTy->getVectorNumElements();
8682cab237bSDimitry Andric if (!isPowerOf2_32(NumVecElems))
8692cab237bSDimitry Andric return RK_None;
8702cab237bSDimitry Andric
8712cab237bSDimitry Andric // We look for a sequence of shuffle,shuffle,add triples like the following
8722cab237bSDimitry Andric // that builds a pairwise reduction tree.
8732cab237bSDimitry Andric //
8742cab237bSDimitry Andric // (X0, X1, X2, X3)
8752cab237bSDimitry Andric // (X0 + X1, X2 + X3, undef, undef)
8762cab237bSDimitry Andric // ((X0 + X1) + (X2 + X3), undef, undef, undef)
8772cab237bSDimitry Andric //
8782cab237bSDimitry Andric // %rdx.shuf.0.0 = shufflevector <4 x float> %rdx, <4 x float> undef,
8792cab237bSDimitry Andric // <4 x i32> <i32 0, i32 2 , i32 undef, i32 undef>
8802cab237bSDimitry Andric // %rdx.shuf.0.1 = shufflevector <4 x float> %rdx, <4 x float> undef,
8812cab237bSDimitry Andric // <4 x i32> <i32 1, i32 3, i32 undef, i32 undef>
8822cab237bSDimitry Andric // %bin.rdx.0 = fadd <4 x float> %rdx.shuf.0.0, %rdx.shuf.0.1
8832cab237bSDimitry Andric // %rdx.shuf.1.0 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef,
8842cab237bSDimitry Andric // <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
8852cab237bSDimitry Andric // %rdx.shuf.1.1 = shufflevector <4 x float> %bin.rdx.0, <4 x float> undef,
8862cab237bSDimitry Andric // <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
8872cab237bSDimitry Andric // %bin.rdx8 = fadd <4 x float> %rdx.shuf.1.0, %rdx.shuf.1.1
8882cab237bSDimitry Andric // %r = extractelement <4 x float> %bin.rdx8, i32 0
8892cab237bSDimitry Andric if (matchPairwiseReductionAtLevel(RdxStart, 0, Log2_32(NumVecElems)) ==
8902cab237bSDimitry Andric RK_None)
8912cab237bSDimitry Andric return RK_None;
8922cab237bSDimitry Andric
8932cab237bSDimitry Andric Opcode = RD->Opcode;
8942cab237bSDimitry Andric Ty = VecTy;
8952cab237bSDimitry Andric
8962cab237bSDimitry Andric return RD->Kind;
8972cab237bSDimitry Andric }
8982cab237bSDimitry Andric
8992cab237bSDimitry Andric static std::pair<Value *, ShuffleVectorInst *>
getShuffleAndOtherOprd(Value * L,Value * R)9002cab237bSDimitry Andric getShuffleAndOtherOprd(Value *L, Value *R) {
9012cab237bSDimitry Andric ShuffleVectorInst *S = nullptr;
9022cab237bSDimitry Andric
9032cab237bSDimitry Andric if ((S = dyn_cast<ShuffleVectorInst>(L)))
9042cab237bSDimitry Andric return std::make_pair(R, S);
9052cab237bSDimitry Andric
9062cab237bSDimitry Andric S = dyn_cast<ShuffleVectorInst>(R);
9072cab237bSDimitry Andric return std::make_pair(L, S);
9082cab237bSDimitry Andric }
9092cab237bSDimitry Andric
9102cab237bSDimitry Andric static ReductionKind
matchVectorSplittingReduction(const ExtractElementInst * ReduxRoot,unsigned & Opcode,Type * & Ty)9112cab237bSDimitry Andric matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot,
9122cab237bSDimitry Andric unsigned &Opcode, Type *&Ty) {
9132cab237bSDimitry Andric if (!EnableReduxCost)
9142cab237bSDimitry Andric return RK_None;
9152cab237bSDimitry Andric
9162cab237bSDimitry Andric // Need to extract the first element.
9172cab237bSDimitry Andric ConstantInt *CI = dyn_cast<ConstantInt>(ReduxRoot->getOperand(1));
9182cab237bSDimitry Andric unsigned Idx = ~0u;
9192cab237bSDimitry Andric if (CI)
9202cab237bSDimitry Andric Idx = CI->getZExtValue();
9212cab237bSDimitry Andric if (Idx != 0)
9222cab237bSDimitry Andric return RK_None;
9232cab237bSDimitry Andric
9242cab237bSDimitry Andric auto *RdxStart = dyn_cast<Instruction>(ReduxRoot->getOperand(0));
9252cab237bSDimitry Andric if (!RdxStart)
9262cab237bSDimitry Andric return RK_None;
9272cab237bSDimitry Andric Optional<ReductionData> RD = getReductionData(RdxStart);
9282cab237bSDimitry Andric if (!RD)
9292cab237bSDimitry Andric return RK_None;
9302cab237bSDimitry Andric
9312cab237bSDimitry Andric Type *VecTy = ReduxRoot->getOperand(0)->getType();
9322cab237bSDimitry Andric unsigned NumVecElems = VecTy->getVectorNumElements();
9332cab237bSDimitry Andric if (!isPowerOf2_32(NumVecElems))
9342cab237bSDimitry Andric return RK_None;
9352cab237bSDimitry Andric
9362cab237bSDimitry Andric // We look for a sequence of shuffles and adds like the following matching one
9372cab237bSDimitry Andric // fadd, shuffle vector pair at a time.
9382cab237bSDimitry Andric //
9392cab237bSDimitry Andric // %rdx.shuf = shufflevector <4 x float> %rdx, <4 x float> undef,
9402cab237bSDimitry Andric // <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
9412cab237bSDimitry Andric // %bin.rdx = fadd <4 x float> %rdx, %rdx.shuf
9422cab237bSDimitry Andric // %rdx.shuf7 = shufflevector <4 x float> %bin.rdx, <4 x float> undef,
9432cab237bSDimitry Andric // <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
9442cab237bSDimitry Andric // %bin.rdx8 = fadd <4 x float> %bin.rdx, %rdx.shuf7
9452cab237bSDimitry Andric // %r = extractelement <4 x float> %bin.rdx8, i32 0
9462cab237bSDimitry Andric
9472cab237bSDimitry Andric unsigned MaskStart = 1;
9482cab237bSDimitry Andric Instruction *RdxOp = RdxStart;
9492cab237bSDimitry Andric SmallVector<int, 32> ShuffleMask(NumVecElems, 0);
9502cab237bSDimitry Andric unsigned NumVecElemsRemain = NumVecElems;
9512cab237bSDimitry Andric while (NumVecElemsRemain - 1) {
9522cab237bSDimitry Andric // Check for the right reduction operation.
9532cab237bSDimitry Andric if (!RdxOp)
9542cab237bSDimitry Andric return RK_None;
9552cab237bSDimitry Andric Optional<ReductionData> RDLevel = getReductionData(RdxOp);
9562cab237bSDimitry Andric if (!RDLevel || !RDLevel->hasSameData(*RD))
9572cab237bSDimitry Andric return RK_None;
9582cab237bSDimitry Andric
9592cab237bSDimitry Andric Value *NextRdxOp;
9602cab237bSDimitry Andric ShuffleVectorInst *Shuffle;
9612cab237bSDimitry Andric std::tie(NextRdxOp, Shuffle) =
9622cab237bSDimitry Andric getShuffleAndOtherOprd(RDLevel->LHS, RDLevel->RHS);
9632cab237bSDimitry Andric
9642cab237bSDimitry Andric // Check the current reduction operation and the shuffle use the same value.
9652cab237bSDimitry Andric if (Shuffle == nullptr)
9662cab237bSDimitry Andric return RK_None;
9672cab237bSDimitry Andric if (Shuffle->getOperand(0) != NextRdxOp)
9682cab237bSDimitry Andric return RK_None;
9692cab237bSDimitry Andric
9702cab237bSDimitry Andric // Check that shuffle masks matches.
9712cab237bSDimitry Andric for (unsigned j = 0; j != MaskStart; ++j)
9722cab237bSDimitry Andric ShuffleMask[j] = MaskStart + j;
9732cab237bSDimitry Andric // Fill the rest of the mask with -1 for undef.
9742cab237bSDimitry Andric std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1);
9752cab237bSDimitry Andric
9762cab237bSDimitry Andric SmallVector<int, 16> Mask = Shuffle->getShuffleMask();
9772cab237bSDimitry Andric if (ShuffleMask != Mask)
9782cab237bSDimitry Andric return RK_None;
9792cab237bSDimitry Andric
9802cab237bSDimitry Andric RdxOp = dyn_cast<Instruction>(NextRdxOp);
9812cab237bSDimitry Andric NumVecElemsRemain /= 2;
9822cab237bSDimitry Andric MaskStart *= 2;
9832cab237bSDimitry Andric }
9842cab237bSDimitry Andric
9852cab237bSDimitry Andric Opcode = RD->Opcode;
9862cab237bSDimitry Andric Ty = VecTy;
9872cab237bSDimitry Andric return RD->Kind;
9882cab237bSDimitry Andric }
9892cab237bSDimitry Andric
getInstructionThroughput(const Instruction * I) const9902cab237bSDimitry Andric int TargetTransformInfo::getInstructionThroughput(const Instruction *I) const {
9912cab237bSDimitry Andric switch (I->getOpcode()) {
9922cab237bSDimitry Andric case Instruction::GetElementPtr:
9932cab237bSDimitry Andric return getUserCost(I);
9942cab237bSDimitry Andric
9952cab237bSDimitry Andric case Instruction::Ret:
9962cab237bSDimitry Andric case Instruction::PHI:
9972cab237bSDimitry Andric case Instruction::Br: {
9982cab237bSDimitry Andric return getCFInstrCost(I->getOpcode());
9992cab237bSDimitry Andric }
10002cab237bSDimitry Andric case Instruction::Add:
10012cab237bSDimitry Andric case Instruction::FAdd:
10022cab237bSDimitry Andric case Instruction::Sub:
10032cab237bSDimitry Andric case Instruction::FSub:
10042cab237bSDimitry Andric case Instruction::Mul:
10052cab237bSDimitry Andric case Instruction::FMul:
10062cab237bSDimitry Andric case Instruction::UDiv:
10072cab237bSDimitry Andric case Instruction::SDiv:
10082cab237bSDimitry Andric case Instruction::FDiv:
10092cab237bSDimitry Andric case Instruction::URem:
10102cab237bSDimitry Andric case Instruction::SRem:
10112cab237bSDimitry Andric case Instruction::FRem:
10122cab237bSDimitry Andric case Instruction::Shl:
10132cab237bSDimitry Andric case Instruction::LShr:
10142cab237bSDimitry Andric case Instruction::AShr:
10152cab237bSDimitry Andric case Instruction::And:
10162cab237bSDimitry Andric case Instruction::Or:
10172cab237bSDimitry Andric case Instruction::Xor: {
10184ba319b5SDimitry Andric TargetTransformInfo::OperandValueKind Op1VK, Op2VK;
10194ba319b5SDimitry Andric TargetTransformInfo::OperandValueProperties Op1VP, Op2VP;
10204ba319b5SDimitry Andric Op1VK = getOperandInfo(I->getOperand(0), Op1VP);
10214ba319b5SDimitry Andric Op2VK = getOperandInfo(I->getOperand(1), Op2VP);
10222cab237bSDimitry Andric SmallVector<const Value *, 2> Operands(I->operand_values());
10234ba319b5SDimitry Andric return getArithmeticInstrCost(I->getOpcode(), I->getType(), Op1VK, Op2VK,
10244ba319b5SDimitry Andric Op1VP, Op2VP, Operands);
10252cab237bSDimitry Andric }
10262cab237bSDimitry Andric case Instruction::Select: {
10272cab237bSDimitry Andric const SelectInst *SI = cast<SelectInst>(I);
10282cab237bSDimitry Andric Type *CondTy = SI->getCondition()->getType();
10292cab237bSDimitry Andric return getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy, I);
10302cab237bSDimitry Andric }
10312cab237bSDimitry Andric case Instruction::ICmp:
10322cab237bSDimitry Andric case Instruction::FCmp: {
10332cab237bSDimitry Andric Type *ValTy = I->getOperand(0)->getType();
10342cab237bSDimitry Andric return getCmpSelInstrCost(I->getOpcode(), ValTy, I->getType(), I);
10352cab237bSDimitry Andric }
10362cab237bSDimitry Andric case Instruction::Store: {
10372cab237bSDimitry Andric const StoreInst *SI = cast<StoreInst>(I);
10382cab237bSDimitry Andric Type *ValTy = SI->getValueOperand()->getType();
10392cab237bSDimitry Andric return getMemoryOpCost(I->getOpcode(), ValTy,
10402cab237bSDimitry Andric SI->getAlignment(),
10412cab237bSDimitry Andric SI->getPointerAddressSpace(), I);
10422cab237bSDimitry Andric }
10432cab237bSDimitry Andric case Instruction::Load: {
10442cab237bSDimitry Andric const LoadInst *LI = cast<LoadInst>(I);
10452cab237bSDimitry Andric return getMemoryOpCost(I->getOpcode(), I->getType(),
10462cab237bSDimitry Andric LI->getAlignment(),
10472cab237bSDimitry Andric LI->getPointerAddressSpace(), I);
10482cab237bSDimitry Andric }
10492cab237bSDimitry Andric case Instruction::ZExt:
10502cab237bSDimitry Andric case Instruction::SExt:
10512cab237bSDimitry Andric case Instruction::FPToUI:
10522cab237bSDimitry Andric case Instruction::FPToSI:
10532cab237bSDimitry Andric case Instruction::FPExt:
10542cab237bSDimitry Andric case Instruction::PtrToInt:
10552cab237bSDimitry Andric case Instruction::IntToPtr:
10562cab237bSDimitry Andric case Instruction::SIToFP:
10572cab237bSDimitry Andric case Instruction::UIToFP:
10582cab237bSDimitry Andric case Instruction::Trunc:
10592cab237bSDimitry Andric case Instruction::FPTrunc:
10602cab237bSDimitry Andric case Instruction::BitCast:
10612cab237bSDimitry Andric case Instruction::AddrSpaceCast: {
10622cab237bSDimitry Andric Type *SrcTy = I->getOperand(0)->getType();
10632cab237bSDimitry Andric return getCastInstrCost(I->getOpcode(), I->getType(), SrcTy, I);
10642cab237bSDimitry Andric }
10652cab237bSDimitry Andric case Instruction::ExtractElement: {
10662cab237bSDimitry Andric const ExtractElementInst * EEI = cast<ExtractElementInst>(I);
10672cab237bSDimitry Andric ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
10682cab237bSDimitry Andric unsigned Idx = -1;
10692cab237bSDimitry Andric if (CI)
10702cab237bSDimitry Andric Idx = CI->getZExtValue();
10712cab237bSDimitry Andric
10722cab237bSDimitry Andric // Try to match a reduction sequence (series of shufflevector and vector
10732cab237bSDimitry Andric // adds followed by a extractelement).
10742cab237bSDimitry Andric unsigned ReduxOpCode;
10752cab237bSDimitry Andric Type *ReduxType;
10762cab237bSDimitry Andric
10772cab237bSDimitry Andric switch (matchVectorSplittingReduction(EEI, ReduxOpCode, ReduxType)) {
10782cab237bSDimitry Andric case RK_Arithmetic:
10792cab237bSDimitry Andric return getArithmeticReductionCost(ReduxOpCode, ReduxType,
10802cab237bSDimitry Andric /*IsPairwiseForm=*/false);
10812cab237bSDimitry Andric case RK_MinMax:
10822cab237bSDimitry Andric return getMinMaxReductionCost(
10832cab237bSDimitry Andric ReduxType, CmpInst::makeCmpResultType(ReduxType),
10842cab237bSDimitry Andric /*IsPairwiseForm=*/false, /*IsUnsigned=*/false);
10852cab237bSDimitry Andric case RK_UnsignedMinMax:
10862cab237bSDimitry Andric return getMinMaxReductionCost(
10872cab237bSDimitry Andric ReduxType, CmpInst::makeCmpResultType(ReduxType),
10882cab237bSDimitry Andric /*IsPairwiseForm=*/false, /*IsUnsigned=*/true);
10892cab237bSDimitry Andric case RK_None:
10902cab237bSDimitry Andric break;
10912cab237bSDimitry Andric }
10922cab237bSDimitry Andric
10932cab237bSDimitry Andric switch (matchPairwiseReduction(EEI, ReduxOpCode, ReduxType)) {
10942cab237bSDimitry Andric case RK_Arithmetic:
10952cab237bSDimitry Andric return getArithmeticReductionCost(ReduxOpCode, ReduxType,
10962cab237bSDimitry Andric /*IsPairwiseForm=*/true);
10972cab237bSDimitry Andric case RK_MinMax:
10982cab237bSDimitry Andric return getMinMaxReductionCost(
10992cab237bSDimitry Andric ReduxType, CmpInst::makeCmpResultType(ReduxType),
11002cab237bSDimitry Andric /*IsPairwiseForm=*/true, /*IsUnsigned=*/false);
11012cab237bSDimitry Andric case RK_UnsignedMinMax:
11022cab237bSDimitry Andric return getMinMaxReductionCost(
11032cab237bSDimitry Andric ReduxType, CmpInst::makeCmpResultType(ReduxType),
11042cab237bSDimitry Andric /*IsPairwiseForm=*/true, /*IsUnsigned=*/true);
11052cab237bSDimitry Andric case RK_None:
11062cab237bSDimitry Andric break;
11072cab237bSDimitry Andric }
11082cab237bSDimitry Andric
11092cab237bSDimitry Andric return getVectorInstrCost(I->getOpcode(),
11102cab237bSDimitry Andric EEI->getOperand(0)->getType(), Idx);
11112cab237bSDimitry Andric }
11122cab237bSDimitry Andric case Instruction::InsertElement: {
11132cab237bSDimitry Andric const InsertElementInst * IE = cast<InsertElementInst>(I);
11142cab237bSDimitry Andric ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
11152cab237bSDimitry Andric unsigned Idx = -1;
11162cab237bSDimitry Andric if (CI)
11172cab237bSDimitry Andric Idx = CI->getZExtValue();
11182cab237bSDimitry Andric return getVectorInstrCost(I->getOpcode(),
11192cab237bSDimitry Andric IE->getType(), Idx);
11202cab237bSDimitry Andric }
11212cab237bSDimitry Andric case Instruction::ShuffleVector: {
11222cab237bSDimitry Andric const ShuffleVectorInst *Shuffle = cast<ShuffleVectorInst>(I);
1123*b5893f02SDimitry Andric Type *Ty = Shuffle->getType();
1124*b5893f02SDimitry Andric Type *SrcTy = Shuffle->getOperand(0)->getType();
1125*b5893f02SDimitry Andric
1126*b5893f02SDimitry Andric // TODO: Identify and add costs for insert subvector, etc.
1127*b5893f02SDimitry Andric int SubIndex;
1128*b5893f02SDimitry Andric if (Shuffle->isExtractSubvectorMask(SubIndex))
1129*b5893f02SDimitry Andric return TTIImpl->getShuffleCost(SK_ExtractSubvector, SrcTy, SubIndex, Ty);
1130*b5893f02SDimitry Andric
11314ba319b5SDimitry Andric if (Shuffle->changesLength())
11322cab237bSDimitry Andric return -1;
11334ba319b5SDimitry Andric
11344ba319b5SDimitry Andric if (Shuffle->isIdentity())
11354ba319b5SDimitry Andric return 0;
11364ba319b5SDimitry Andric
11374ba319b5SDimitry Andric if (Shuffle->isReverse())
11384ba319b5SDimitry Andric return TTIImpl->getShuffleCost(SK_Reverse, Ty, 0, nullptr);
11394ba319b5SDimitry Andric
11404ba319b5SDimitry Andric if (Shuffle->isSelect())
11414ba319b5SDimitry Andric return TTIImpl->getShuffleCost(SK_Select, Ty, 0, nullptr);
11424ba319b5SDimitry Andric
11434ba319b5SDimitry Andric if (Shuffle->isTranspose())
11444ba319b5SDimitry Andric return TTIImpl->getShuffleCost(SK_Transpose, Ty, 0, nullptr);
11454ba319b5SDimitry Andric
11464ba319b5SDimitry Andric if (Shuffle->isZeroEltSplat())
11474ba319b5SDimitry Andric return TTIImpl->getShuffleCost(SK_Broadcast, Ty, 0, nullptr);
11484ba319b5SDimitry Andric
11494ba319b5SDimitry Andric if (Shuffle->isSingleSource())
11504ba319b5SDimitry Andric return TTIImpl->getShuffleCost(SK_PermuteSingleSrc, Ty, 0, nullptr);
11514ba319b5SDimitry Andric
11524ba319b5SDimitry Andric return TTIImpl->getShuffleCost(SK_PermuteTwoSrc, Ty, 0, nullptr);
11532cab237bSDimitry Andric }
11542cab237bSDimitry Andric case Instruction::Call:
11552cab237bSDimitry Andric if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
11562cab237bSDimitry Andric SmallVector<Value *, 4> Args(II->arg_operands());
11572cab237bSDimitry Andric
11582cab237bSDimitry Andric FastMathFlags FMF;
11592cab237bSDimitry Andric if (auto *FPMO = dyn_cast<FPMathOperator>(II))
11602cab237bSDimitry Andric FMF = FPMO->getFastMathFlags();
11612cab237bSDimitry Andric
11622cab237bSDimitry Andric return getIntrinsicInstrCost(II->getIntrinsicID(), II->getType(),
11632cab237bSDimitry Andric Args, FMF);
11642cab237bSDimitry Andric }
11652cab237bSDimitry Andric return -1;
11662cab237bSDimitry Andric default:
11672cab237bSDimitry Andric // We don't have any information on this instruction.
11682cab237bSDimitry Andric return -1;
11692cab237bSDimitry Andric }
11702cab237bSDimitry Andric }
11712cab237bSDimitry Andric
~Concept()1172ff0cc061SDimitry Andric TargetTransformInfo::Concept::~Concept() {}
1173ff0cc061SDimitry Andric
TargetIRAnalysis()1174ff0cc061SDimitry Andric TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
1175ff0cc061SDimitry Andric
TargetIRAnalysis(std::function<Result (const Function &)> TTICallback)1176ff0cc061SDimitry Andric TargetIRAnalysis::TargetIRAnalysis(
11777d523365SDimitry Andric std::function<Result(const Function &)> TTICallback)
11783ca95b02SDimitry Andric : TTICallback(std::move(TTICallback)) {}
1179ff0cc061SDimitry Andric
run(const Function & F,FunctionAnalysisManager &)11803ca95b02SDimitry Andric TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F,
1181d88c1a5aSDimitry Andric FunctionAnalysisManager &) {
1182ff0cc061SDimitry Andric return TTICallback(F);
1183139f7f9bSDimitry Andric }
1184139f7f9bSDimitry Andric
1185d88c1a5aSDimitry Andric AnalysisKey TargetIRAnalysis::Key;
1186ff0cc061SDimitry Andric
getDefaultTTI(const Function & F)11877d523365SDimitry Andric TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) {
1188875ed548SDimitry Andric return Result(F.getParent()->getDataLayout());
1189139f7f9bSDimitry Andric }
1190139f7f9bSDimitry Andric
1191ff0cc061SDimitry Andric // Register the basic pass.
1192ff0cc061SDimitry Andric INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti",
1193ff0cc061SDimitry Andric "Target Transform Information", false, true)
1194ff0cc061SDimitry Andric char TargetTransformInfoWrapperPass::ID = 0;
1195ff0cc061SDimitry Andric
anchor()1196ff0cc061SDimitry Andric void TargetTransformInfoWrapperPass::anchor() {}
1197ff0cc061SDimitry Andric
TargetTransformInfoWrapperPass()1198ff0cc061SDimitry Andric TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass()
1199ff0cc061SDimitry Andric : ImmutablePass(ID) {
1200ff0cc061SDimitry Andric initializeTargetTransformInfoWrapperPassPass(
1201ff0cc061SDimitry Andric *PassRegistry::getPassRegistry());
1202139f7f9bSDimitry Andric }
1203139f7f9bSDimitry Andric
TargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)1204ff0cc061SDimitry Andric TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass(
1205ff0cc061SDimitry Andric TargetIRAnalysis TIRA)
1206ff0cc061SDimitry Andric : ImmutablePass(ID), TIRA(std::move(TIRA)) {
1207ff0cc061SDimitry Andric initializeTargetTransformInfoWrapperPassPass(
1208ff0cc061SDimitry Andric *PassRegistry::getPassRegistry());
1209139f7f9bSDimitry Andric }
1210139f7f9bSDimitry Andric
getTTI(const Function & F)12117d523365SDimitry Andric TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) {
1212d88c1a5aSDimitry Andric FunctionAnalysisManager DummyFAM;
12133ca95b02SDimitry Andric TTI = TIRA.run(F, DummyFAM);
1214ff0cc061SDimitry Andric return *TTI;
1215139f7f9bSDimitry Andric }
1216139f7f9bSDimitry Andric
1217ff0cc061SDimitry Andric ImmutablePass *
createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA)1218ff0cc061SDimitry Andric llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) {
1219ff0cc061SDimitry Andric return new TargetTransformInfoWrapperPass(std::move(TIRA));
1220139f7f9bSDimitry Andric }
1221