RISCVSubtarget.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //===-- RISCVSubtarget.cpp - RISCV 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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file implements the RISCV specific subclass of TargetSubtargetInfo.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "RISCVSubtarget.h"
  13. #include "RISCV.h"
  14. #include "RISCVFrameLowering.h"
  15. #include "RISCVMacroFusion.h"
  16. #include "RISCVTargetMachine.h"
  17. #include "GISel/RISCVCallLowering.h"
  18. #include "GISel/RISCVLegalizerInfo.h"
  19. #include "GISel/RISCVRegisterBankInfo.h"
  20. #include "llvm/MC/TargetRegistry.h"
  21. #include "llvm/Support/ErrorHandling.h"
  22. using namespace llvm;
  23. #define DEBUG_TYPE "riscv-subtarget"
  24. #define GET_SUBTARGETINFO_TARGET_DESC
  25. #define GET_SUBTARGETINFO_CTOR
  26. #include "RISCVGenSubtargetInfo.inc"
  27. static cl::opt<bool> EnableSubRegLiveness("riscv-enable-subreg-liveness",
  28. cl::init(false), cl::Hidden);
  29. static cl::opt<unsigned> RVVVectorLMULMax(
  30. "riscv-v-fixed-length-vector-lmul-max",
  31. cl::desc("The maximum LMUL value to use for fixed length vectors. "
  32. "Fractional LMUL values are not supported."),
  33. cl::init(8), cl::Hidden);
  34. static cl::opt<bool> RISCVDisableUsingConstantPoolForLargeInts(
  35. "riscv-disable-using-constant-pool-for-large-ints",
  36. cl::desc("Disable using constant pool for large integers."),
  37. cl::init(false), cl::Hidden);
  38. static cl::opt<unsigned> RISCVMaxBuildIntsCost(
  39. "riscv-max-build-ints-cost",
  40. cl::desc("The maximum cost used for building integers."), cl::init(0),
  41. cl::Hidden);
  42. void RISCVSubtarget::anchor() {}
  43. RISCVSubtarget &
  44. RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
  45. StringRef TuneCPU, StringRef FS,
  46. StringRef ABIName) {
  47. // Determine default and user-specified characteristics
  48. bool Is64Bit = TT.isArch64Bit();
  49. if (CPU.empty() || CPU == "generic")
  50. CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
  51. if (TuneCPU.empty())
  52. TuneCPU = CPU;
  53. ParseSubtargetFeatures(CPU, TuneCPU, FS);
  54. if (Is64Bit) {
  55. XLenVT = MVT::i64;
  56. XLen = 64;
  57. }
  58. TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
  59. RISCVFeatures::validate(TT, getFeatureBits());
  60. return *this;
  61. }
  62. RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
  63. StringRef TuneCPU, StringRef FS,
  64. StringRef ABIName, unsigned RVVVectorBitsMin,
  65. unsigned RVVVectorBitsMax,
  66. const TargetMachine &TM)
  67. : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
  68. RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
  69. FrameLowering(
  70. initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
  71. InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
  72. if (RISCV::isX18ReservedByDefault(TT))
  73. UserReservedRegister.set(RISCV::X18);
  74. CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
  75. Legalizer.reset(new RISCVLegalizerInfo(*this));
  76. auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo());
  77. RegBankInfo.reset(RBI);
  78. InstSelector.reset(createRISCVInstructionSelector(
  79. *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
  80. }
  81. const CallLowering *RISCVSubtarget::getCallLowering() const {
  82. return CallLoweringInfo.get();
  83. }
  84. InstructionSelector *RISCVSubtarget::getInstructionSelector() const {
  85. return InstSelector.get();
  86. }
  87. const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const {
  88. return Legalizer.get();
  89. }
  90. const RegisterBankInfo *RISCVSubtarget::getRegBankInfo() const {
  91. return RegBankInfo.get();
  92. }
  93. bool RISCVSubtarget::useConstantPoolForLargeInts() const {
  94. return !RISCVDisableUsingConstantPoolForLargeInts;
  95. }
  96. unsigned RISCVSubtarget::getMaxBuildIntsCost() const {
  97. // Loading integer from constant pool needs two instructions (the reason why
  98. // the minimum cost is 2): an address calculation instruction and a load
  99. // instruction. Usually, address calculation and instructions used for
  100. // building integers (addi, slli, etc.) can be done in one cycle, so here we
  101. // set the default cost to (LoadLatency + 1) if no threshold is provided.
  102. return RISCVMaxBuildIntsCost == 0
  103. ? getSchedModel().LoadLatency + 1
  104. : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
  105. }
  106. unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const {
  107. assert(hasVInstructions() &&
  108. "Tried to get vector length without Zve or V extension support!");
  109. // ZvlLen specifies the minimum required vlen. The upper bound provided by
  110. // riscv-v-vector-bits-max should be no less than it.
  111. if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
  112. report_fatal_error("riscv-v-vector-bits-max specified is lower "
  113. "than the Zvl*b limitation");
  114. return RVVVectorBitsMax;
  115. }
  116. unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {
  117. assert(hasVInstructions() &&
  118. "Tried to get vector length without Zve or V extension support!");
  119. if (RVVVectorBitsMin == -1U)
  120. return ZvlLen;
  121. // ZvlLen specifies the minimum required vlen. The lower bound provided by
  122. // riscv-v-vector-bits-min should be no less than it.
  123. if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
  124. report_fatal_error("riscv-v-vector-bits-min specified is lower "
  125. "than the Zvl*b limitation");
  126. return RVVVectorBitsMin;
  127. }
  128. unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {
  129. assert(hasVInstructions() &&
  130. "Tried to get vector length without Zve or V extension support!");
  131. assert(RVVVectorLMULMax <= 8 && isPowerOf2_32(RVVVectorLMULMax) &&
  132. "V extension requires a LMUL to be at most 8 and a power of 2!");
  133. return PowerOf2Floor(
  134. std::max<unsigned>(std::min<unsigned>(RVVVectorLMULMax, 8), 1));
  135. }
  136. bool RISCVSubtarget::useRVVForFixedLengthVectors() const {
  137. return hasVInstructions() && getMinRVVVectorSizeInBits() != 0;
  138. }
  139. bool RISCVSubtarget::enableSubRegLiveness() const {
  140. // FIXME: Enable subregister liveness by default for RVV to better handle
  141. // LMUL>1 and segment load/store.
  142. return EnableSubRegLiveness;
  143. }
  144. void RISCVSubtarget::getPostRAMutations(
  145. std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
  146. Mutations.push_back(createRISCVMacroFusionDAGMutation());
  147. }