1139f7f9bSDimitry Andric //===- BasicTargetTransformInfo.cpp - Basic target-independent TTI impl ---===// 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 /// \file 10139f7f9bSDimitry Andric /// This file provides the implementation of a basic TargetTransformInfo pass 11139f7f9bSDimitry Andric /// predicated on the target abstractions present in the target independent 12139f7f9bSDimitry Andric /// code generator. It uses these (primarily TargetLowering) to model as much 13139f7f9bSDimitry Andric /// of the TTI query interface as possible. It is included by most targets so 14139f7f9bSDimitry Andric /// that they can specialize only a small subset of the query space. 15139f7f9bSDimitry Andric /// 16139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 17139f7f9bSDimitry Andric 18139f7f9bSDimitry Andric #define DEBUG_TYPE "basictti" 19139f7f9bSDimitry Andric #include "llvm/CodeGen/Passes.h" 20139f7f9bSDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 21139f7f9bSDimitry Andric #include "llvm/Target/TargetLowering.h" 22139f7f9bSDimitry Andric #include <utility> 23139f7f9bSDimitry Andric 24139f7f9bSDimitry Andric using namespace llvm; 25139f7f9bSDimitry Andric 26139f7f9bSDimitry Andric namespace { 27139f7f9bSDimitry Andric 28139f7f9bSDimitry Andric class BasicTTI : public ImmutablePass, public TargetTransformInfo { 29*f785676fSDimitry Andric const TargetMachine *TM; 30139f7f9bSDimitry Andric 31139f7f9bSDimitry Andric /// Estimate the overhead of scalarizing an instruction. Insert and Extract 32139f7f9bSDimitry Andric /// are set if the result needs to be inserted and/or extracted from vectors. 33139f7f9bSDimitry Andric unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const; 34139f7f9bSDimitry Andric 35*f785676fSDimitry Andric const TargetLoweringBase *getTLI() const { return TM->getTargetLowering(); } 36*f785676fSDimitry Andric 37139f7f9bSDimitry Andric public: 38*f785676fSDimitry Andric BasicTTI() : ImmutablePass(ID), TM(0) { 39139f7f9bSDimitry Andric llvm_unreachable("This pass cannot be directly constructed"); 40139f7f9bSDimitry Andric } 41139f7f9bSDimitry Andric 42*f785676fSDimitry Andric BasicTTI(const TargetMachine *TM) : ImmutablePass(ID), TM(TM) { 43139f7f9bSDimitry Andric initializeBasicTTIPass(*PassRegistry::getPassRegistry()); 44139f7f9bSDimitry Andric } 45139f7f9bSDimitry Andric 46139f7f9bSDimitry Andric virtual void initializePass() { 47139f7f9bSDimitry Andric pushTTIStack(this); 48139f7f9bSDimitry Andric } 49139f7f9bSDimitry Andric 50139f7f9bSDimitry Andric virtual void finalizePass() { 51139f7f9bSDimitry Andric popTTIStack(); 52139f7f9bSDimitry Andric } 53139f7f9bSDimitry Andric 54139f7f9bSDimitry Andric virtual void getAnalysisUsage(AnalysisUsage &AU) const { 55139f7f9bSDimitry Andric TargetTransformInfo::getAnalysisUsage(AU); 56139f7f9bSDimitry Andric } 57139f7f9bSDimitry Andric 58139f7f9bSDimitry Andric /// Pass identification. 59139f7f9bSDimitry Andric static char ID; 60139f7f9bSDimitry Andric 61139f7f9bSDimitry Andric /// Provide necessary pointer adjustments for the two base classes. 62139f7f9bSDimitry Andric virtual void *getAdjustedAnalysisPointer(const void *ID) { 63139f7f9bSDimitry Andric if (ID == &TargetTransformInfo::ID) 64139f7f9bSDimitry Andric return (TargetTransformInfo*)this; 65139f7f9bSDimitry Andric return this; 66139f7f9bSDimitry Andric } 67139f7f9bSDimitry Andric 68*f785676fSDimitry Andric virtual bool hasBranchDivergence() const; 69*f785676fSDimitry Andric 70139f7f9bSDimitry Andric /// \name Scalar TTI Implementations 71139f7f9bSDimitry Andric /// @{ 72139f7f9bSDimitry Andric 73139f7f9bSDimitry Andric virtual bool isLegalAddImmediate(int64_t imm) const; 74139f7f9bSDimitry Andric virtual bool isLegalICmpImmediate(int64_t imm) const; 75139f7f9bSDimitry Andric virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, 76139f7f9bSDimitry Andric int64_t BaseOffset, bool HasBaseReg, 77139f7f9bSDimitry Andric int64_t Scale) const; 78*f785676fSDimitry Andric virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, 79*f785676fSDimitry Andric int64_t BaseOffset, bool HasBaseReg, 80*f785676fSDimitry Andric int64_t Scale) const; 81139f7f9bSDimitry Andric virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; 82139f7f9bSDimitry Andric virtual bool isTypeLegal(Type *Ty) const; 83139f7f9bSDimitry Andric virtual unsigned getJumpBufAlignment() const; 84139f7f9bSDimitry Andric virtual unsigned getJumpBufSize() const; 85139f7f9bSDimitry Andric virtual bool shouldBuildLookupTables() const; 86*f785676fSDimitry Andric virtual bool haveFastSqrt(Type *Ty) const; 87*f785676fSDimitry Andric virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) const; 88139f7f9bSDimitry Andric 89139f7f9bSDimitry Andric /// @} 90139f7f9bSDimitry Andric 91139f7f9bSDimitry Andric /// \name Vector TTI Implementations 92139f7f9bSDimitry Andric /// @{ 93139f7f9bSDimitry Andric 94139f7f9bSDimitry Andric virtual unsigned getNumberOfRegisters(bool Vector) const; 95139f7f9bSDimitry Andric virtual unsigned getMaximumUnrollFactor() const; 96139f7f9bSDimitry Andric virtual unsigned getRegisterBitWidth(bool Vector) const; 97139f7f9bSDimitry Andric virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, 98139f7f9bSDimitry Andric OperandValueKind, 99139f7f9bSDimitry Andric OperandValueKind) const; 100139f7f9bSDimitry Andric virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, 101139f7f9bSDimitry Andric int Index, Type *SubTp) const; 102139f7f9bSDimitry Andric virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, 103139f7f9bSDimitry Andric Type *Src) const; 104139f7f9bSDimitry Andric virtual unsigned getCFInstrCost(unsigned Opcode) const; 105139f7f9bSDimitry Andric virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, 106139f7f9bSDimitry Andric Type *CondTy) const; 107139f7f9bSDimitry Andric virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, 108139f7f9bSDimitry Andric unsigned Index) const; 109139f7f9bSDimitry Andric virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, 110139f7f9bSDimitry Andric unsigned Alignment, 111139f7f9bSDimitry Andric unsigned AddressSpace) const; 112139f7f9bSDimitry Andric virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, Type *RetTy, 113139f7f9bSDimitry Andric ArrayRef<Type*> Tys) const; 114139f7f9bSDimitry Andric virtual unsigned getNumberOfParts(Type *Tp) const; 115*f785676fSDimitry Andric virtual unsigned getAddressComputationCost(Type *Ty, bool IsComplex) const; 116*f785676fSDimitry Andric virtual unsigned getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwise) const; 117139f7f9bSDimitry Andric 118139f7f9bSDimitry Andric /// @} 119139f7f9bSDimitry Andric }; 120139f7f9bSDimitry Andric 121139f7f9bSDimitry Andric } 122139f7f9bSDimitry Andric 123139f7f9bSDimitry Andric INITIALIZE_AG_PASS(BasicTTI, TargetTransformInfo, "basictti", 124139f7f9bSDimitry Andric "Target independent code generator's TTI", true, true, false) 125139f7f9bSDimitry Andric char BasicTTI::ID = 0; 126139f7f9bSDimitry Andric 127139f7f9bSDimitry Andric ImmutablePass * 128*f785676fSDimitry Andric llvm::createBasicTargetTransformInfoPass(const TargetMachine *TM) { 129*f785676fSDimitry Andric return new BasicTTI(TM); 130139f7f9bSDimitry Andric } 131139f7f9bSDimitry Andric 132*f785676fSDimitry Andric bool BasicTTI::hasBranchDivergence() const { return false; } 133139f7f9bSDimitry Andric 134139f7f9bSDimitry Andric bool BasicTTI::isLegalAddImmediate(int64_t imm) const { 135*f785676fSDimitry Andric return getTLI()->isLegalAddImmediate(imm); 136139f7f9bSDimitry Andric } 137139f7f9bSDimitry Andric 138139f7f9bSDimitry Andric bool BasicTTI::isLegalICmpImmediate(int64_t imm) const { 139*f785676fSDimitry Andric return getTLI()->isLegalICmpImmediate(imm); 140139f7f9bSDimitry Andric } 141139f7f9bSDimitry Andric 142139f7f9bSDimitry Andric bool BasicTTI::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, 143139f7f9bSDimitry Andric int64_t BaseOffset, bool HasBaseReg, 144139f7f9bSDimitry Andric int64_t Scale) const { 145139f7f9bSDimitry Andric TargetLoweringBase::AddrMode AM; 146139f7f9bSDimitry Andric AM.BaseGV = BaseGV; 147139f7f9bSDimitry Andric AM.BaseOffs = BaseOffset; 148139f7f9bSDimitry Andric AM.HasBaseReg = HasBaseReg; 149139f7f9bSDimitry Andric AM.Scale = Scale; 150*f785676fSDimitry Andric return getTLI()->isLegalAddressingMode(AM, Ty); 151*f785676fSDimitry Andric } 152*f785676fSDimitry Andric 153*f785676fSDimitry Andric int BasicTTI::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, 154*f785676fSDimitry Andric int64_t BaseOffset, bool HasBaseReg, 155*f785676fSDimitry Andric int64_t Scale) const { 156*f785676fSDimitry Andric TargetLoweringBase::AddrMode AM; 157*f785676fSDimitry Andric AM.BaseGV = BaseGV; 158*f785676fSDimitry Andric AM.BaseOffs = BaseOffset; 159*f785676fSDimitry Andric AM.HasBaseReg = HasBaseReg; 160*f785676fSDimitry Andric AM.Scale = Scale; 161*f785676fSDimitry Andric return getTLI()->getScalingFactorCost(AM, Ty); 162139f7f9bSDimitry Andric } 163139f7f9bSDimitry Andric 164139f7f9bSDimitry Andric bool BasicTTI::isTruncateFree(Type *Ty1, Type *Ty2) const { 165*f785676fSDimitry Andric return getTLI()->isTruncateFree(Ty1, Ty2); 166139f7f9bSDimitry Andric } 167139f7f9bSDimitry Andric 168139f7f9bSDimitry Andric bool BasicTTI::isTypeLegal(Type *Ty) const { 169*f785676fSDimitry Andric EVT T = getTLI()->getValueType(Ty); 170*f785676fSDimitry Andric return getTLI()->isTypeLegal(T); 171139f7f9bSDimitry Andric } 172139f7f9bSDimitry Andric 173139f7f9bSDimitry Andric unsigned BasicTTI::getJumpBufAlignment() const { 174*f785676fSDimitry Andric return getTLI()->getJumpBufAlignment(); 175139f7f9bSDimitry Andric } 176139f7f9bSDimitry Andric 177139f7f9bSDimitry Andric unsigned BasicTTI::getJumpBufSize() const { 178*f785676fSDimitry Andric return getTLI()->getJumpBufSize(); 179139f7f9bSDimitry Andric } 180139f7f9bSDimitry Andric 181139f7f9bSDimitry Andric bool BasicTTI::shouldBuildLookupTables() const { 182*f785676fSDimitry Andric const TargetLoweringBase *TLI = getTLI(); 183139f7f9bSDimitry Andric return TLI->supportJumpTables() && 184139f7f9bSDimitry Andric (TLI->isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || 185139f7f9bSDimitry Andric TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other)); 186139f7f9bSDimitry Andric } 187139f7f9bSDimitry Andric 188*f785676fSDimitry Andric bool BasicTTI::haveFastSqrt(Type *Ty) const { 189*f785676fSDimitry Andric const TargetLoweringBase *TLI = getTLI(); 190*f785676fSDimitry Andric EVT VT = TLI->getValueType(Ty); 191*f785676fSDimitry Andric return TLI->isTypeLegal(VT) && TLI->isOperationLegalOrCustom(ISD::FSQRT, VT); 192*f785676fSDimitry Andric } 193*f785676fSDimitry Andric 194*f785676fSDimitry Andric void BasicTTI::getUnrollingPreferences(Loop *, UnrollingPreferences &) const { } 195*f785676fSDimitry Andric 196139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 197139f7f9bSDimitry Andric // 198139f7f9bSDimitry Andric // Calls used by the vectorizers. 199139f7f9bSDimitry Andric // 200139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 201139f7f9bSDimitry Andric 202139f7f9bSDimitry Andric unsigned BasicTTI::getScalarizationOverhead(Type *Ty, bool Insert, 203139f7f9bSDimitry Andric bool Extract) const { 204139f7f9bSDimitry Andric assert (Ty->isVectorTy() && "Can only scalarize vectors"); 205139f7f9bSDimitry Andric unsigned Cost = 0; 206139f7f9bSDimitry Andric 207139f7f9bSDimitry Andric for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) { 208139f7f9bSDimitry Andric if (Insert) 209139f7f9bSDimitry Andric Cost += TopTTI->getVectorInstrCost(Instruction::InsertElement, Ty, i); 210139f7f9bSDimitry Andric if (Extract) 211139f7f9bSDimitry Andric Cost += TopTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, i); 212139f7f9bSDimitry Andric } 213139f7f9bSDimitry Andric 214139f7f9bSDimitry Andric return Cost; 215139f7f9bSDimitry Andric } 216139f7f9bSDimitry Andric 217139f7f9bSDimitry Andric unsigned BasicTTI::getNumberOfRegisters(bool Vector) const { 218139f7f9bSDimitry Andric return 1; 219139f7f9bSDimitry Andric } 220139f7f9bSDimitry Andric 221139f7f9bSDimitry Andric unsigned BasicTTI::getRegisterBitWidth(bool Vector) const { 222139f7f9bSDimitry Andric return 32; 223139f7f9bSDimitry Andric } 224139f7f9bSDimitry Andric 225139f7f9bSDimitry Andric unsigned BasicTTI::getMaximumUnrollFactor() const { 226139f7f9bSDimitry Andric return 1; 227139f7f9bSDimitry Andric } 228139f7f9bSDimitry Andric 229139f7f9bSDimitry Andric unsigned BasicTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty, 230139f7f9bSDimitry Andric OperandValueKind, 231139f7f9bSDimitry Andric OperandValueKind) const { 232139f7f9bSDimitry Andric // Check if any of the operands are vector operands. 233*f785676fSDimitry Andric const TargetLoweringBase *TLI = getTLI(); 234139f7f9bSDimitry Andric int ISD = TLI->InstructionOpcodeToISD(Opcode); 235139f7f9bSDimitry Andric assert(ISD && "Invalid opcode"); 236139f7f9bSDimitry Andric 237139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty); 238139f7f9bSDimitry Andric 239284c1978SDimitry Andric bool IsFloat = Ty->getScalarType()->isFloatingPointTy(); 240284c1978SDimitry Andric // Assume that floating point arithmetic operations cost twice as much as 241284c1978SDimitry Andric // integer operations. 242284c1978SDimitry Andric unsigned OpCost = (IsFloat ? 2 : 1); 243284c1978SDimitry Andric 244139f7f9bSDimitry Andric if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { 245139f7f9bSDimitry Andric // The operation is legal. Assume it costs 1. 246284c1978SDimitry Andric // If the type is split to multiple registers, assume that there is some 247139f7f9bSDimitry Andric // overhead to this. 248139f7f9bSDimitry Andric // TODO: Once we have extract/insert subvector cost we need to use them. 249139f7f9bSDimitry Andric if (LT.first > 1) 250284c1978SDimitry Andric return LT.first * 2 * OpCost; 251284c1978SDimitry Andric return LT.first * 1 * OpCost; 252139f7f9bSDimitry Andric } 253139f7f9bSDimitry Andric 254139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, LT.second)) { 255139f7f9bSDimitry Andric // If the operation is custom lowered then assume 256139f7f9bSDimitry Andric // thare the code is twice as expensive. 257284c1978SDimitry Andric return LT.first * 2 * OpCost; 258139f7f9bSDimitry Andric } 259139f7f9bSDimitry Andric 260139f7f9bSDimitry Andric // Else, assume that we need to scalarize this op. 261139f7f9bSDimitry Andric if (Ty->isVectorTy()) { 262139f7f9bSDimitry Andric unsigned Num = Ty->getVectorNumElements(); 263139f7f9bSDimitry Andric unsigned Cost = TopTTI->getArithmeticInstrCost(Opcode, Ty->getScalarType()); 264139f7f9bSDimitry Andric // return the cost of multiple scalar invocation plus the cost of inserting 265139f7f9bSDimitry Andric // and extracting the values. 266139f7f9bSDimitry Andric return getScalarizationOverhead(Ty, true, true) + Num * Cost; 267139f7f9bSDimitry Andric } 268139f7f9bSDimitry Andric 269139f7f9bSDimitry Andric // We don't know anything about this scalar instruction. 270284c1978SDimitry Andric return OpCost; 271139f7f9bSDimitry Andric } 272139f7f9bSDimitry Andric 273139f7f9bSDimitry Andric unsigned BasicTTI::getShuffleCost(ShuffleKind Kind, Type *Tp, int Index, 274139f7f9bSDimitry Andric Type *SubTp) const { 275139f7f9bSDimitry Andric return 1; 276139f7f9bSDimitry Andric } 277139f7f9bSDimitry Andric 278139f7f9bSDimitry Andric unsigned BasicTTI::getCastInstrCost(unsigned Opcode, Type *Dst, 279139f7f9bSDimitry Andric Type *Src) const { 280*f785676fSDimitry Andric const TargetLoweringBase *TLI = getTLI(); 281139f7f9bSDimitry Andric int ISD = TLI->InstructionOpcodeToISD(Opcode); 282139f7f9bSDimitry Andric assert(ISD && "Invalid opcode"); 283139f7f9bSDimitry Andric 284139f7f9bSDimitry Andric std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(Src); 285139f7f9bSDimitry Andric std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(Dst); 286139f7f9bSDimitry Andric 287139f7f9bSDimitry Andric // Check for NOOP conversions. 288139f7f9bSDimitry Andric if (SrcLT.first == DstLT.first && 289139f7f9bSDimitry Andric SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { 290139f7f9bSDimitry Andric 291139f7f9bSDimitry Andric // Bitcast between types that are legalized to the same type are free. 292139f7f9bSDimitry Andric if (Opcode == Instruction::BitCast || Opcode == Instruction::Trunc) 293139f7f9bSDimitry Andric return 0; 294139f7f9bSDimitry Andric } 295139f7f9bSDimitry Andric 296139f7f9bSDimitry Andric if (Opcode == Instruction::Trunc && 297139f7f9bSDimitry Andric TLI->isTruncateFree(SrcLT.second, DstLT.second)) 298139f7f9bSDimitry Andric return 0; 299139f7f9bSDimitry Andric 300139f7f9bSDimitry Andric if (Opcode == Instruction::ZExt && 301139f7f9bSDimitry Andric TLI->isZExtFree(SrcLT.second, DstLT.second)) 302139f7f9bSDimitry Andric return 0; 303139f7f9bSDimitry Andric 304139f7f9bSDimitry Andric // If the cast is marked as legal (or promote) then assume low cost. 305139f7f9bSDimitry Andric if (TLI->isOperationLegalOrPromote(ISD, DstLT.second)) 306139f7f9bSDimitry Andric return 1; 307139f7f9bSDimitry Andric 308139f7f9bSDimitry Andric // Handle scalar conversions. 309139f7f9bSDimitry Andric if (!Src->isVectorTy() && !Dst->isVectorTy()) { 310139f7f9bSDimitry Andric 311139f7f9bSDimitry Andric // Scalar bitcasts are usually free. 312139f7f9bSDimitry Andric if (Opcode == Instruction::BitCast) 313139f7f9bSDimitry Andric return 0; 314139f7f9bSDimitry Andric 315139f7f9bSDimitry Andric // Just check the op cost. If the operation is legal then assume it costs 1. 316139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, DstLT.second)) 317139f7f9bSDimitry Andric return 1; 318139f7f9bSDimitry Andric 319139f7f9bSDimitry Andric // Assume that illegal scalar instruction are expensive. 320139f7f9bSDimitry Andric return 4; 321139f7f9bSDimitry Andric } 322139f7f9bSDimitry Andric 323139f7f9bSDimitry Andric // Check vector-to-vector casts. 324139f7f9bSDimitry Andric if (Dst->isVectorTy() && Src->isVectorTy()) { 325139f7f9bSDimitry Andric 326139f7f9bSDimitry Andric // If the cast is between same-sized registers, then the check is simple. 327139f7f9bSDimitry Andric if (SrcLT.first == DstLT.first && 328139f7f9bSDimitry Andric SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { 329139f7f9bSDimitry Andric 330139f7f9bSDimitry Andric // Assume that Zext is done using AND. 331139f7f9bSDimitry Andric if (Opcode == Instruction::ZExt) 332139f7f9bSDimitry Andric return 1; 333139f7f9bSDimitry Andric 334139f7f9bSDimitry Andric // Assume that sext is done using SHL and SRA. 335139f7f9bSDimitry Andric if (Opcode == Instruction::SExt) 336139f7f9bSDimitry Andric return 2; 337139f7f9bSDimitry Andric 338139f7f9bSDimitry Andric // Just check the op cost. If the operation is legal then assume it costs 339139f7f9bSDimitry Andric // 1 and multiply by the type-legalization overhead. 340139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, DstLT.second)) 341139f7f9bSDimitry Andric return SrcLT.first * 1; 342139f7f9bSDimitry Andric } 343139f7f9bSDimitry Andric 344139f7f9bSDimitry Andric // If we are converting vectors and the operation is illegal, or 345139f7f9bSDimitry Andric // if the vectors are legalized to different types, estimate the 346139f7f9bSDimitry Andric // scalarization costs. 347139f7f9bSDimitry Andric unsigned Num = Dst->getVectorNumElements(); 348139f7f9bSDimitry Andric unsigned Cost = TopTTI->getCastInstrCost(Opcode, Dst->getScalarType(), 349139f7f9bSDimitry Andric Src->getScalarType()); 350139f7f9bSDimitry Andric 351139f7f9bSDimitry Andric // Return the cost of multiple scalar invocation plus the cost of 352139f7f9bSDimitry Andric // inserting and extracting the values. 353139f7f9bSDimitry Andric return getScalarizationOverhead(Dst, true, true) + Num * Cost; 354139f7f9bSDimitry Andric } 355139f7f9bSDimitry Andric 356139f7f9bSDimitry Andric // We already handled vector-to-vector and scalar-to-scalar conversions. This 357139f7f9bSDimitry Andric // is where we handle bitcast between vectors and scalars. We need to assume 358139f7f9bSDimitry Andric // that the conversion is scalarized in one way or another. 359139f7f9bSDimitry Andric if (Opcode == Instruction::BitCast) 360139f7f9bSDimitry Andric // Illegal bitcasts are done by storing and loading from a stack slot. 361139f7f9bSDimitry Andric return (Src->isVectorTy()? getScalarizationOverhead(Src, false, true):0) + 362139f7f9bSDimitry Andric (Dst->isVectorTy()? getScalarizationOverhead(Dst, true, false):0); 363139f7f9bSDimitry Andric 364139f7f9bSDimitry Andric llvm_unreachable("Unhandled cast"); 365139f7f9bSDimitry Andric } 366139f7f9bSDimitry Andric 367139f7f9bSDimitry Andric unsigned BasicTTI::getCFInstrCost(unsigned Opcode) const { 368139f7f9bSDimitry Andric // Branches are assumed to be predicted. 369139f7f9bSDimitry Andric return 0; 370139f7f9bSDimitry Andric } 371139f7f9bSDimitry Andric 372139f7f9bSDimitry Andric unsigned BasicTTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, 373139f7f9bSDimitry Andric Type *CondTy) const { 374*f785676fSDimitry Andric const TargetLoweringBase *TLI = getTLI(); 375139f7f9bSDimitry Andric int ISD = TLI->InstructionOpcodeToISD(Opcode); 376139f7f9bSDimitry Andric assert(ISD && "Invalid opcode"); 377139f7f9bSDimitry Andric 378139f7f9bSDimitry Andric // Selects on vectors are actually vector selects. 379139f7f9bSDimitry Andric if (ISD == ISD::SELECT) { 380139f7f9bSDimitry Andric assert(CondTy && "CondTy must exist"); 381139f7f9bSDimitry Andric if (CondTy->isVectorTy()) 382139f7f9bSDimitry Andric ISD = ISD::VSELECT; 383139f7f9bSDimitry Andric } 384139f7f9bSDimitry Andric 385139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(ValTy); 386139f7f9bSDimitry Andric 387139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, LT.second)) { 388139f7f9bSDimitry Andric // The operation is legal. Assume it costs 1. Multiply 389139f7f9bSDimitry Andric // by the type-legalization overhead. 390139f7f9bSDimitry Andric return LT.first * 1; 391139f7f9bSDimitry Andric } 392139f7f9bSDimitry Andric 393139f7f9bSDimitry Andric // Otherwise, assume that the cast is scalarized. 394139f7f9bSDimitry Andric if (ValTy->isVectorTy()) { 395139f7f9bSDimitry Andric unsigned Num = ValTy->getVectorNumElements(); 396139f7f9bSDimitry Andric if (CondTy) 397139f7f9bSDimitry Andric CondTy = CondTy->getScalarType(); 398139f7f9bSDimitry Andric unsigned Cost = TopTTI->getCmpSelInstrCost(Opcode, ValTy->getScalarType(), 399139f7f9bSDimitry Andric CondTy); 400139f7f9bSDimitry Andric 401139f7f9bSDimitry Andric // Return the cost of multiple scalar invocation plus the cost of inserting 402139f7f9bSDimitry Andric // and extracting the values. 403139f7f9bSDimitry Andric return getScalarizationOverhead(ValTy, true, false) + Num * Cost; 404139f7f9bSDimitry Andric } 405139f7f9bSDimitry Andric 406139f7f9bSDimitry Andric // Unknown scalar opcode. 407139f7f9bSDimitry Andric return 1; 408139f7f9bSDimitry Andric } 409139f7f9bSDimitry Andric 410139f7f9bSDimitry Andric unsigned BasicTTI::getVectorInstrCost(unsigned Opcode, Type *Val, 411139f7f9bSDimitry Andric unsigned Index) const { 412139f7f9bSDimitry Andric return 1; 413139f7f9bSDimitry Andric } 414139f7f9bSDimitry Andric 415139f7f9bSDimitry Andric unsigned BasicTTI::getMemoryOpCost(unsigned Opcode, Type *Src, 416139f7f9bSDimitry Andric unsigned Alignment, 417139f7f9bSDimitry Andric unsigned AddressSpace) const { 418139f7f9bSDimitry Andric assert(!Src->isVoidTy() && "Invalid type"); 419*f785676fSDimitry Andric std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Src); 420139f7f9bSDimitry Andric 421139f7f9bSDimitry Andric // Assume that all loads of legal types cost 1. 422139f7f9bSDimitry Andric return LT.first; 423139f7f9bSDimitry Andric } 424139f7f9bSDimitry Andric 425139f7f9bSDimitry Andric unsigned BasicTTI::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, 426139f7f9bSDimitry Andric ArrayRef<Type *> Tys) const { 427139f7f9bSDimitry Andric unsigned ISD = 0; 428139f7f9bSDimitry Andric switch (IID) { 429139f7f9bSDimitry Andric default: { 430139f7f9bSDimitry Andric // Assume that we need to scalarize this intrinsic. 431139f7f9bSDimitry Andric unsigned ScalarizationCost = 0; 432139f7f9bSDimitry Andric unsigned ScalarCalls = 1; 433139f7f9bSDimitry Andric if (RetTy->isVectorTy()) { 434139f7f9bSDimitry Andric ScalarizationCost = getScalarizationOverhead(RetTy, true, false); 435139f7f9bSDimitry Andric ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); 436139f7f9bSDimitry Andric } 437139f7f9bSDimitry Andric for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { 438139f7f9bSDimitry Andric if (Tys[i]->isVectorTy()) { 439139f7f9bSDimitry Andric ScalarizationCost += getScalarizationOverhead(Tys[i], false, true); 440139f7f9bSDimitry Andric ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); 441139f7f9bSDimitry Andric } 442139f7f9bSDimitry Andric } 443139f7f9bSDimitry Andric 444139f7f9bSDimitry Andric return ScalarCalls + ScalarizationCost; 445139f7f9bSDimitry Andric } 446139f7f9bSDimitry Andric // Look for intrinsics that can be lowered directly or turned into a scalar 447139f7f9bSDimitry Andric // intrinsic call. 448139f7f9bSDimitry Andric case Intrinsic::sqrt: ISD = ISD::FSQRT; break; 449139f7f9bSDimitry Andric case Intrinsic::sin: ISD = ISD::FSIN; break; 450139f7f9bSDimitry Andric case Intrinsic::cos: ISD = ISD::FCOS; break; 451139f7f9bSDimitry Andric case Intrinsic::exp: ISD = ISD::FEXP; break; 452139f7f9bSDimitry Andric case Intrinsic::exp2: ISD = ISD::FEXP2; break; 453139f7f9bSDimitry Andric case Intrinsic::log: ISD = ISD::FLOG; break; 454139f7f9bSDimitry Andric case Intrinsic::log10: ISD = ISD::FLOG10; break; 455139f7f9bSDimitry Andric case Intrinsic::log2: ISD = ISD::FLOG2; break; 456139f7f9bSDimitry Andric case Intrinsic::fabs: ISD = ISD::FABS; break; 457*f785676fSDimitry Andric case Intrinsic::copysign: ISD = ISD::FCOPYSIGN; break; 458139f7f9bSDimitry Andric case Intrinsic::floor: ISD = ISD::FFLOOR; break; 459139f7f9bSDimitry Andric case Intrinsic::ceil: ISD = ISD::FCEIL; break; 460139f7f9bSDimitry Andric case Intrinsic::trunc: ISD = ISD::FTRUNC; break; 461*f785676fSDimitry Andric case Intrinsic::nearbyint: 462*f785676fSDimitry Andric ISD = ISD::FNEARBYINT; break; 463139f7f9bSDimitry Andric case Intrinsic::rint: ISD = ISD::FRINT; break; 464*f785676fSDimitry Andric case Intrinsic::round: ISD = ISD::FROUND; break; 465139f7f9bSDimitry Andric case Intrinsic::pow: ISD = ISD::FPOW; break; 466139f7f9bSDimitry Andric case Intrinsic::fma: ISD = ISD::FMA; break; 467139f7f9bSDimitry Andric case Intrinsic::fmuladd: ISD = ISD::FMA; break; // FIXME: mul + add? 468*f785676fSDimitry Andric case Intrinsic::lifetime_start: 469*f785676fSDimitry Andric case Intrinsic::lifetime_end: 470*f785676fSDimitry Andric return 0; 471139f7f9bSDimitry Andric } 472139f7f9bSDimitry Andric 473*f785676fSDimitry Andric const TargetLoweringBase *TLI = getTLI(); 474139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(RetTy); 475139f7f9bSDimitry Andric 476139f7f9bSDimitry Andric if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { 477139f7f9bSDimitry Andric // The operation is legal. Assume it costs 1. 478139f7f9bSDimitry Andric // If the type is split to multiple registers, assume that thre is some 479139f7f9bSDimitry Andric // overhead to this. 480139f7f9bSDimitry Andric // TODO: Once we have extract/insert subvector cost we need to use them. 481139f7f9bSDimitry Andric if (LT.first > 1) 482139f7f9bSDimitry Andric return LT.first * 2; 483139f7f9bSDimitry Andric return LT.first * 1; 484139f7f9bSDimitry Andric } 485139f7f9bSDimitry Andric 486139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, LT.second)) { 487139f7f9bSDimitry Andric // If the operation is custom lowered then assume 488139f7f9bSDimitry Andric // thare the code is twice as expensive. 489139f7f9bSDimitry Andric return LT.first * 2; 490139f7f9bSDimitry Andric } 491139f7f9bSDimitry Andric 492139f7f9bSDimitry Andric // Else, assume that we need to scalarize this intrinsic. For math builtins 493139f7f9bSDimitry Andric // this will emit a costly libcall, adding call overhead and spills. Make it 494139f7f9bSDimitry Andric // very expensive. 495139f7f9bSDimitry Andric if (RetTy->isVectorTy()) { 496139f7f9bSDimitry Andric unsigned Num = RetTy->getVectorNumElements(); 497139f7f9bSDimitry Andric unsigned Cost = TopTTI->getIntrinsicInstrCost(IID, RetTy->getScalarType(), 498139f7f9bSDimitry Andric Tys); 499139f7f9bSDimitry Andric return 10 * Cost * Num; 500139f7f9bSDimitry Andric } 501139f7f9bSDimitry Andric 502139f7f9bSDimitry Andric // This is going to be turned into a library call, make it expensive. 503139f7f9bSDimitry Andric return 10; 504139f7f9bSDimitry Andric } 505139f7f9bSDimitry Andric 506139f7f9bSDimitry Andric unsigned BasicTTI::getNumberOfParts(Type *Tp) const { 507*f785676fSDimitry Andric std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp); 508139f7f9bSDimitry Andric return LT.first; 509139f7f9bSDimitry Andric } 510139f7f9bSDimitry Andric 511*f785676fSDimitry Andric unsigned BasicTTI::getAddressComputationCost(Type *Ty, bool IsComplex) const { 512139f7f9bSDimitry Andric return 0; 513139f7f9bSDimitry Andric } 514*f785676fSDimitry Andric 515*f785676fSDimitry Andric unsigned BasicTTI::getReductionCost(unsigned Opcode, Type *Ty, 516*f785676fSDimitry Andric bool IsPairwise) const { 517*f785676fSDimitry Andric assert(Ty->isVectorTy() && "Expect a vector type"); 518*f785676fSDimitry Andric unsigned NumVecElts = Ty->getVectorNumElements(); 519*f785676fSDimitry Andric unsigned NumReduxLevels = Log2_32(NumVecElts); 520*f785676fSDimitry Andric unsigned ArithCost = NumReduxLevels * 521*f785676fSDimitry Andric TopTTI->getArithmeticInstrCost(Opcode, Ty); 522*f785676fSDimitry Andric // Assume the pairwise shuffles add a cost. 523*f785676fSDimitry Andric unsigned ShuffleCost = 524*f785676fSDimitry Andric NumReduxLevels * (IsPairwise + 1) * 525*f785676fSDimitry Andric TopTTI->getShuffleCost(SK_ExtractSubvector, Ty, NumVecElts / 2, Ty); 526*f785676fSDimitry Andric return ShuffleCost + ArithCost + getScalarizationOverhead(Ty, false, true); 527*f785676fSDimitry Andric } 528