brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.5 KiB · c16b23e Raw
445 lines · c
1//===-- RISCVSubtarget.h - Define Subtarget for the RISC-V ------*- 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// This file declares the RISC-V specific subclass of TargetSubtargetInfo.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H14#define LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H15 16#include "GISel/RISCVRegisterBankInfo.h"17#include "MCTargetDesc/RISCVBaseInfo.h"18#include "RISCVFrameLowering.h"19#include "RISCVISelLowering.h"20#include "RISCVInstrInfo.h"21#include "llvm/CodeGen/GlobalISel/CallLowering.h"22#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"23#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"24#include "llvm/CodeGen/MachineScheduler.h"25#include "llvm/CodeGen/TargetSubtargetInfo.h"26#include "llvm/IR/DataLayout.h"27#include "llvm/Support/Compiler.h"28#include "llvm/Target/TargetMachine.h"29#include <bitset>30 31#define GET_RISCV_MACRO_FUSION_PRED_DECL32#include "RISCVGenMacroFusion.inc"33 34#define GET_SUBTARGETINFO_HEADER35#include "RISCVGenSubtargetInfo.inc"36 37namespace llvm {38class StringRef;39 40namespace RISCVTuneInfoTable {41 42struct RISCVTuneInfo {43  const char *Name;44  uint8_t PrefFunctionAlignment;45  uint8_t PrefLoopAlignment;46 47  // Information needed by LoopDataPrefetch.48  uint16_t CacheLineSize;49  uint16_t PrefetchDistance;50  uint16_t MinPrefetchStride;51  unsigned MaxPrefetchIterationsAhead;52 53  unsigned MinimumJumpTableEntries;54 55  // Tail duplication threshold at -O3.56  unsigned TailDupAggressiveThreshold;57 58  unsigned MaxStoresPerMemsetOptSize;59  unsigned MaxStoresPerMemset;60 61  unsigned MaxGluedStoresPerMemcpy;62  unsigned MaxStoresPerMemcpyOptSize;63  unsigned MaxStoresPerMemcpy;64 65  unsigned MaxStoresPerMemmoveOptSize;66  unsigned MaxStoresPerMemmove;67 68  unsigned MaxLoadsPerMemcmpOptSize;69  unsigned MaxLoadsPerMemcmp;70 71  // The direction of PostRA scheduling.72  MISched::Direction PostRASchedDirection;73};74 75#define GET_RISCVTuneInfoTable_DECL76#include "RISCVGenSearchableTables.inc"77} // namespace RISCVTuneInfoTable78 79class RISCVSubtarget : public RISCVGenSubtargetInfo {80public:81  // clang-format off82  enum RISCVProcFamilyEnum : uint8_t {83    Others,84    SiFive7,85    VentanaVeyron,86    MIPSP8700,87    Andes45,88  };89  enum RISCVVRGatherCostModelEnum : uint8_t {90    Quadratic,91    NLog2N,92  };93  // clang-format on94private:95  virtual void anchor();96 97  RISCVProcFamilyEnum RISCVProcFamily = Others;98  RISCVVRGatherCostModelEnum RISCVVRGatherCostModel = Quadratic;99 100#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \101  bool ATTRIBUTE = DEFAULT;102#include "RISCVGenSubtargetInfo.inc"103 104  unsigned XSfmmTE = 0;105  unsigned ZvlLen = 0;106  unsigned RVVVectorBitsMin;107  unsigned RVVVectorBitsMax;108  uint8_t MaxInterleaveFactor = 2;109  RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;110  std::bitset<RISCV::NUM_TARGET_REGS> UserReservedRegister;111  const RISCVTuneInfoTable::RISCVTuneInfo *TuneInfo;112 113  RISCVFrameLowering FrameLowering;114  RISCVInstrInfo InstrInfo;115  RISCVTargetLowering TLInfo;116 117  /// Initializes using the passed in CPU and feature strings so that we can118  /// use initializer lists for subtarget initialization.119  RISCVSubtarget &initializeSubtargetDependencies(const Triple &TT,120                                                  StringRef CPU,121                                                  StringRef TuneCPU,122                                                  StringRef FS,123                                                  StringRef ABIName);124 125public:126  // Initializes the data members to match that of the specified triple.127  RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,128                 StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin,129                 unsigned RVVVectorLMULMax, const TargetMachine &TM);130 131  ~RISCVSubtarget() override;132 133  // Parses features string setting specified subtarget options. The134  // definition of this function is auto-generated by tblgen.135  void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);136 137  const RISCVFrameLowering *getFrameLowering() const override {138    return &FrameLowering;139  }140  const RISCVInstrInfo *getInstrInfo() const override { return &InstrInfo; }141  const RISCVRegisterInfo *getRegisterInfo() const override {142    return &InstrInfo.getRegisterInfo();143  }144  const RISCVTargetLowering *getTargetLowering() const override {145    return &TLInfo;146  }147 148  bool enableMachineScheduler() const override { return true; }149 150  bool enablePostRAScheduler() const override { return UsePostRAScheduler; }151 152  Align getPrefFunctionAlignment() const {153    return Align(TuneInfo->PrefFunctionAlignment);154  }155  Align getPrefLoopAlignment() const {156    return Align(TuneInfo->PrefLoopAlignment);157  }158 159  /// Returns RISC-V processor family.160  /// Avoid this function! CPU specifics should be kept local to this class161  /// and preferably modeled with SubtargetFeatures or properties in162  /// initializeProperties().163  RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }164 165  RISCVVRGatherCostModelEnum getVRGatherCostModel() const { return RISCVVRGatherCostModel; }166 167#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \168  bool GETTER() const { return ATTRIBUTE; }169#include "RISCVGenSubtargetInfo.inc"170 171  LLVM_DEPRECATED("Now Equivalent to hasStdExtZca", "hasStdExtZca")172  bool hasStdExtCOrZca() const { return HasStdExtZca; }173  bool hasStdExtCOrZcd() const { return HasStdExtC || HasStdExtZcd; }174  bool hasStdExtCOrZcfOrZce() const {175    return HasStdExtC || HasStdExtZcf || HasStdExtZce;176  }177  bool hasStdExtZvl() const { return ZvlLen != 0; }178  bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; }179  bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; }180  bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; }181  bool hasStdExtZfhminOrZhinxmin() const {182    return HasStdExtZfhmin || HasStdExtZhinxmin;183  }184  bool hasHalfFPLoadStoreMove() const {185    return HasStdExtZfhmin || HasStdExtZfbfmin;186  }187 188  bool hasCLZLike() const {189    return HasStdExtZbb || HasStdExtP || HasVendorXTHeadBb ||190           (HasVendorXCVbitmanip && !IsRV64);191  }192  bool hasCTZLike() const {193    return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);194  }195  bool hasCPOPLike() const {196    return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);197  }198  bool hasREV8Like() const {199    return HasStdExtZbb || HasStdExtZbkb || HasStdExtP || HasVendorXTHeadBb;200  }201 202  bool hasBEXTILike() const { return HasStdExtZbs || HasVendorXTHeadBs; }203 204  bool hasCZEROLike() const {205    return HasStdExtZicond || HasVendorXVentanaCondOps;206  }207 208  bool hasConditionalMoveFusion() const {209    // Do we support fusing a branch+mv or branch+c.mv as a conditional move.210    return (hasConditionalCompressedMoveFusion() && hasStdExtZca()) ||211           hasShortForwardBranchIALU();212  }213 214  bool hasShlAdd(int64_t ShAmt) const {215    if (ShAmt <= 0)216      return false;217    if (ShAmt <= 3)218      return HasStdExtZba || HasVendorXAndesPerf || HasVendorXTHeadBa;219    return ShAmt <= 31 && HasVendorXqciac;220  }221 222  bool is64Bit() const { return IsRV64; }223  MVT getXLenVT() const {224    return is64Bit() ? MVT::i64 : MVT::i32;225  }226  unsigned getXLen() const {227    return is64Bit() ? 64 : 32;228  }229  bool useMIPSLoadStorePairs() const;230  bool useMIPSCCMovInsn() const;231  unsigned getFLen() const {232    if (HasStdExtD)233      return 64;234 235    if (HasStdExtF)236      return 32;237 238    return 0;239  }240 241  Align getZilsdAlign() const {242    return Align(enableUnalignedScalarMem() ? 1243                 : allowZilsd4ByteAlign()   ? 4244                                            : 8);245  }246 247  unsigned getELen() const {248    assert(hasVInstructions() && "Expected V extension");249    return hasVInstructionsI64() ? 64 : 32;250  }251  unsigned getRealMinVLen() const {252    unsigned VLen = getMinRVVVectorSizeInBits();253    return VLen == 0 ? ZvlLen : VLen;254  }255  unsigned getRealMaxVLen() const {256    unsigned VLen = getMaxRVVVectorSizeInBits();257    return VLen == 0 ? 65536 : VLen;258  }259  // If we know the exact VLEN, return it.  Otherwise, return std::nullopt.260  std::optional<unsigned> getRealVLen() const {261    unsigned Min = getRealMinVLen();262    if (Min != getRealMaxVLen())263      return std::nullopt;264    return Min;265  }266 267  /// If the ElementCount or TypeSize \p X is scalable and VScale (VLEN) is268  /// exactly known, returns \p X converted to a fixed quantity. Otherwise269  /// returns \p X unmodified.270  template <typename Quantity> Quantity expandVScale(Quantity X) const {271    if (auto VLen = getRealVLen(); VLen && X.isScalable()) {272      const unsigned VScale = *VLen / RISCV::RVVBitsPerBlock;273      X = Quantity::getFixed(X.getKnownMinValue() * VScale);274    }275    return X;276  }277 278  RISCVABI::ABI getTargetABI() const { return TargetABI; }279  bool isSoftFPABI() const {280    return TargetABI == RISCVABI::ABI_LP64 ||281           TargetABI == RISCVABI::ABI_ILP32 ||282           TargetABI == RISCVABI::ABI_ILP32E;283  }284  bool isRegisterReservedByUser(Register i) const override {285    assert(i.id() < RISCV::NUM_TARGET_REGS && "Register out of range");286    return UserReservedRegister[i.id()];287  }288 289  // XRay support - require D and C extensions.290  bool isXRaySupported() const override { return hasStdExtD() && hasStdExtC(); }291 292  // Vector codegen related methods.293  bool hasVInstructions() const { return HasStdExtZve32x; }294  bool hasVInstructionsI64() const { return HasStdExtZve64x; }295  bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }296  bool hasVInstructionsF16() const { return HasStdExtZvfh; }297  bool hasVInstructionsBF16Minimal() const {298    return HasStdExtZvfbfmin || HasStdExtZvfbfa;299  }300  bool hasVInstructionsF32() const { return HasStdExtZve32f; }301  bool hasVInstructionsF64() const { return HasStdExtZve64d; }302  bool hasVInstructionsBF16() const { return HasStdExtZvfbfa; }303  // F16 and F64 both require F32.304  bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }305  bool hasVInstructionsFullMultiply() const { return HasStdExtV; }306  unsigned getMaxInterleaveFactor() const {307    return hasVInstructions() ? MaxInterleaveFactor : 1;308  }309 310  bool hasOptimizedSegmentLoadStore(unsigned NF) const {311    switch (NF) {312    case 2:313      return hasOptimizedNF2SegmentLoadStore();314    case 3:315      return hasOptimizedNF3SegmentLoadStore();316    case 4:317      return hasOptimizedNF4SegmentLoadStore();318    case 5:319      return hasOptimizedNF5SegmentLoadStore();320    case 6:321      return hasOptimizedNF6SegmentLoadStore();322    case 7:323      return hasOptimizedNF7SegmentLoadStore();324    case 8:325      return hasOptimizedNF8SegmentLoadStore();326    default:327      llvm_unreachable("Unexpected NF");328    }329  }330 331  bool enablePExtCodeGen() const;332 333  // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the334  // vector hardware implementation which may be less than VLEN.335  unsigned getDLenFactor() const {336    if (DLenFactor2)337      return 2;338    return 1;339  }340 341protected:342  // SelectionDAGISel related APIs.343  std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;344 345  // GlobalISel related APIs.346  mutable std::unique_ptr<CallLowering> CallLoweringInfo;347  mutable std::unique_ptr<InstructionSelector> InstSelector;348  mutable std::unique_ptr<LegalizerInfo> Legalizer;349  mutable std::unique_ptr<RISCVRegisterBankInfo> RegBankInfo;350 351  // Return the known range for the bit length of RVV data registers as set352  // at the command line. A value of 0 means nothing is known about that particular353  // limit beyond what's implied by the architecture.354  // NOTE: Please use getRealMinVLen and getRealMaxVLen instead!355  unsigned getMaxRVVVectorSizeInBits() const;356  unsigned getMinRVVVectorSizeInBits() const;357 358public:359  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;360  const CallLowering *getCallLowering() const override;361  InstructionSelector *getInstructionSelector() const override;362  const LegalizerInfo *getLegalizerInfo() const override;363  const RISCVRegisterBankInfo *getRegBankInfo() const override;364 365  bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }366  bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }367 368  bool useConstantPoolForLargeInts() const;369 370  // Maximum cost used for building integers, integers will be put into constant371  // pool if exceeded.372  unsigned getMaxBuildIntsCost() const;373 374  unsigned getMaxLMULForFixedLengthVectors() const;375  bool useRVVForFixedLengthVectors() const;376 377  bool enableSubRegLiveness() const override;378 379  bool enableMachinePipeliner() const override;380 381  bool useDFAforSMS() const override { return false; }382 383  bool useAA() const override;384 385  unsigned getCacheLineSize() const override {386    return TuneInfo->CacheLineSize;387  };388  unsigned getPrefetchDistance() const override {389    return TuneInfo->PrefetchDistance;390  };391  unsigned getMinPrefetchStride(unsigned NumMemAccesses,392                                unsigned NumStridedMemAccesses,393                                unsigned NumPrefetches,394                                bool HasCall) const override {395    return TuneInfo->MinPrefetchStride;396  };397  unsigned getMaxPrefetchIterationsAhead() const override {398    return TuneInfo->MaxPrefetchIterationsAhead;399  };400  bool enableWritePrefetching() const override { return true; }401 402  unsigned getMinimumJumpTableEntries() const;403 404  unsigned getTailDupAggressiveThreshold() const {405    return TuneInfo->TailDupAggressiveThreshold;406  }407 408  unsigned getMaxStoresPerMemset(bool OptSize) const {409    return OptSize ? TuneInfo->MaxStoresPerMemsetOptSize410                   : TuneInfo->MaxStoresPerMemset;411  }412 413  unsigned getMaxGluedStoresPerMemcpy() const {414    return TuneInfo->MaxGluedStoresPerMemcpy;415  }416 417  unsigned getMaxStoresPerMemcpy(bool OptSize) const {418    return OptSize ? TuneInfo->MaxStoresPerMemcpyOptSize419                   : TuneInfo->MaxStoresPerMemcpy;420  }421 422  unsigned getMaxStoresPerMemmove(bool OptSize) const {423    return OptSize ? TuneInfo->MaxStoresPerMemmoveOptSize424                   : TuneInfo->MaxStoresPerMemmove;425  }426 427  unsigned getMaxLoadsPerMemcmp(bool OptSize) const {428    return OptSize ? TuneInfo->MaxLoadsPerMemcmpOptSize429                   : TuneInfo->MaxLoadsPerMemcmp;430  }431 432  MISched::Direction getPostRASchedDirection() const {433    return TuneInfo->PostRASchedDirection;434  }435 436  void overrideSchedPolicy(MachineSchedPolicy &Policy,437                           const SchedRegion &Region) const override;438 439  void overridePostRASchedPolicy(MachineSchedPolicy &Policy,440                                 const SchedRegion &Region) const override;441};442} // namespace llvm443 444#endif445