brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.3 KiB · 30f2151 Raw
394 lines · c
1//===- ARMTargetTransformInfo.h - ARM 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//9/// \file10/// This file a TargetTransformInfoImplBase conforming object specific to the11/// ARM target machine. It uses the target's detailed information to12/// provide more precise answers to certain TTI queries, while letting the13/// target independent and default TTI implementations handle the rest.14//15//===----------------------------------------------------------------------===//16 17#ifndef LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H18#define LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H19 20#include "ARM.h"21#include "ARMSubtarget.h"22#include "ARMTargetMachine.h"23#include "llvm/ADT/ArrayRef.h"24#include "llvm/Analysis/TargetTransformInfo.h"25#include "llvm/CodeGen/BasicTTIImpl.h"26#include "llvm/IR/Constant.h"27#include "llvm/IR/Function.h"28#include "llvm/TargetParser/SubtargetFeature.h"29#include <optional>30 31namespace llvm {32 33class APInt;34class ARMTargetLowering;35class Instruction;36class Loop;37class SCEV;38class ScalarEvolution;39class Type;40class Value;41 42namespace TailPredication {43  enum Mode {44    Disabled = 0,45    EnabledNoReductions,46    Enabled,47    ForceEnabledNoReductions,48    ForceEnabled49  };50}51 52// For controlling conversion of memcpy into Tail Predicated loop.53namespace TPLoop {54enum MemTransfer { ForceDisabled = 0, ForceEnabled, Allow };55}56 57class ARMTTIImpl final : public BasicTTIImplBase<ARMTTIImpl> {58  using BaseT = BasicTTIImplBase<ARMTTIImpl>;59  using TTI = TargetTransformInfo;60 61  friend BaseT;62 63  const ARMSubtarget *ST;64  const ARMTargetLowering *TLI;65 66  // Currently the following features are excluded from InlineFeaturesAllowed.67  // ModeThumb, FeatureNoARM, ModeSoftFloat, FeatureFP64, FeatureD3268  // Depending on whether they are set or unset, different69  // instructions/registers are available. For example, inlining a callee with70  // -thumb-mode in a caller with +thumb-mode, may cause the assembler to71  // fail if the callee uses ARM only instructions, e.g. in inline asm.72  const FeatureBitset InlineFeaturesAllowed = {73      ARM::FeatureVFP2, ARM::FeatureVFP3, ARM::FeatureNEON, ARM::FeatureThumb2,74      ARM::FeatureFP16, ARM::FeatureVFP4, ARM::FeatureFPARMv8,75      ARM::FeatureFullFP16, ARM::FeatureFP16FML, ARM::FeatureHWDivThumb,76      ARM::FeatureHWDivARM, ARM::FeatureDB, ARM::FeatureV7Clrex,77      ARM::FeatureAcquireRelease, ARM::FeatureSlowFPBrcc,78      ARM::FeaturePerfMon, ARM::FeatureTrustZone, ARM::Feature8MSecExt,79      ARM::FeatureCrypto, ARM::FeatureCRC, ARM::FeatureRAS,80      ARM::FeatureFPAO, ARM::FeatureFuseAES, ARM::FeatureZCZeroing,81      ARM::FeatureProfUnpredicate, ARM::FeatureSlowVGETLNi32,82      ARM::FeatureSlowVDUP32, ARM::FeaturePreferVMOVSR,83      ARM::FeaturePrefISHSTBarrier, ARM::FeatureMuxedUnits,84      ARM::FeatureSlowOddRegister, ARM::FeatureSlowLoadDSubreg,85      ARM::FeatureDontWidenVMOVS, ARM::FeatureExpandMLx,86      ARM::FeatureHasVMLxHazards, ARM::FeatureNEONForFPMovs,87      ARM::FeatureNEONForFP, ARM::FeatureCheckVLDnAlign,88      ARM::FeatureHasSlowFPVMLx, ARM::FeatureHasSlowFPVFMx,89      ARM::FeatureVMLxForwarding, ARM::FeaturePref32BitThumb,90      ARM::FeatureAvoidPartialCPSR, ARM::FeatureCheapPredicableCPSR,91      ARM::FeatureAvoidMOVsShOp, ARM::FeatureHasRetAddrStack,92      ARM::FeatureHasNoBranchPredictor, ARM::FeatureDSP, ARM::FeatureMP,93      ARM::FeatureVirtualization, ARM::FeatureMClass, ARM::FeatureRClass,94      ARM::FeatureAClass, ARM::FeatureStrictAlign, ARM::FeatureLongCalls,95      ARM::FeatureExecuteOnly, ARM::FeatureReserveR9, ARM::FeatureNoMovt,96      ARM::FeatureNoNegativeImmediates97  };98 99  const ARMSubtarget *getST() const { return ST; }100  const ARMTargetLowering *getTLI() const { return TLI; }101 102public:103  explicit ARMTTIImpl(const ARMBaseTargetMachine *TM, const Function &F)104      : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),105        TLI(ST->getTargetLowering()) {}106 107  bool areInlineCompatible(const Function *Caller,108                           const Function *Callee) const override;109 110  bool enableInterleavedAccessVectorization() const override { return true; }111 112  TTI::AddressingModeKind113  getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const override;114 115  /// Floating-point computation using ARMv8 AArch32 Advanced116  /// SIMD instructions remains unchanged from ARMv7. Only AArch64 SIMD117  /// and Arm MVE are IEEE-754 compliant.118  bool isFPVectorizationPotentiallyUnsafe() const override {119    return !ST->isTargetDarwin() && !ST->hasMVEFloatOps();120  }121 122  std::optional<Instruction *>123  instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;124  std::optional<Value *> simplifyDemandedVectorEltsIntrinsic(125      InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,126      APInt &UndefElts2, APInt &UndefElts3,127      std::function<void(Instruction *, unsigned, APInt, APInt &)>128          SimplifyAndSetOp) const override;129 130  /// \name Scalar TTI Implementations131  /// @{132 133  InstructionCost getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx,134                                        const APInt &Imm,135                                        Type *Ty) const override;136 137  using BaseT::getIntImmCost;138  InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,139                                TTI::TargetCostKind CostKind) const override;140 141  InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,142                                    const APInt &Imm, Type *Ty,143                                    TTI::TargetCostKind CostKind,144                                    Instruction *Inst = nullptr) const override;145 146  /// @}147 148  /// \name Vector TTI Implementations149  /// @{150 151  unsigned getNumberOfRegisters(unsigned ClassID) const override {152    bool Vector = (ClassID == 1);153    if (Vector) {154      if (ST->hasNEON())155        return 16;156      if (ST->hasMVEIntegerOps())157        return 8;158      return 0;159    }160 161    if (ST->isThumb1Only())162      return 8;163    return 13;164  }165 166  TypeSize167  getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override {168    switch (K) {169    case TargetTransformInfo::RGK_Scalar:170      return TypeSize::getFixed(32);171    case TargetTransformInfo::RGK_FixedWidthVector:172      if (ST->hasNEON())173        return TypeSize::getFixed(128);174      if (ST->hasMVEIntegerOps())175        return TypeSize::getFixed(128);176      return TypeSize::getFixed(0);177    case TargetTransformInfo::RGK_ScalableVector:178      return TypeSize::getScalable(0);179    }180    llvm_unreachable("Unsupported register kind");181  }182 183  unsigned getMaxInterleaveFactor(ElementCount VF) const override {184    return ST->getMaxInterleaveFactor();185  }186 187  bool isProfitableLSRChainElement(Instruction *I) const override;188 189  bool190  isLegalMaskedLoad(Type *DataTy, Align Alignment, unsigned AddressSpace,191                    TTI::MaskKind MaskKind =192                        TTI::MaskKind::VariableOrConstantMask) const override;193 194  bool195  isLegalMaskedStore(Type *DataTy, Align Alignment, unsigned AddressSpace,196                     TTI::MaskKind MaskKind =197                         TTI::MaskKind::VariableOrConstantMask) const override {198    return isLegalMaskedLoad(DataTy, Alignment, AddressSpace, MaskKind);199  }200 201  bool forceScalarizeMaskedGather(VectorType *VTy,202                                  Align Alignment) const override {203    // For MVE, we have a custom lowering pass that will already have custom204    // legalised any gathers that we can lower to MVE intrinsics, and want to205    // expand all the rest. The pass runs before the masked intrinsic lowering206    // pass.207    return true;208  }209 210  bool forceScalarizeMaskedScatter(VectorType *VTy,211                                   Align Alignment) const override {212    return forceScalarizeMaskedGather(VTy, Alignment);213  }214 215  bool isLegalMaskedGather(Type *Ty, Align Alignment) const override;216 217  bool isLegalMaskedScatter(Type *Ty, Align Alignment) const override {218    return isLegalMaskedGather(Ty, Alignment);219  }220 221  InstructionCost getMemcpyCost(const Instruction *I) const override;222 223  uint64_t getMaxMemIntrinsicInlineSizeThreshold() const override {224    return ST->getMaxInlineSizeThreshold();225  }226 227  int getNumMemOps(const IntrinsicInst *I) const;228 229  InstructionCost230  getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy,231                 ArrayRef<int> Mask, TTI::TargetCostKind CostKind, int Index,232                 VectorType *SubTp, ArrayRef<const Value *> Args = {},233                 const Instruction *CxtI = nullptr) const override;234 235  bool preferInLoopReduction(RecurKind Kind, Type *Ty) const override;236 237  bool preferPredicatedReductionSelect() const override;238 239  bool shouldExpandReduction(const IntrinsicInst *II) const override {240    return false;241  }242 243  InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind,244                                 const Instruction *I = nullptr) const override;245 246  InstructionCost247  getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,248                   TTI::CastContextHint CCH, TTI::TargetCostKind CostKind,249                   const Instruction *I = nullptr) const override;250 251  InstructionCost getCmpSelInstrCost(252      unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred,253      TTI::TargetCostKind CostKind,254      TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},255      TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},256      const Instruction *I = nullptr) const override;257 258  using BaseT::getVectorInstrCost;259  InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val,260                                     TTI::TargetCostKind CostKind,261                                     unsigned Index, const Value *Op0,262                                     const Value *Op1) const override;263 264  InstructionCost265  getAddressComputationCost(Type *Val, ScalarEvolution *SE, const SCEV *Ptr,266                            TTI::TargetCostKind CostKind) const override;267 268  InstructionCost getArithmeticInstrCost(269      unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,270      TTI::OperandValueInfo Op1Info = {TTI::OK_AnyValue, TTI::OP_None},271      TTI::OperandValueInfo Op2Info = {TTI::OK_AnyValue, TTI::OP_None},272      ArrayRef<const Value *> Args = {},273      const Instruction *CxtI = nullptr) const override;274 275  InstructionCost getMemoryOpCost(276      unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,277      TTI::TargetCostKind CostKind,278      TTI::OperandValueInfo OpInfo = {TTI::OK_AnyValue, TTI::OP_None},279      const Instruction *I = nullptr) const override;280 281  InstructionCost282  getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA,283                        TTI::TargetCostKind CostKind) const override;284 285  InstructionCost getInterleavedMemoryOpCost(286      unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,287      Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,288      bool UseMaskForCond = false, bool UseMaskForGaps = false) const override;289 290  InstructionCost291  getGatherScatterOpCost(unsigned Opcode, Type *DataTy, const Value *Ptr,292                         bool VariableMask, Align Alignment,293                         TTI::TargetCostKind CostKind,294                         const Instruction *I = nullptr) const override;295 296  InstructionCost297  getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy,298                             std::optional<FastMathFlags> FMF,299                             TTI::TargetCostKind CostKind) const override;300  InstructionCost301  getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy,302                           VectorType *ValTy, std::optional<FastMathFlags> FMF,303                           TTI::TargetCostKind CostKind) const override;304  InstructionCost305  getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy,306                         VectorType *ValTy,307                         TTI::TargetCostKind CostKind) const override;308 309  InstructionCost310  getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF,311                         TTI::TargetCostKind CostKind) const override;312 313  InstructionCost314  getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,315                        TTI::TargetCostKind CostKind) const override;316 317  /// getScalingFactorCost - Return the cost of the scaling used in318  /// addressing mode represented by AM.319  /// If the AM is supported, the return value must be >= 0.320  /// If the AM is not supported, the return value is an invalid cost.321  InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV,322                                       StackOffset BaseOffset, bool HasBaseReg,323                                       int64_t Scale,324                                       unsigned AddrSpace) const override;325 326  bool maybeLoweredToCall(Instruction &I) const;327  bool isLoweredToCall(const Function *F) const override;328  bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,329                                AssumptionCache &AC, TargetLibraryInfo *LibInfo,330                                HardwareLoopInfo &HWLoopInfo) const override;331  bool preferPredicateOverEpilogue(TailFoldingInfo *TFI) const override;332  void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,333                               TTI::UnrollingPreferences &UP,334                               OptimizationRemarkEmitter *ORE) const override;335 336  TailFoldingStyle337  getPreferredTailFoldingStyle(bool IVUpdateMayOverflow = true) const override;338 339  void getPeelingPreferences(Loop *L, ScalarEvolution &SE,340                             TTI::PeelingPreferences &PP) const override;341  bool shouldBuildLookupTablesForConstant(Constant *C) const override {342    // In the ROPI and RWPI relocation models we can't have pointers to global343    // variables or functions in constant data, so don't convert switches to344    // lookup tables if any of the values would need relocation.345    if (ST->isROPI() || ST->isRWPI())346      return !C->needsDynamicRelocation();347 348    return true;349  }350 351  bool hasArmWideBranch(bool Thumb) const override;352 353  bool isProfitableToSinkOperands(Instruction *I,354                                  SmallVectorImpl<Use *> &Ops) const override;355 356  unsigned getNumBytesToPadGlobalArray(unsigned Size,357                                       Type *ArrayType) const override;358 359  /// @}360};361 362/// isVREVMask - Check if a vector shuffle corresponds to a VREV363/// instruction with the specified blocksize.  (The order of the elements364/// within each block of the vector is reversed.)365inline bool isVREVMask(ArrayRef<int> M, EVT VT, unsigned BlockSize) {366  assert((BlockSize == 16 || BlockSize == 32 || BlockSize == 64) &&367         "Only possible block sizes for VREV are: 16, 32, 64");368 369  unsigned EltSz = VT.getScalarSizeInBits();370  if (EltSz != 8 && EltSz != 16 && EltSz != 32)371    return false;372 373  unsigned BlockElts = M[0] + 1;374  // If the first shuffle index is UNDEF, be optimistic.375  if (M[0] < 0)376    BlockElts = BlockSize / EltSz;377 378  if (BlockSize <= EltSz || BlockSize != BlockElts * EltSz)379    return false;380 381  for (unsigned i = 0, e = M.size(); i < e; ++i) {382    if (M[i] < 0)383      continue; // ignore UNDEF indices384    if ((unsigned)M[i] != (i - i % BlockElts) + (BlockElts - 1 - i % BlockElts))385      return false;386  }387 388  return true;389}390 391} // end namespace llvm392 393#endif // LLVM_LIB_TARGET_ARM_ARMTARGETTRANSFORMINFO_H394