Home | History | Annotate | Download | only in Analysis
      1 //===- llvm/Analysis/TargetTransformInfo.cpp ------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/Analysis/TargetTransformInfo.h"
     11 #include "llvm/Analysis/TargetTransformInfoImpl.h"
     12 #include "llvm/IR/CallSite.h"
     13 #include "llvm/IR/DataLayout.h"
     14 #include "llvm/IR/Instruction.h"
     15 #include "llvm/IR/Instructions.h"
     16 #include "llvm/IR/IntrinsicInst.h"
     17 #include "llvm/IR/Module.h"
     18 #include "llvm/IR/Operator.h"
     19 #include "llvm/Support/ErrorHandling.h"
     20 #include <utility>
     21 
     22 using namespace llvm;
     23 
     24 #define DEBUG_TYPE "tti"
     25 
     26 namespace {
     27 /// \brief No-op implementation of the TTI interface using the utility base
     28 /// classes.
     29 ///
     30 /// This is used when no target specific information is available.
     31 struct NoTTIImpl : TargetTransformInfoImplCRTPBase<NoTTIImpl> {
     32   explicit NoTTIImpl(const DataLayout &DL)
     33       : TargetTransformInfoImplCRTPBase<NoTTIImpl>(DL) {}
     34 };
     35 }
     36 
     37 TargetTransformInfo::TargetTransformInfo(const DataLayout &DL)
     38     : TTIImpl(new Model<NoTTIImpl>(NoTTIImpl(DL))) {}
     39 
     40 TargetTransformInfo::~TargetTransformInfo() {}
     41 
     42 TargetTransformInfo::TargetTransformInfo(TargetTransformInfo &&Arg)
     43     : TTIImpl(std::move(Arg.TTIImpl)) {}
     44 
     45 TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) {
     46   TTIImpl = std::move(RHS.TTIImpl);
     47   return *this;
     48 }
     49 
     50 int TargetTransformInfo::getOperationCost(unsigned Opcode, Type *Ty,
     51                                           Type *OpTy) const {
     52   int Cost = TTIImpl->getOperationCost(Opcode, Ty, OpTy);
     53   assert(Cost >= 0 && "TTI should not produce negative costs!");
     54   return Cost;
     55 }
     56 
     57 int TargetTransformInfo::getCallCost(FunctionType *FTy, int NumArgs) const {
     58   int Cost = TTIImpl->getCallCost(FTy, NumArgs);
     59   assert(Cost >= 0 && "TTI should not produce negative costs!");
     60   return Cost;
     61 }
     62 
     63 int TargetTransformInfo::getCallCost(const Function *F,
     64                                      ArrayRef<const Value *> Arguments) const {
     65   int Cost = TTIImpl->getCallCost(F, Arguments);
     66   assert(Cost >= 0 && "TTI should not produce negative costs!");
     67   return Cost;
     68 }
     69 
     70 unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
     71   return TTIImpl->getInliningThresholdMultiplier();
     72 }
     73 
     74 int TargetTransformInfo::getGEPCost(Type *PointeeType, const Value *Ptr,
     75                                     ArrayRef<const Value *> Operands) const {
     76   return TTIImpl->getGEPCost(PointeeType, Ptr, Operands);
     77 }
     78 
     79 int TargetTransformInfo::getIntrinsicCost(
     80     Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) const {
     81   int Cost = TTIImpl->getIntrinsicCost(IID, RetTy, Arguments);
     82   assert(Cost >= 0 && "TTI should not produce negative costs!");
     83   return Cost;
     84 }
     85 
     86 int TargetTransformInfo::getUserCost(const User *U) const {
     87   int Cost = TTIImpl->getUserCost(U);
     88   assert(Cost >= 0 && "TTI should not produce negative costs!");
     89   return Cost;
     90 }
     91 
     92 bool TargetTransformInfo::hasBranchDivergence() const {
     93   return TTIImpl->hasBranchDivergence();
     94 }
     95 
     96 bool TargetTransformInfo::isSourceOfDivergence(const Value *V) const {
     97   return TTIImpl->isSourceOfDivergence(V);
     98 }
     99 
    100 bool TargetTransformInfo::isLoweredToCall(const Function *F) const {
    101   return TTIImpl->isLoweredToCall(F);
    102 }
    103 
    104 void TargetTransformInfo::getUnrollingPreferences(
    105     Loop *L, UnrollingPreferences &UP) const {
    106   return TTIImpl->getUnrollingPreferences(L, UP);
    107 }
    108 
    109 bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
    110   return TTIImpl->isLegalAddImmediate(Imm);
    111 }
    112 
    113 bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const {
    114   return TTIImpl->isLegalICmpImmediate(Imm);
    115 }
    116 
    117 bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
    118                                                 int64_t BaseOffset,
    119                                                 bool HasBaseReg,
    120                                                 int64_t Scale,
    121                                                 unsigned AddrSpace) const {
    122   return TTIImpl->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
    123                                         Scale, AddrSpace);
    124 }
    125 
    126 bool TargetTransformInfo::isLegalMaskedStore(Type *DataType) const {
    127   return TTIImpl->isLegalMaskedStore(DataType);
    128 }
    129 
    130 bool TargetTransformInfo::isLegalMaskedLoad(Type *DataType) const {
    131   return TTIImpl->isLegalMaskedLoad(DataType);
    132 }
    133 
    134 bool TargetTransformInfo::isLegalMaskedGather(Type *DataType) const {
    135   return TTIImpl->isLegalMaskedGather(DataType);
    136 }
    137 
    138 bool TargetTransformInfo::isLegalMaskedScatter(Type *DataType) const {
    139   return TTIImpl->isLegalMaskedGather(DataType);
    140 }
    141 
    142 int TargetTransformInfo::getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,
    143                                               int64_t BaseOffset,
    144                                               bool HasBaseReg,
    145                                               int64_t Scale,
    146                                               unsigned AddrSpace) const {
    147   int Cost = TTIImpl->getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg,
    148                                            Scale, AddrSpace);
    149   assert(Cost >= 0 && "TTI should not produce negative costs!");
    150   return Cost;
    151 }
    152 
    153 bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const {
    154   return TTIImpl->isTruncateFree(Ty1, Ty2);
    155 }
    156 
    157 bool TargetTransformInfo::isProfitableToHoist(Instruction *I) const {
    158   return TTIImpl->isProfitableToHoist(I);
    159 }
    160 
    161 bool TargetTransformInfo::isTypeLegal(Type *Ty) const {
    162   return TTIImpl->isTypeLegal(Ty);
    163 }
    164 
    165 unsigned TargetTransformInfo::getJumpBufAlignment() const {
    166   return TTIImpl->getJumpBufAlignment();
    167 }
    168 
    169 unsigned TargetTransformInfo::getJumpBufSize() const {
    170   return TTIImpl->getJumpBufSize();
    171 }
    172 
    173 bool TargetTransformInfo::shouldBuildLookupTables() const {
    174   return TTIImpl->shouldBuildLookupTables();
    175 }
    176 
    177 bool TargetTransformInfo::enableAggressiveInterleaving(bool LoopHasReductions) const {
    178   return TTIImpl->enableAggressiveInterleaving(LoopHasReductions);
    179 }
    180 
    181 bool TargetTransformInfo::enableInterleavedAccessVectorization() const {
    182   return TTIImpl->enableInterleavedAccessVectorization();
    183 }
    184 
    185 bool TargetTransformInfo::isFPVectorizationPotentiallyUnsafe() const {
    186   return TTIImpl->isFPVectorizationPotentiallyUnsafe();
    187 }
    188 
    189 bool TargetTransformInfo::allowsMisalignedMemoryAccesses(unsigned BitWidth,
    190                                                          unsigned AddressSpace,
    191                                                          unsigned Alignment,
    192                                                          bool *Fast) const {
    193   return TTIImpl->allowsMisalignedMemoryAccesses(BitWidth, AddressSpace,
    194                                                  Alignment, Fast);
    195 }
    196 
    197 TargetTransformInfo::PopcntSupportKind
    198 TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const {
    199   return TTIImpl->getPopcntSupport(IntTyWidthInBit);
    200 }
    201 
    202 bool TargetTransformInfo::haveFastSqrt(Type *Ty) const {
    203   return TTIImpl->haveFastSqrt(Ty);
    204 }
    205 
    206 int TargetTransformInfo::getFPOpCost(Type *Ty) const {
    207   int Cost = TTIImpl->getFPOpCost(Ty);
    208   assert(Cost >= 0 && "TTI should not produce negative costs!");
    209   return Cost;
    210 }
    211 
    212 int TargetTransformInfo::getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx,
    213                                                const APInt &Imm,
    214                                                Type *Ty) const {
    215   int Cost = TTIImpl->getIntImmCodeSizeCost(Opcode, Idx, Imm, Ty);
    216   assert(Cost >= 0 && "TTI should not produce negative costs!");
    217   return Cost;
    218 }
    219 
    220 int TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const {
    221   int Cost = TTIImpl->getIntImmCost(Imm, Ty);
    222   assert(Cost >= 0 && "TTI should not produce negative costs!");
    223   return Cost;
    224 }
    225 
    226 int TargetTransformInfo::getIntImmCost(unsigned Opcode, unsigned Idx,
    227                                        const APInt &Imm, Type *Ty) const {
    228   int Cost = TTIImpl->getIntImmCost(Opcode, Idx, Imm, Ty);
    229   assert(Cost >= 0 && "TTI should not produce negative costs!");
    230   return Cost;
    231 }
    232 
    233 int TargetTransformInfo::getIntImmCost(Intrinsic::ID IID, unsigned Idx,
    234                                        const APInt &Imm, Type *Ty) const {
    235   int Cost = TTIImpl->getIntImmCost(IID, Idx, Imm, Ty);
    236   assert(Cost >= 0 && "TTI should not produce negative costs!");
    237   return Cost;
    238 }
    239 
    240 unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const {
    241   return TTIImpl->getNumberOfRegisters(Vector);
    242 }
    243 
    244 unsigned TargetTransformInfo::getRegisterBitWidth(bool Vector) const {
    245   return TTIImpl->getRegisterBitWidth(Vector);
    246 }
    247 
    248 unsigned TargetTransformInfo::getLoadStoreVecRegBitWidth(unsigned AS) const {
    249   return TTIImpl->getLoadStoreVecRegBitWidth(AS);
    250 }
    251 
    252 unsigned TargetTransformInfo::getCacheLineSize() const {
    253   return TTIImpl->getCacheLineSize();
    254 }
    255 
    256 unsigned TargetTransformInfo::getPrefetchDistance() const {
    257   return TTIImpl->getPrefetchDistance();
    258 }
    259 
    260 unsigned TargetTransformInfo::getMinPrefetchStride() const {
    261   return TTIImpl->getMinPrefetchStride();
    262 }
    263 
    264 unsigned TargetTransformInfo::getMaxPrefetchIterationsAhead() const {
    265   return TTIImpl->getMaxPrefetchIterationsAhead();
    266 }
    267 
    268 unsigned TargetTransformInfo::getMaxInterleaveFactor(unsigned VF) const {
    269   return TTIImpl->getMaxInterleaveFactor(VF);
    270 }
    271 
    272 int TargetTransformInfo::getArithmeticInstrCost(
    273     unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
    274     OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo,
    275     OperandValueProperties Opd2PropInfo) const {
    276   int Cost = TTIImpl->getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
    277                                              Opd1PropInfo, Opd2PropInfo);
    278   assert(Cost >= 0 && "TTI should not produce negative costs!");
    279   return Cost;
    280 }
    281 
    282 int TargetTransformInfo::getShuffleCost(ShuffleKind Kind, Type *Ty, int Index,
    283                                         Type *SubTp) const {
    284   int Cost = TTIImpl->getShuffleCost(Kind, Ty, Index, SubTp);
    285   assert(Cost >= 0 && "TTI should not produce negative costs!");
    286   return Cost;
    287 }
    288 
    289 int TargetTransformInfo::getCastInstrCost(unsigned Opcode, Type *Dst,
    290                                           Type *Src) const {
    291   int Cost = TTIImpl->getCastInstrCost(Opcode, Dst, Src);
    292   assert(Cost >= 0 && "TTI should not produce negative costs!");
    293   return Cost;
    294 }
    295 
    296 int TargetTransformInfo::getExtractWithExtendCost(unsigned Opcode, Type *Dst,
    297                                                   VectorType *VecTy,
    298                                                   unsigned Index) const {
    299   int Cost = TTIImpl->getExtractWithExtendCost(Opcode, Dst, VecTy, Index);
    300   assert(Cost >= 0 && "TTI should not produce negative costs!");
    301   return Cost;
    302 }
    303 
    304 int TargetTransformInfo::getCFInstrCost(unsigned Opcode) const {
    305   int Cost = TTIImpl->getCFInstrCost(Opcode);
    306   assert(Cost >= 0 && "TTI should not produce negative costs!");
    307   return Cost;
    308 }
    309 
    310 int TargetTransformInfo::getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
    311                                             Type *CondTy) const {
    312   int Cost = TTIImpl->getCmpSelInstrCost(Opcode, ValTy, CondTy);
    313   assert(Cost >= 0 && "TTI should not produce negative costs!");
    314   return Cost;
    315 }
    316 
    317 int TargetTransformInfo::getVectorInstrCost(unsigned Opcode, Type *Val,
    318                                             unsigned Index) const {
    319   int Cost = TTIImpl->getVectorInstrCost(Opcode, Val, Index);
    320   assert(Cost >= 0 && "TTI should not produce negative costs!");
    321   return Cost;
    322 }
    323 
    324 int TargetTransformInfo::getMemoryOpCost(unsigned Opcode, Type *Src,
    325                                          unsigned Alignment,
    326                                          unsigned AddressSpace) const {
    327   int Cost = TTIImpl->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
    328   assert(Cost >= 0 && "TTI should not produce negative costs!");
    329   return Cost;
    330 }
    331 
    332 int TargetTransformInfo::getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
    333                                                unsigned Alignment,
    334                                                unsigned AddressSpace) const {
    335   int Cost =
    336       TTIImpl->getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
    337   assert(Cost >= 0 && "TTI should not produce negative costs!");
    338   return Cost;
    339 }
    340 
    341 int TargetTransformInfo::getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
    342                                                 Value *Ptr, bool VariableMask,
    343                                                 unsigned Alignment) const {
    344   int Cost = TTIImpl->getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask,
    345                                              Alignment);
    346   assert(Cost >= 0 && "TTI should not produce negative costs!");
    347   return Cost;
    348 }
    349 
    350 int TargetTransformInfo::getInterleavedMemoryOpCost(
    351     unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
    352     unsigned Alignment, unsigned AddressSpace) const {
    353   int Cost = TTIImpl->getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
    354                                                  Alignment, AddressSpace);
    355   assert(Cost >= 0 && "TTI should not produce negative costs!");
    356   return Cost;
    357 }
    358 
    359 int TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
    360                                                ArrayRef<Type *> Tys,
    361                                                FastMathFlags FMF) const {
    362   int Cost = TTIImpl->getIntrinsicInstrCost(ID, RetTy, Tys, FMF);
    363   assert(Cost >= 0 && "TTI should not produce negative costs!");
    364   return Cost;
    365 }
    366 
    367 int TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
    368                                                ArrayRef<Value *> Args,
    369                                                FastMathFlags FMF) const {
    370   int Cost = TTIImpl->getIntrinsicInstrCost(ID, RetTy, Args, FMF);
    371   assert(Cost >= 0 && "TTI should not produce negative costs!");
    372   return Cost;
    373 }
    374 
    375 int TargetTransformInfo::getCallInstrCost(Function *F, Type *RetTy,
    376                                           ArrayRef<Type *> Tys) const {
    377   int Cost = TTIImpl->getCallInstrCost(F, RetTy, Tys);
    378   assert(Cost >= 0 && "TTI should not produce negative costs!");
    379   return Cost;
    380 }
    381 
    382 unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const {
    383   return TTIImpl->getNumberOfParts(Tp);
    384 }
    385 
    386 int TargetTransformInfo::getAddressComputationCost(Type *Tp,
    387                                                    bool IsComplex) const {
    388   int Cost = TTIImpl->getAddressComputationCost(Tp, IsComplex);
    389   assert(Cost >= 0 && "TTI should not produce negative costs!");
    390   return Cost;
    391 }
    392 
    393 int TargetTransformInfo::getReductionCost(unsigned Opcode, Type *Ty,
    394                                           bool IsPairwiseForm) const {
    395   int Cost = TTIImpl->getReductionCost(Opcode, Ty, IsPairwiseForm);
    396   assert(Cost >= 0 && "TTI should not produce negative costs!");
    397   return Cost;
    398 }
    399 
    400 unsigned
    401 TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
    402   return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
    403 }
    404 
    405 bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
    406                                              MemIntrinsicInfo &Info) const {
    407   return TTIImpl->getTgtMemIntrinsic(Inst, Info);
    408 }
    409 
    410 Value *TargetTransformInfo::getOrCreateResultFromMemIntrinsic(
    411     IntrinsicInst *Inst, Type *ExpectedType) const {
    412   return TTIImpl->getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
    413 }
    414 
    415 bool TargetTransformInfo::areInlineCompatible(const Function *Caller,
    416                                               const Function *Callee) const {
    417   return TTIImpl->areInlineCompatible(Caller, Callee);
    418 }
    419 
    420 TargetTransformInfo::Concept::~Concept() {}
    421 
    422 TargetIRAnalysis::TargetIRAnalysis() : TTICallback(&getDefaultTTI) {}
    423 
    424 TargetIRAnalysis::TargetIRAnalysis(
    425     std::function<Result(const Function &)> TTICallback)
    426     : TTICallback(std::move(TTICallback)) {}
    427 
    428 TargetIRAnalysis::Result TargetIRAnalysis::run(const Function &F,
    429                                                AnalysisManager<Function> &) {
    430   return TTICallback(F);
    431 }
    432 
    433 char TargetIRAnalysis::PassID;
    434 
    435 TargetIRAnalysis::Result TargetIRAnalysis::getDefaultTTI(const Function &F) {
    436   return Result(F.getParent()->getDataLayout());
    437 }
    438 
    439 // Register the basic pass.
    440 INITIALIZE_PASS(TargetTransformInfoWrapperPass, "tti",
    441                 "Target Transform Information", false, true)
    442 char TargetTransformInfoWrapperPass::ID = 0;
    443 
    444 void TargetTransformInfoWrapperPass::anchor() {}
    445 
    446 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass()
    447     : ImmutablePass(ID) {
    448   initializeTargetTransformInfoWrapperPassPass(
    449       *PassRegistry::getPassRegistry());
    450 }
    451 
    452 TargetTransformInfoWrapperPass::TargetTransformInfoWrapperPass(
    453     TargetIRAnalysis TIRA)
    454     : ImmutablePass(ID), TIRA(std::move(TIRA)) {
    455   initializeTargetTransformInfoWrapperPassPass(
    456       *PassRegistry::getPassRegistry());
    457 }
    458 
    459 TargetTransformInfo &TargetTransformInfoWrapperPass::getTTI(const Function &F) {
    460   AnalysisManager<Function> DummyFAM;
    461   TTI = TIRA.run(F, DummyFAM);
    462   return *TTI;
    463 }
    464 
    465 ImmutablePass *
    466 llvm::createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA) {
    467   return new TargetTransformInfoWrapperPass(std::move(TIRA));
    468 }
    469