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