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-exception 6 // 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 "RISCVTargetMachine.h" 19 #include "llvm/CodeGen/MacroFusion.h" 20 #include "llvm/CodeGen/ScheduleDAGMutation.h" 21 #include "llvm/MC/TargetRegistry.h" 22 #include "llvm/Support/ErrorHandling.h" 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "riscv-subtarget" 27 28 #define GET_SUBTARGETINFO_TARGET_DESC 29 #define GET_SUBTARGETINFO_CTOR 30 #include "RISCVGenSubtargetInfo.inc" 31 32 #define GET_RISCV_MACRO_FUSION_PRED_IMPL 33 #include "RISCVGenMacroFusion.inc" 34 35 namespace llvm::RISCVTuneInfoTable { 36 37 #define GET_RISCVTuneInfoTable_IMPL 38 #include "RISCVGenSearchableTables.inc" 39 } // namespace llvm::RISCVTuneInfoTable 40 41 static cl::opt<unsigned> RVVVectorLMULMax( 42 "riscv-v-fixed-length-vector-lmul-max", 43 cl::desc("The maximum LMUL value to use for fixed length vectors. " 44 "Fractional LMUL values are not supported."), 45 cl::init(8), cl::Hidden); 46 47 static cl::opt<bool> RISCVDisableUsingConstantPoolForLargeInts( 48 "riscv-disable-using-constant-pool-for-large-ints", 49 cl::desc("Disable using constant pool for large integers."), 50 cl::init(false), cl::Hidden); 51 52 static cl::opt<unsigned> RISCVMaxBuildIntsCost( 53 "riscv-max-build-ints-cost", 54 cl::desc("The maximum cost used for building integers."), cl::init(0), 55 cl::Hidden); 56 57 static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true), 58 cl::desc("Enable the use of AA during codegen.")); 59 60 static cl::opt<unsigned> RISCVMinimumJumpTableEntries( 61 "riscv-min-jump-table-entries", cl::Hidden, 62 cl::desc("Set minimum number of entries to use a jump table on RISCV")); 63 64 void RISCVSubtarget::anchor() {} 65 66 RISCVSubtarget & 67 RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU, 68 StringRef TuneCPU, StringRef FS, 69 StringRef ABIName) { 70 // Determine default and user-specified characteristics 71 bool Is64Bit = TT.isArch64Bit(); 72 if (CPU.empty() || CPU == "generic") 73 CPU = Is64Bit ? "generic-rv64" : "generic-rv32"; 74 75 if (TuneCPU.empty()) 76 TuneCPU = CPU; 77 78 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU); 79 // If there is no TuneInfo for this CPU, we fail back to generic. 80 if (!TuneInfo) 81 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic"); 82 assert(TuneInfo && "TuneInfo shouldn't be nullptr!"); 83 84 ParseSubtargetFeatures(CPU, TuneCPU, FS); 85 TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName); 86 RISCVFeatures::validate(TT, getFeatureBits()); 87 return *this; 88 } 89 90 RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU, 91 StringRef TuneCPU, StringRef FS, 92 StringRef ABIName, unsigned RVVVectorBitsMin, 93 unsigned RVVVectorBitsMax, 94 const TargetMachine &TM) 95 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS), 96 RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax), 97 FrameLowering( 98 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)), 99 InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {} 100 101 const CallLowering *RISCVSubtarget::getCallLowering() const { 102 if (!CallLoweringInfo) 103 CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering())); 104 return CallLoweringInfo.get(); 105 } 106 107 InstructionSelector *RISCVSubtarget::getInstructionSelector() const { 108 if (!InstSelector) { 109 InstSelector.reset(createRISCVInstructionSelector( 110 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()), 111 *this, *getRegBankInfo())); 112 } 113 return InstSelector.get(); 114 } 115 116 const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const { 117 if (!Legalizer) 118 Legalizer.reset(new RISCVLegalizerInfo(*this)); 119 return Legalizer.get(); 120 } 121 122 const RISCVRegisterBankInfo *RISCVSubtarget::getRegBankInfo() const { 123 if (!RegBankInfo) 124 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode())); 125 return RegBankInfo.get(); 126 } 127 128 bool RISCVSubtarget::useConstantPoolForLargeInts() const { 129 return !RISCVDisableUsingConstantPoolForLargeInts; 130 } 131 132 unsigned RISCVSubtarget::getMaxBuildIntsCost() const { 133 // Loading integer from constant pool needs two instructions (the reason why 134 // the minimum cost is 2): an address calculation instruction and a load 135 // instruction. Usually, address calculation and instructions used for 136 // building integers (addi, slli, etc.) can be done in one cycle, so here we 137 // set the default cost to (LoadLatency + 1) if no threshold is provided. 138 return RISCVMaxBuildIntsCost == 0 139 ? getSchedModel().LoadLatency + 1 140 : std::max<unsigned>(2, RISCVMaxBuildIntsCost); 141 } 142 143 unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const { 144 assert(hasVInstructions() && 145 "Tried to get vector length without Zve or V extension support!"); 146 147 // ZvlLen specifies the minimum required vlen. The upper bound provided by 148 // riscv-v-vector-bits-max should be no less than it. 149 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen) 150 report_fatal_error("riscv-v-vector-bits-max specified is lower " 151 "than the Zvl*b limitation"); 152 153 return RVVVectorBitsMax; 154 } 155 156 unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const { 157 assert(hasVInstructions() && 158 "Tried to get vector length without Zve or V extension support!"); 159 160 if (RVVVectorBitsMin == -1U) 161 return ZvlLen; 162 163 // ZvlLen specifies the minimum required vlen. The lower bound provided by 164 // riscv-v-vector-bits-min should be no less than it. 165 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen) 166 report_fatal_error("riscv-v-vector-bits-min specified is lower " 167 "than the Zvl*b limitation"); 168 169 return RVVVectorBitsMin; 170 } 171 172 unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const { 173 assert(hasVInstructions() && 174 "Tried to get vector length without Zve or V extension support!"); 175 assert(RVVVectorLMULMax <= 8 && 176 llvm::has_single_bit<uint32_t>(RVVVectorLMULMax) && 177 "V extension requires a LMUL to be at most 8 and a power of 2!"); 178 return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8)); 179 } 180 181 bool RISCVSubtarget::useRVVForFixedLengthVectors() const { 182 return hasVInstructions() && getMinRVVVectorSizeInBits() != 0; 183 } 184 185 bool RISCVSubtarget::enableSubRegLiveness() const { return true; } 186 187 void RISCVSubtarget::getPostRAMutations( 188 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { 189 Mutations.push_back(createMacroFusionDAGMutation(getMacroFusions())); 190 } 191 192 /// Enable use of alias analysis during code generation (during MI 193 /// scheduling, DAGCombine, etc.). 194 bool RISCVSubtarget::useAA() const { return UseAA; } 195 196 unsigned RISCVSubtarget::getMinimumJumpTableEntries() const { 197 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0 198 ? RISCVMinimumJumpTableEntries 199 : TuneInfo->MinimumJumpTableEntries; 200 } 201