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 { 29139f7f9bSDimitry Andric const TargetLoweringBase *TLI; 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 35139f7f9bSDimitry Andric public: 36139f7f9bSDimitry Andric BasicTTI() : ImmutablePass(ID), TLI(0) { 37139f7f9bSDimitry Andric llvm_unreachable("This pass cannot be directly constructed"); 38139f7f9bSDimitry Andric } 39139f7f9bSDimitry Andric 40139f7f9bSDimitry Andric BasicTTI(const TargetLoweringBase *TLI) : ImmutablePass(ID), TLI(TLI) { 41139f7f9bSDimitry Andric initializeBasicTTIPass(*PassRegistry::getPassRegistry()); 42139f7f9bSDimitry Andric } 43139f7f9bSDimitry Andric 44139f7f9bSDimitry Andric virtual void initializePass() { 45139f7f9bSDimitry Andric pushTTIStack(this); 46139f7f9bSDimitry Andric } 47139f7f9bSDimitry Andric 48139f7f9bSDimitry Andric virtual void finalizePass() { 49139f7f9bSDimitry Andric popTTIStack(); 50139f7f9bSDimitry Andric } 51139f7f9bSDimitry Andric 52139f7f9bSDimitry Andric virtual void getAnalysisUsage(AnalysisUsage &AU) const { 53139f7f9bSDimitry Andric TargetTransformInfo::getAnalysisUsage(AU); 54139f7f9bSDimitry Andric } 55139f7f9bSDimitry Andric 56139f7f9bSDimitry Andric /// Pass identification. 57139f7f9bSDimitry Andric static char ID; 58139f7f9bSDimitry Andric 59139f7f9bSDimitry Andric /// Provide necessary pointer adjustments for the two base classes. 60139f7f9bSDimitry Andric virtual void *getAdjustedAnalysisPointer(const void *ID) { 61139f7f9bSDimitry Andric if (ID == &TargetTransformInfo::ID) 62139f7f9bSDimitry Andric return (TargetTransformInfo*)this; 63139f7f9bSDimitry Andric return this; 64139f7f9bSDimitry Andric } 65139f7f9bSDimitry Andric 66139f7f9bSDimitry Andric /// \name Scalar TTI Implementations 67139f7f9bSDimitry Andric /// @{ 68139f7f9bSDimitry Andric 69139f7f9bSDimitry Andric virtual bool isLegalAddImmediate(int64_t imm) const; 70139f7f9bSDimitry Andric virtual bool isLegalICmpImmediate(int64_t imm) const; 71139f7f9bSDimitry Andric virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, 72139f7f9bSDimitry Andric int64_t BaseOffset, bool HasBaseReg, 73139f7f9bSDimitry Andric int64_t Scale) const; 74139f7f9bSDimitry Andric virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; 75139f7f9bSDimitry Andric virtual bool isTypeLegal(Type *Ty) const; 76139f7f9bSDimitry Andric virtual unsigned getJumpBufAlignment() const; 77139f7f9bSDimitry Andric virtual unsigned getJumpBufSize() const; 78139f7f9bSDimitry Andric virtual bool shouldBuildLookupTables() const; 79139f7f9bSDimitry Andric 80139f7f9bSDimitry Andric /// @} 81139f7f9bSDimitry Andric 82139f7f9bSDimitry Andric /// \name Vector TTI Implementations 83139f7f9bSDimitry Andric /// @{ 84139f7f9bSDimitry Andric 85139f7f9bSDimitry Andric virtual unsigned getNumberOfRegisters(bool Vector) const; 86139f7f9bSDimitry Andric virtual unsigned getMaximumUnrollFactor() const; 87139f7f9bSDimitry Andric virtual unsigned getRegisterBitWidth(bool Vector) const; 88139f7f9bSDimitry Andric virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, 89139f7f9bSDimitry Andric OperandValueKind, 90139f7f9bSDimitry Andric OperandValueKind) const; 91139f7f9bSDimitry Andric virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, 92139f7f9bSDimitry Andric int Index, Type *SubTp) const; 93139f7f9bSDimitry Andric virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, 94139f7f9bSDimitry Andric Type *Src) const; 95139f7f9bSDimitry Andric virtual unsigned getCFInstrCost(unsigned Opcode) const; 96139f7f9bSDimitry Andric virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, 97139f7f9bSDimitry Andric Type *CondTy) const; 98139f7f9bSDimitry Andric virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, 99139f7f9bSDimitry Andric unsigned Index) const; 100139f7f9bSDimitry Andric virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, 101139f7f9bSDimitry Andric unsigned Alignment, 102139f7f9bSDimitry Andric unsigned AddressSpace) const; 103139f7f9bSDimitry Andric virtual unsigned getIntrinsicInstrCost(Intrinsic::ID, Type *RetTy, 104139f7f9bSDimitry Andric ArrayRef<Type*> Tys) const; 105139f7f9bSDimitry Andric virtual unsigned getNumberOfParts(Type *Tp) const; 106139f7f9bSDimitry Andric virtual unsigned getAddressComputationCost(Type *Ty) const; 107139f7f9bSDimitry Andric 108139f7f9bSDimitry Andric /// @} 109139f7f9bSDimitry Andric }; 110139f7f9bSDimitry Andric 111139f7f9bSDimitry Andric } 112139f7f9bSDimitry Andric 113139f7f9bSDimitry Andric INITIALIZE_AG_PASS(BasicTTI, TargetTransformInfo, "basictti", 114139f7f9bSDimitry Andric "Target independent code generator's TTI", true, true, false) 115139f7f9bSDimitry Andric char BasicTTI::ID = 0; 116139f7f9bSDimitry Andric 117139f7f9bSDimitry Andric ImmutablePass * 118139f7f9bSDimitry Andric llvm::createBasicTargetTransformInfoPass(const TargetLoweringBase *TLI) { 119139f7f9bSDimitry Andric return new BasicTTI(TLI); 120139f7f9bSDimitry Andric } 121139f7f9bSDimitry Andric 122139f7f9bSDimitry Andric 123139f7f9bSDimitry Andric bool BasicTTI::isLegalAddImmediate(int64_t imm) const { 124139f7f9bSDimitry Andric return TLI->isLegalAddImmediate(imm); 125139f7f9bSDimitry Andric } 126139f7f9bSDimitry Andric 127139f7f9bSDimitry Andric bool BasicTTI::isLegalICmpImmediate(int64_t imm) const { 128139f7f9bSDimitry Andric return TLI->isLegalICmpImmediate(imm); 129139f7f9bSDimitry Andric } 130139f7f9bSDimitry Andric 131139f7f9bSDimitry Andric bool BasicTTI::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, 132139f7f9bSDimitry Andric int64_t BaseOffset, bool HasBaseReg, 133139f7f9bSDimitry Andric int64_t Scale) const { 134139f7f9bSDimitry Andric TargetLoweringBase::AddrMode AM; 135139f7f9bSDimitry Andric AM.BaseGV = BaseGV; 136139f7f9bSDimitry Andric AM.BaseOffs = BaseOffset; 137139f7f9bSDimitry Andric AM.HasBaseReg = HasBaseReg; 138139f7f9bSDimitry Andric AM.Scale = Scale; 139139f7f9bSDimitry Andric return TLI->isLegalAddressingMode(AM, Ty); 140139f7f9bSDimitry Andric } 141139f7f9bSDimitry Andric 142139f7f9bSDimitry Andric bool BasicTTI::isTruncateFree(Type *Ty1, Type *Ty2) const { 143139f7f9bSDimitry Andric return TLI->isTruncateFree(Ty1, Ty2); 144139f7f9bSDimitry Andric } 145139f7f9bSDimitry Andric 146139f7f9bSDimitry Andric bool BasicTTI::isTypeLegal(Type *Ty) const { 147139f7f9bSDimitry Andric EVT T = TLI->getValueType(Ty); 148139f7f9bSDimitry Andric return TLI->isTypeLegal(T); 149139f7f9bSDimitry Andric } 150139f7f9bSDimitry Andric 151139f7f9bSDimitry Andric unsigned BasicTTI::getJumpBufAlignment() const { 152139f7f9bSDimitry Andric return TLI->getJumpBufAlignment(); 153139f7f9bSDimitry Andric } 154139f7f9bSDimitry Andric 155139f7f9bSDimitry Andric unsigned BasicTTI::getJumpBufSize() const { 156139f7f9bSDimitry Andric return TLI->getJumpBufSize(); 157139f7f9bSDimitry Andric } 158139f7f9bSDimitry Andric 159139f7f9bSDimitry Andric bool BasicTTI::shouldBuildLookupTables() const { 160139f7f9bSDimitry Andric return TLI->supportJumpTables() && 161139f7f9bSDimitry Andric (TLI->isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || 162139f7f9bSDimitry Andric TLI->isOperationLegalOrCustom(ISD::BRIND, MVT::Other)); 163139f7f9bSDimitry Andric } 164139f7f9bSDimitry Andric 165139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 166139f7f9bSDimitry Andric // 167139f7f9bSDimitry Andric // Calls used by the vectorizers. 168139f7f9bSDimitry Andric // 169139f7f9bSDimitry Andric //===----------------------------------------------------------------------===// 170139f7f9bSDimitry Andric 171139f7f9bSDimitry Andric unsigned BasicTTI::getScalarizationOverhead(Type *Ty, bool Insert, 172139f7f9bSDimitry Andric bool Extract) const { 173139f7f9bSDimitry Andric assert (Ty->isVectorTy() && "Can only scalarize vectors"); 174139f7f9bSDimitry Andric unsigned Cost = 0; 175139f7f9bSDimitry Andric 176139f7f9bSDimitry Andric for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) { 177139f7f9bSDimitry Andric if (Insert) 178139f7f9bSDimitry Andric Cost += TopTTI->getVectorInstrCost(Instruction::InsertElement, Ty, i); 179139f7f9bSDimitry Andric if (Extract) 180139f7f9bSDimitry Andric Cost += TopTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, i); 181139f7f9bSDimitry Andric } 182139f7f9bSDimitry Andric 183139f7f9bSDimitry Andric return Cost; 184139f7f9bSDimitry Andric } 185139f7f9bSDimitry Andric 186139f7f9bSDimitry Andric unsigned BasicTTI::getNumberOfRegisters(bool Vector) const { 187139f7f9bSDimitry Andric return 1; 188139f7f9bSDimitry Andric } 189139f7f9bSDimitry Andric 190139f7f9bSDimitry Andric unsigned BasicTTI::getRegisterBitWidth(bool Vector) const { 191139f7f9bSDimitry Andric return 32; 192139f7f9bSDimitry Andric } 193139f7f9bSDimitry Andric 194139f7f9bSDimitry Andric unsigned BasicTTI::getMaximumUnrollFactor() const { 195139f7f9bSDimitry Andric return 1; 196139f7f9bSDimitry Andric } 197139f7f9bSDimitry Andric 198139f7f9bSDimitry Andric unsigned BasicTTI::getArithmeticInstrCost(unsigned Opcode, Type *Ty, 199139f7f9bSDimitry Andric OperandValueKind, 200139f7f9bSDimitry Andric OperandValueKind) const { 201139f7f9bSDimitry Andric // Check if any of the operands are vector operands. 202139f7f9bSDimitry Andric int ISD = TLI->InstructionOpcodeToISD(Opcode); 203139f7f9bSDimitry Andric assert(ISD && "Invalid opcode"); 204139f7f9bSDimitry Andric 205139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Ty); 206139f7f9bSDimitry Andric 207*284c1978SDimitry Andric bool IsFloat = Ty->getScalarType()->isFloatingPointTy(); 208*284c1978SDimitry Andric // Assume that floating point arithmetic operations cost twice as much as 209*284c1978SDimitry Andric // integer operations. 210*284c1978SDimitry Andric unsigned OpCost = (IsFloat ? 2 : 1); 211*284c1978SDimitry Andric 212139f7f9bSDimitry Andric if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { 213139f7f9bSDimitry Andric // The operation is legal. Assume it costs 1. 214*284c1978SDimitry Andric // If the type is split to multiple registers, assume that there is some 215139f7f9bSDimitry Andric // overhead to this. 216139f7f9bSDimitry Andric // TODO: Once we have extract/insert subvector cost we need to use them. 217139f7f9bSDimitry Andric if (LT.first > 1) 218*284c1978SDimitry Andric return LT.first * 2 * OpCost; 219*284c1978SDimitry Andric return LT.first * 1 * OpCost; 220139f7f9bSDimitry Andric } 221139f7f9bSDimitry Andric 222139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, LT.second)) { 223139f7f9bSDimitry Andric // If the operation is custom lowered then assume 224139f7f9bSDimitry Andric // thare the code is twice as expensive. 225*284c1978SDimitry Andric return LT.first * 2 * OpCost; 226139f7f9bSDimitry Andric } 227139f7f9bSDimitry Andric 228139f7f9bSDimitry Andric // Else, assume that we need to scalarize this op. 229139f7f9bSDimitry Andric if (Ty->isVectorTy()) { 230139f7f9bSDimitry Andric unsigned Num = Ty->getVectorNumElements(); 231139f7f9bSDimitry Andric unsigned Cost = TopTTI->getArithmeticInstrCost(Opcode, Ty->getScalarType()); 232139f7f9bSDimitry Andric // return the cost of multiple scalar invocation plus the cost of inserting 233139f7f9bSDimitry Andric // and extracting the values. 234139f7f9bSDimitry Andric return getScalarizationOverhead(Ty, true, true) + Num * Cost; 235139f7f9bSDimitry Andric } 236139f7f9bSDimitry Andric 237139f7f9bSDimitry Andric // We don't know anything about this scalar instruction. 238*284c1978SDimitry Andric return OpCost; 239139f7f9bSDimitry Andric } 240139f7f9bSDimitry Andric 241139f7f9bSDimitry Andric unsigned BasicTTI::getShuffleCost(ShuffleKind Kind, Type *Tp, int Index, 242139f7f9bSDimitry Andric Type *SubTp) const { 243139f7f9bSDimitry Andric return 1; 244139f7f9bSDimitry Andric } 245139f7f9bSDimitry Andric 246139f7f9bSDimitry Andric unsigned BasicTTI::getCastInstrCost(unsigned Opcode, Type *Dst, 247139f7f9bSDimitry Andric Type *Src) const { 248139f7f9bSDimitry Andric int ISD = TLI->InstructionOpcodeToISD(Opcode); 249139f7f9bSDimitry Andric assert(ISD && "Invalid opcode"); 250139f7f9bSDimitry Andric 251139f7f9bSDimitry Andric std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(Src); 252139f7f9bSDimitry Andric std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(Dst); 253139f7f9bSDimitry Andric 254139f7f9bSDimitry Andric // Check for NOOP conversions. 255139f7f9bSDimitry Andric if (SrcLT.first == DstLT.first && 256139f7f9bSDimitry Andric SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { 257139f7f9bSDimitry Andric 258139f7f9bSDimitry Andric // Bitcast between types that are legalized to the same type are free. 259139f7f9bSDimitry Andric if (Opcode == Instruction::BitCast || Opcode == Instruction::Trunc) 260139f7f9bSDimitry Andric return 0; 261139f7f9bSDimitry Andric } 262139f7f9bSDimitry Andric 263139f7f9bSDimitry Andric if (Opcode == Instruction::Trunc && 264139f7f9bSDimitry Andric TLI->isTruncateFree(SrcLT.second, DstLT.second)) 265139f7f9bSDimitry Andric return 0; 266139f7f9bSDimitry Andric 267139f7f9bSDimitry Andric if (Opcode == Instruction::ZExt && 268139f7f9bSDimitry Andric TLI->isZExtFree(SrcLT.second, DstLT.second)) 269139f7f9bSDimitry Andric return 0; 270139f7f9bSDimitry Andric 271139f7f9bSDimitry Andric // If the cast is marked as legal (or promote) then assume low cost. 272139f7f9bSDimitry Andric if (TLI->isOperationLegalOrPromote(ISD, DstLT.second)) 273139f7f9bSDimitry Andric return 1; 274139f7f9bSDimitry Andric 275139f7f9bSDimitry Andric // Handle scalar conversions. 276139f7f9bSDimitry Andric if (!Src->isVectorTy() && !Dst->isVectorTy()) { 277139f7f9bSDimitry Andric 278139f7f9bSDimitry Andric // Scalar bitcasts are usually free. 279139f7f9bSDimitry Andric if (Opcode == Instruction::BitCast) 280139f7f9bSDimitry Andric return 0; 281139f7f9bSDimitry Andric 282139f7f9bSDimitry Andric // Just check the op cost. If the operation is legal then assume it costs 1. 283139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, DstLT.second)) 284139f7f9bSDimitry Andric return 1; 285139f7f9bSDimitry Andric 286139f7f9bSDimitry Andric // Assume that illegal scalar instruction are expensive. 287139f7f9bSDimitry Andric return 4; 288139f7f9bSDimitry Andric } 289139f7f9bSDimitry Andric 290139f7f9bSDimitry Andric // Check vector-to-vector casts. 291139f7f9bSDimitry Andric if (Dst->isVectorTy() && Src->isVectorTy()) { 292139f7f9bSDimitry Andric 293139f7f9bSDimitry Andric // If the cast is between same-sized registers, then the check is simple. 294139f7f9bSDimitry Andric if (SrcLT.first == DstLT.first && 295139f7f9bSDimitry Andric SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { 296139f7f9bSDimitry Andric 297139f7f9bSDimitry Andric // Assume that Zext is done using AND. 298139f7f9bSDimitry Andric if (Opcode == Instruction::ZExt) 299139f7f9bSDimitry Andric return 1; 300139f7f9bSDimitry Andric 301139f7f9bSDimitry Andric // Assume that sext is done using SHL and SRA. 302139f7f9bSDimitry Andric if (Opcode == Instruction::SExt) 303139f7f9bSDimitry Andric return 2; 304139f7f9bSDimitry Andric 305139f7f9bSDimitry Andric // Just check the op cost. If the operation is legal then assume it costs 306139f7f9bSDimitry Andric // 1 and multiply by the type-legalization overhead. 307139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, DstLT.second)) 308139f7f9bSDimitry Andric return SrcLT.first * 1; 309139f7f9bSDimitry Andric } 310139f7f9bSDimitry Andric 311139f7f9bSDimitry Andric // If we are converting vectors and the operation is illegal, or 312139f7f9bSDimitry Andric // if the vectors are legalized to different types, estimate the 313139f7f9bSDimitry Andric // scalarization costs. 314139f7f9bSDimitry Andric unsigned Num = Dst->getVectorNumElements(); 315139f7f9bSDimitry Andric unsigned Cost = TopTTI->getCastInstrCost(Opcode, Dst->getScalarType(), 316139f7f9bSDimitry Andric Src->getScalarType()); 317139f7f9bSDimitry Andric 318139f7f9bSDimitry Andric // Return the cost of multiple scalar invocation plus the cost of 319139f7f9bSDimitry Andric // inserting and extracting the values. 320139f7f9bSDimitry Andric return getScalarizationOverhead(Dst, true, true) + Num * Cost; 321139f7f9bSDimitry Andric } 322139f7f9bSDimitry Andric 323139f7f9bSDimitry Andric // We already handled vector-to-vector and scalar-to-scalar conversions. This 324139f7f9bSDimitry Andric // is where we handle bitcast between vectors and scalars. We need to assume 325139f7f9bSDimitry Andric // that the conversion is scalarized in one way or another. 326139f7f9bSDimitry Andric if (Opcode == Instruction::BitCast) 327139f7f9bSDimitry Andric // Illegal bitcasts are done by storing and loading from a stack slot. 328139f7f9bSDimitry Andric return (Src->isVectorTy()? getScalarizationOverhead(Src, false, true):0) + 329139f7f9bSDimitry Andric (Dst->isVectorTy()? getScalarizationOverhead(Dst, true, false):0); 330139f7f9bSDimitry Andric 331139f7f9bSDimitry Andric llvm_unreachable("Unhandled cast"); 332139f7f9bSDimitry Andric } 333139f7f9bSDimitry Andric 334139f7f9bSDimitry Andric unsigned BasicTTI::getCFInstrCost(unsigned Opcode) const { 335139f7f9bSDimitry Andric // Branches are assumed to be predicted. 336139f7f9bSDimitry Andric return 0; 337139f7f9bSDimitry Andric } 338139f7f9bSDimitry Andric 339139f7f9bSDimitry Andric unsigned BasicTTI::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, 340139f7f9bSDimitry Andric Type *CondTy) const { 341139f7f9bSDimitry Andric int ISD = TLI->InstructionOpcodeToISD(Opcode); 342139f7f9bSDimitry Andric assert(ISD && "Invalid opcode"); 343139f7f9bSDimitry Andric 344139f7f9bSDimitry Andric // Selects on vectors are actually vector selects. 345139f7f9bSDimitry Andric if (ISD == ISD::SELECT) { 346139f7f9bSDimitry Andric assert(CondTy && "CondTy must exist"); 347139f7f9bSDimitry Andric if (CondTy->isVectorTy()) 348139f7f9bSDimitry Andric ISD = ISD::VSELECT; 349139f7f9bSDimitry Andric } 350139f7f9bSDimitry Andric 351139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(ValTy); 352139f7f9bSDimitry Andric 353139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, LT.second)) { 354139f7f9bSDimitry Andric // The operation is legal. Assume it costs 1. Multiply 355139f7f9bSDimitry Andric // by the type-legalization overhead. 356139f7f9bSDimitry Andric return LT.first * 1; 357139f7f9bSDimitry Andric } 358139f7f9bSDimitry Andric 359139f7f9bSDimitry Andric // Otherwise, assume that the cast is scalarized. 360139f7f9bSDimitry Andric if (ValTy->isVectorTy()) { 361139f7f9bSDimitry Andric unsigned Num = ValTy->getVectorNumElements(); 362139f7f9bSDimitry Andric if (CondTy) 363139f7f9bSDimitry Andric CondTy = CondTy->getScalarType(); 364139f7f9bSDimitry Andric unsigned Cost = TopTTI->getCmpSelInstrCost(Opcode, ValTy->getScalarType(), 365139f7f9bSDimitry Andric CondTy); 366139f7f9bSDimitry Andric 367139f7f9bSDimitry Andric // Return the cost of multiple scalar invocation plus the cost of inserting 368139f7f9bSDimitry Andric // and extracting the values. 369139f7f9bSDimitry Andric return getScalarizationOverhead(ValTy, true, false) + Num * Cost; 370139f7f9bSDimitry Andric } 371139f7f9bSDimitry Andric 372139f7f9bSDimitry Andric // Unknown scalar opcode. 373139f7f9bSDimitry Andric return 1; 374139f7f9bSDimitry Andric } 375139f7f9bSDimitry Andric 376139f7f9bSDimitry Andric unsigned BasicTTI::getVectorInstrCost(unsigned Opcode, Type *Val, 377139f7f9bSDimitry Andric unsigned Index) const { 378139f7f9bSDimitry Andric return 1; 379139f7f9bSDimitry Andric } 380139f7f9bSDimitry Andric 381139f7f9bSDimitry Andric unsigned BasicTTI::getMemoryOpCost(unsigned Opcode, Type *Src, 382139f7f9bSDimitry Andric unsigned Alignment, 383139f7f9bSDimitry Andric unsigned AddressSpace) const { 384139f7f9bSDimitry Andric assert(!Src->isVoidTy() && "Invalid type"); 385139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Src); 386139f7f9bSDimitry Andric 387139f7f9bSDimitry Andric // Assume that all loads of legal types cost 1. 388139f7f9bSDimitry Andric return LT.first; 389139f7f9bSDimitry Andric } 390139f7f9bSDimitry Andric 391139f7f9bSDimitry Andric unsigned BasicTTI::getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy, 392139f7f9bSDimitry Andric ArrayRef<Type *> Tys) const { 393139f7f9bSDimitry Andric unsigned ISD = 0; 394139f7f9bSDimitry Andric switch (IID) { 395139f7f9bSDimitry Andric default: { 396139f7f9bSDimitry Andric // Assume that we need to scalarize this intrinsic. 397139f7f9bSDimitry Andric unsigned ScalarizationCost = 0; 398139f7f9bSDimitry Andric unsigned ScalarCalls = 1; 399139f7f9bSDimitry Andric if (RetTy->isVectorTy()) { 400139f7f9bSDimitry Andric ScalarizationCost = getScalarizationOverhead(RetTy, true, false); 401139f7f9bSDimitry Andric ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); 402139f7f9bSDimitry Andric } 403139f7f9bSDimitry Andric for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) { 404139f7f9bSDimitry Andric if (Tys[i]->isVectorTy()) { 405139f7f9bSDimitry Andric ScalarizationCost += getScalarizationOverhead(Tys[i], false, true); 406139f7f9bSDimitry Andric ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements()); 407139f7f9bSDimitry Andric } 408139f7f9bSDimitry Andric } 409139f7f9bSDimitry Andric 410139f7f9bSDimitry Andric return ScalarCalls + ScalarizationCost; 411139f7f9bSDimitry Andric } 412139f7f9bSDimitry Andric // Look for intrinsics that can be lowered directly or turned into a scalar 413139f7f9bSDimitry Andric // intrinsic call. 414139f7f9bSDimitry Andric case Intrinsic::sqrt: ISD = ISD::FSQRT; break; 415139f7f9bSDimitry Andric case Intrinsic::sin: ISD = ISD::FSIN; break; 416139f7f9bSDimitry Andric case Intrinsic::cos: ISD = ISD::FCOS; break; 417139f7f9bSDimitry Andric case Intrinsic::exp: ISD = ISD::FEXP; break; 418139f7f9bSDimitry Andric case Intrinsic::exp2: ISD = ISD::FEXP2; break; 419139f7f9bSDimitry Andric case Intrinsic::log: ISD = ISD::FLOG; break; 420139f7f9bSDimitry Andric case Intrinsic::log10: ISD = ISD::FLOG10; break; 421139f7f9bSDimitry Andric case Intrinsic::log2: ISD = ISD::FLOG2; break; 422139f7f9bSDimitry Andric case Intrinsic::fabs: ISD = ISD::FABS; break; 423139f7f9bSDimitry Andric case Intrinsic::floor: ISD = ISD::FFLOOR; break; 424139f7f9bSDimitry Andric case Intrinsic::ceil: ISD = ISD::FCEIL; break; 425139f7f9bSDimitry Andric case Intrinsic::trunc: ISD = ISD::FTRUNC; break; 426139f7f9bSDimitry Andric case Intrinsic::rint: ISD = ISD::FRINT; break; 427139f7f9bSDimitry Andric case Intrinsic::pow: ISD = ISD::FPOW; break; 428139f7f9bSDimitry Andric case Intrinsic::fma: ISD = ISD::FMA; break; 429139f7f9bSDimitry Andric case Intrinsic::fmuladd: ISD = ISD::FMA; break; // FIXME: mul + add? 430139f7f9bSDimitry Andric } 431139f7f9bSDimitry Andric 432139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(RetTy); 433139f7f9bSDimitry Andric 434139f7f9bSDimitry Andric if (TLI->isOperationLegalOrPromote(ISD, LT.second)) { 435139f7f9bSDimitry Andric // The operation is legal. Assume it costs 1. 436139f7f9bSDimitry Andric // If the type is split to multiple registers, assume that thre is some 437139f7f9bSDimitry Andric // overhead to this. 438139f7f9bSDimitry Andric // TODO: Once we have extract/insert subvector cost we need to use them. 439139f7f9bSDimitry Andric if (LT.first > 1) 440139f7f9bSDimitry Andric return LT.first * 2; 441139f7f9bSDimitry Andric return LT.first * 1; 442139f7f9bSDimitry Andric } 443139f7f9bSDimitry Andric 444139f7f9bSDimitry Andric if (!TLI->isOperationExpand(ISD, LT.second)) { 445139f7f9bSDimitry Andric // If the operation is custom lowered then assume 446139f7f9bSDimitry Andric // thare the code is twice as expensive. 447139f7f9bSDimitry Andric return LT.first * 2; 448139f7f9bSDimitry Andric } 449139f7f9bSDimitry Andric 450139f7f9bSDimitry Andric // Else, assume that we need to scalarize this intrinsic. For math builtins 451139f7f9bSDimitry Andric // this will emit a costly libcall, adding call overhead and spills. Make it 452139f7f9bSDimitry Andric // very expensive. 453139f7f9bSDimitry Andric if (RetTy->isVectorTy()) { 454139f7f9bSDimitry Andric unsigned Num = RetTy->getVectorNumElements(); 455139f7f9bSDimitry Andric unsigned Cost = TopTTI->getIntrinsicInstrCost(IID, RetTy->getScalarType(), 456139f7f9bSDimitry Andric Tys); 457139f7f9bSDimitry Andric return 10 * Cost * Num; 458139f7f9bSDimitry Andric } 459139f7f9bSDimitry Andric 460139f7f9bSDimitry Andric // This is going to be turned into a library call, make it expensive. 461139f7f9bSDimitry Andric return 10; 462139f7f9bSDimitry Andric } 463139f7f9bSDimitry Andric 464139f7f9bSDimitry Andric unsigned BasicTTI::getNumberOfParts(Type *Tp) const { 465139f7f9bSDimitry Andric std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(Tp); 466139f7f9bSDimitry Andric return LT.first; 467139f7f9bSDimitry Andric } 468139f7f9bSDimitry Andric 469139f7f9bSDimitry Andric unsigned BasicTTI::getAddressComputationCost(Type *Ty) const { 470139f7f9bSDimitry Andric return 0; 471139f7f9bSDimitry Andric } 472