brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · d7f4e1d Raw
209 lines · c
1//===-- NVPTXTargetTransformInfo.h - NVPTX specific TTI ---------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// This file a TargetTransformInfoImplBase conforming object specific to the10/// NVPTX target machine. It uses the target's detailed information to11/// provide more precise answers to certain TTI queries, while letting the12/// target independent and default TTI implementations handle the rest.13///14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_LIB_TARGET_NVPTX_NVPTXTARGETTRANSFORMINFO_H17#define LLVM_LIB_TARGET_NVPTX_NVPTXTARGETTRANSFORMINFO_H18 19#include "MCTargetDesc/NVPTXBaseInfo.h"20#include "NVPTXTargetMachine.h"21#include "NVPTXUtilities.h"22#include "llvm/Analysis/TargetTransformInfo.h"23#include "llvm/CodeGen/BasicTTIImpl.h"24#include "llvm/CodeGen/TargetLowering.h"25#include <optional>26 27namespace llvm {28 29class NVPTXTTIImpl final : public BasicTTIImplBase<NVPTXTTIImpl> {30  typedef BasicTTIImplBase<NVPTXTTIImpl> BaseT;31  typedef TargetTransformInfo TTI;32  friend BaseT;33 34  const NVPTXSubtarget *ST;35  const NVPTXTargetLowering *TLI;36 37  const NVPTXSubtarget *getST() const { return ST; };38  const NVPTXTargetLowering *getTLI() const { return TLI; };39 40public:41  explicit NVPTXTTIImpl(const NVPTXTargetMachine *TM, const Function &F)42      : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl()),43        TLI(ST->getTargetLowering()) {}44 45  bool hasBranchDivergence(const Function *F = nullptr) const override {46    return true;47  }48 49  bool isSourceOfDivergence(const Value *V) const override;50 51  unsigned getFlatAddressSpace() const override {52    return AddressSpace::ADDRESS_SPACE_GENERIC;53  }54 55  bool56  canHaveNonUndefGlobalInitializerInAddressSpace(unsigned AS) const override {57    return AS != AddressSpace::ADDRESS_SPACE_SHARED &&58           AS != AddressSpace::ADDRESS_SPACE_LOCAL && AS != ADDRESS_SPACE_PARAM;59  }60 61  std::optional<Instruction *>62  instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;63 64  // Loads and stores can be vectorized if the alignment is at least as big as65  // the load/store we want to vectorize.66  bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,67                                   unsigned AddrSpace) const override {68    return Alignment >= ChainSizeInBytes;69  }70  bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment,71                                    unsigned AddrSpace) const override {72    return isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment, AddrSpace);73  }74 75  // NVPTX has infinite registers of all kinds, but the actual machine doesn't.76  // We conservatively return 1 here which is just enough to enable the77  // vectorizers but disables heuristics based on the number of registers.78  // FIXME: Return a more reasonable number, while keeping an eye on79  // LoopVectorizer's unrolling heuristics.80  unsigned getNumberOfRegisters(unsigned ClassID) const override { return 1; }81 82  // Only <2 x half> should be vectorized, so always return 32 for the vector83  // register size.84  TypeSize85  getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override {86    return TypeSize::getFixed(32);87  }88  unsigned getMinVectorRegisterBitWidth() const override { return 32; }89 90  bool shouldExpandReduction(const IntrinsicInst *II) const override {91    // Turn off ExpandReductions pass for NVPTX, which doesn't have advanced92    // swizzling operations. Our backend/Selection DAG can expand these93    // reductions with less movs.94    return false;95  }96 97  // We don't want to prevent inlining because of target-cpu and -features98  // attributes that were added to newer versions of LLVM/Clang: There are99  // no incompatible functions in PTX, ptxas will throw errors in such cases.100  bool areInlineCompatible(const Function *Caller,101                           const Function *Callee) const override {102    return true;103  }104 105  // Increase the inlining cost threshold by a factor of 11, reflecting that106  // calls are particularly expensive in NVPTX.107  unsigned getInliningThresholdMultiplier() const override { return 11; }108 109  InstructionCost110  getInstructionCost(const User *U, ArrayRef<const Value *> Operands,111                     TTI::TargetCostKind CostKind) const override;112 113  InstructionCost getArithmeticInstrCost(114      unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,115      TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},116      TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},117      ArrayRef<const Value *> Args = {},118      const Instruction *CxtI = nullptr) const override;119 120  InstructionCost getScalarizationOverhead(121      VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract,122      TTI::TargetCostKind CostKind, bool ForPoisonSrc = true,123      ArrayRef<Value *> VL = {}) const override {124    if (!InTy->getElementCount().isFixed())125      return InstructionCost::getInvalid();126 127    auto VT = getTLI()->getValueType(DL, InTy);128    auto NumElements = InTy->getElementCount().getFixedValue();129    InstructionCost Cost = 0;130    if (Insert && !VL.empty()) {131      bool AllConstant = all_of(seq(NumElements), [&](int Idx) {132        return !DemandedElts[Idx] || isa<Constant>(VL[Idx]);133      });134      if (AllConstant) {135        Cost += TTI::TCC_Free;136        Insert = false;137      }138    }139    if (Insert && NVPTX::isPackedVectorTy(VT) && VT.is32BitVector()) {140      // Can be built in a single 32-bit mov (64-bit regs are emulated in SASS141      // with 2x 32-bit regs)142      Cost += 1;143      Insert = false;144    }145    if (Insert && VT == MVT::v4i8) {146      InstructionCost Cost = 3; // 3 x PRMT147      for (auto Idx : seq(NumElements))148        if (DemandedElts[Idx])149          Cost += 1; // zext operand to i32150      Insert = false;151    }152    return Cost + BaseT::getScalarizationOverhead(InTy, DemandedElts, Insert,153                                                  Extract, CostKind,154                                                  ForPoisonSrc, VL);155  }156 157  void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,158                               TTI::UnrollingPreferences &UP,159                               OptimizationRemarkEmitter *ORE) const override;160 161  void getPeelingPreferences(Loop *L, ScalarEvolution &SE,162                             TTI::PeelingPreferences &PP) const override;163 164  bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const override {165    // Volatile loads/stores are only supported for shared and global address166    // spaces, or for generic AS that maps to them.167    if (!(AddrSpace == llvm::ADDRESS_SPACE_GENERIC ||168          AddrSpace == llvm::ADDRESS_SPACE_GLOBAL ||169          AddrSpace == llvm::ADDRESS_SPACE_SHARED))170      return false;171 172    switch(I->getOpcode()){173    default:174      return false;175    case Instruction::Load:176    case Instruction::Store:177      return true;178    }179  }180 181  bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,182                                  Intrinsic::ID IID) const override;183 184  bool isLegalMaskedStore(Type *DataType, Align Alignment, unsigned AddrSpace,185                          TTI::MaskKind MaskKind) const override;186 187  bool isLegalMaskedLoad(Type *DataType, Align Alignment, unsigned AddrSpace,188                         TTI::MaskKind MaskKind) const override;189 190  unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const override;191 192  Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,193                                          Value *NewV) const override;194  unsigned getAssumedAddrSpace(const Value *V) const override;195 196  void collectKernelLaunchBounds(197      const Function &F,198      SmallVectorImpl<std::pair<StringRef, int64_t>> &LB) const override;199 200  bool shouldBuildRelLookupTables() const override {201    // Self-referential globals are not supported.202    return false;203  }204};205 206} // end namespace llvm207 208#endif209