brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · f86265a Raw
268 lines · cpp
1//===-- RISCVSubtarget.cpp - RISC-V Subtarget Information -----------------===//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 implements the RISC-V specific subclass of TargetSubtargetInfo.10//11//===----------------------------------------------------------------------===//12 13#include "RISCVSubtarget.h"14#include "GISel/RISCVCallLowering.h"15#include "GISel/RISCVLegalizerInfo.h"16#include "RISCV.h"17#include "RISCVFrameLowering.h"18#include "RISCVSelectionDAGInfo.h"19#include "RISCVTargetMachine.h"20#include "llvm/MC/TargetRegistry.h"21#include "llvm/Support/ErrorHandling.h"22 23using namespace llvm;24 25#define DEBUG_TYPE "riscv-subtarget"26 27#define GET_SUBTARGETINFO_TARGET_DESC28#define GET_SUBTARGETINFO_CTOR29#include "RISCVGenSubtargetInfo.inc"30 31#define GET_RISCV_MACRO_FUSION_PRED_IMPL32#include "RISCVGenMacroFusion.inc"33 34namespace llvm::RISCVTuneInfoTable {35 36#define GET_RISCVTuneInfoTable_IMPL37#include "RISCVGenSearchableTables.inc"38} // namespace llvm::RISCVTuneInfoTable39 40static cl::opt<unsigned> RVVVectorLMULMax(41    "riscv-v-fixed-length-vector-lmul-max",42    cl::desc("The maximum LMUL value to use for fixed length vectors. "43             "Fractional LMUL values are not supported."),44    cl::init(8), cl::Hidden);45 46static cl::opt<bool> RISCVDisableUsingConstantPoolForLargeInts(47    "riscv-disable-using-constant-pool-for-large-ints",48    cl::desc("Disable using constant pool for large integers."),49    cl::init(false), cl::Hidden);50 51static cl::opt<unsigned> RISCVMaxBuildIntsCost(52    "riscv-max-build-ints-cost",53    cl::desc("The maximum cost used for building integers."), cl::init(0),54    cl::Hidden);55 56static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),57                           cl::desc("Enable the use of AA during codegen."));58 59static cl::opt<unsigned> RISCVMinimumJumpTableEntries(60    "riscv-min-jump-table-entries", cl::Hidden,61    cl::desc("Set minimum number of entries to use a jump table on RISCV"));62 63static cl::opt<bool> UseMIPSLoadStorePairsOpt(64    "use-riscv-mips-load-store-pairs",65    cl::desc("Enable the load/store pair optimization pass"), cl::init(false),66    cl::Hidden);67 68static cl::opt<bool> UseMIPSCCMovInsn("use-riscv-mips-ccmov",69                                      cl::desc("Use 'mips.ccmov' instruction"),70                                      cl::init(true), cl::Hidden);71 72static cl::opt<bool> EnablePExtCodeGen(73    "enable-p-ext-codegen",74    cl::desc("Turn on P Extension codegen(This is a temporary switch where "75             "only partial codegen is currently supported)"),76    cl::init(false), cl::Hidden);77 78void RISCVSubtarget::anchor() {}79 80RISCVSubtarget &81RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,82                                                StringRef TuneCPU, StringRef FS,83                                                StringRef ABIName) {84  // Determine default and user-specified characteristics85  bool Is64Bit = TT.isArch64Bit();86  if (CPU.empty() || CPU == "generic")87    CPU = Is64Bit ? "generic-rv64" : "generic-rv32";88 89  if (TuneCPU.empty())90    TuneCPU = CPU;91  if (TuneCPU == "generic")92    TuneCPU = Is64Bit ? "generic-rv64" : "generic-rv32";93 94  TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);95  // If there is no TuneInfo for this CPU, we fail back to generic.96  if (!TuneInfo)97    TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");98  assert(TuneInfo && "TuneInfo shouldn't be nullptr!");99 100  ParseSubtargetFeatures(CPU, TuneCPU, FS);101  TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);102  RISCVFeatures::validate(TT, getFeatureBits());103  return *this;104}105 106RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,107                               StringRef TuneCPU, StringRef FS,108                               StringRef ABIName, unsigned RVVVectorBitsMin,109                               unsigned RVVVectorBitsMax,110                               const TargetMachine &TM)111    : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),112      RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),113      FrameLowering(114          initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),115      InstrInfo(*this), TLInfo(TM, *this) {116  TSInfo = std::make_unique<RISCVSelectionDAGInfo>();117}118 119RISCVSubtarget::~RISCVSubtarget() = default;120 121const SelectionDAGTargetInfo *RISCVSubtarget::getSelectionDAGInfo() const {122  return TSInfo.get();123}124 125const CallLowering *RISCVSubtarget::getCallLowering() const {126  if (!CallLoweringInfo)127    CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));128  return CallLoweringInfo.get();129}130 131InstructionSelector *RISCVSubtarget::getInstructionSelector() const {132  if (!InstSelector) {133    InstSelector.reset(createRISCVInstructionSelector(134        *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),135        *this, *getRegBankInfo()));136  }137  return InstSelector.get();138}139 140const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const {141  if (!Legalizer)142    Legalizer.reset(new RISCVLegalizerInfo(*this));143  return Legalizer.get();144}145 146const RISCVRegisterBankInfo *RISCVSubtarget::getRegBankInfo() const {147  if (!RegBankInfo)148    RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));149  return RegBankInfo.get();150}151 152bool RISCVSubtarget::useConstantPoolForLargeInts() const {153  return !RISCVDisableUsingConstantPoolForLargeInts;154}155 156bool RISCVSubtarget::enablePExtCodeGen() const {157  return HasStdExtP && EnablePExtCodeGen;158}159 160unsigned RISCVSubtarget::getMaxBuildIntsCost() const {161  // Loading integer from constant pool needs two instructions (the reason why162  // the minimum cost is 2): an address calculation instruction and a load163  // instruction. Usually, address calculation and instructions used for164  // building integers (addi, slli, etc.) can be done in one cycle, so here we165  // set the default cost to (LoadLatency + 1) if no threshold is provided.166  return RISCVMaxBuildIntsCost == 0167             ? getSchedModel().LoadLatency + 1168             : std::max<unsigned>(2, RISCVMaxBuildIntsCost);169}170 171unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const {172  assert(hasVInstructions() &&173         "Tried to get vector length without Zve or V extension support!");174 175  // ZvlLen specifies the minimum required vlen. The upper bound provided by176  // riscv-v-vector-bits-max should be no less than it.177  if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)178    report_fatal_error("riscv-v-vector-bits-max specified is lower "179                       "than the Zvl*b limitation");180 181  return RVVVectorBitsMax;182}183 184unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {185  assert(hasVInstructions() &&186         "Tried to get vector length without Zve or V extension support!");187 188  if (RVVVectorBitsMin == -1U)189    return ZvlLen;190 191  // ZvlLen specifies the minimum required vlen. The lower bound provided by192  // riscv-v-vector-bits-min should be no less than it.193  if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)194    report_fatal_error("riscv-v-vector-bits-min specified is lower "195                       "than the Zvl*b limitation");196 197  return RVVVectorBitsMin;198}199 200unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {201  assert(hasVInstructions() &&202         "Tried to get vector length without Zve or V extension support!");203  assert(RVVVectorLMULMax <= 8 &&204         llvm::has_single_bit<uint32_t>(RVVVectorLMULMax) &&205         "V extension requires a LMUL to be at most 8 and a power of 2!");206  return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8));207}208 209bool RISCVSubtarget::useRVVForFixedLengthVectors() const {210  return hasVInstructions() &&211         getMinRVVVectorSizeInBits() >= RISCV::RVVBitsPerBlock;212}213 214bool RISCVSubtarget::enableSubRegLiveness() const { return true; }215 216bool RISCVSubtarget::enableMachinePipeliner() const {217  return getSchedModel().hasInstrSchedModel();218}219 220  /// Enable use of alias analysis during code generation (during MI221  /// scheduling, DAGCombine, etc.).222bool RISCVSubtarget::useAA() const { return UseAA; }223 224unsigned RISCVSubtarget::getMinimumJumpTableEntries() const {225  return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0226             ? RISCVMinimumJumpTableEntries227             : TuneInfo->MinimumJumpTableEntries;228}229 230void RISCVSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,231                                         const SchedRegion &Region) const {232  // Do bidirectional scheduling since it provides a more balanced scheduling233  // leading to better performance. This will increase compile time.234  Policy.OnlyTopDown = false;235  Policy.OnlyBottomUp = false;236 237  // Disabling the latency heuristic can reduce the number of spills/reloads but238  // will cause some regressions on some cores.239  Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;240 241  // Spilling is generally expensive on all RISC-V cores, so always enable242  // register-pressure tracking. This will increase compile time.243  Policy.ShouldTrackPressure = true;244}245 246void RISCVSubtarget::overridePostRASchedPolicy(247    MachineSchedPolicy &Policy, const SchedRegion &Region) const {248  MISched::Direction PostRASchedDirection = getPostRASchedDirection();249  if (PostRASchedDirection == MISched::TopDown) {250    Policy.OnlyTopDown = true;251    Policy.OnlyBottomUp = false;252  } else if (PostRASchedDirection == MISched::BottomUp) {253    Policy.OnlyTopDown = false;254    Policy.OnlyBottomUp = true;255  } else if (PostRASchedDirection == MISched::Bidirectional) {256    Policy.OnlyTopDown = false;257    Policy.OnlyBottomUp = false;258  }259}260 261bool RISCVSubtarget::useMIPSLoadStorePairs() const {262  return UseMIPSLoadStorePairsOpt && HasVendorXMIPSLSP;263}264 265bool RISCVSubtarget::useMIPSCCMovInsn() const {266  return UseMIPSCCMovInsn && HasVendorXMIPSCMov;267}268