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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares the RISC-V specific subclass of TargetSubtargetInfo. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H 14 #define LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H 15 16 #include "MCTargetDesc/RISCVBaseInfo.h" 17 #include "RISCVFrameLowering.h" 18 #include "RISCVISelLowering.h" 19 #include "RISCVInstrInfo.h" 20 #include "llvm/CodeGen/GlobalISel/CallLowering.h" 21 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 22 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 23 #include "llvm/CodeGen/RegisterBankInfo.h" 24 #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 25 #include "llvm/CodeGen/TargetSubtargetInfo.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/Target/TargetMachine.h" 28 #include <bitset> 29 30 #define GET_SUBTARGETINFO_HEADER 31 #include "RISCVGenSubtargetInfo.inc" 32 33 namespace llvm { 34 class StringRef; 35 36 namespace RISCVTuneInfoTable { 37 38 struct RISCVTuneInfo { 39 const char *Name; 40 uint8_t PrefFunctionAlignment; 41 uint8_t PrefLoopAlignment; 42 43 // Information needed by LoopDataPrefetch. 44 uint16_t CacheLineSize; 45 uint16_t PrefetchDistance; 46 uint16_t MinPrefetchStride; 47 unsigned MaxPrefetchIterationsAhead; 48 49 unsigned MinimumJumpTableEntries; 50 }; 51 52 #define GET_RISCVTuneInfoTable_DECL 53 #include "RISCVGenSearchableTables.inc" 54 } // namespace RISCVTuneInfoTable 55 56 class RISCVSubtarget : public RISCVGenSubtargetInfo { 57 public: 58 // clang-format off 59 enum RISCVProcFamilyEnum : uint8_t { 60 Others, 61 SiFive7, 62 VentanaVeyron, 63 }; 64 // clang-format on 65 private: 66 virtual void anchor(); 67 68 RISCVProcFamilyEnum RISCVProcFamily = Others; 69 70 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 71 bool ATTRIBUTE = DEFAULT; 72 #include "RISCVGenSubtargetInfo.inc" 73 74 unsigned ZvlLen = 0; 75 unsigned RVVVectorBitsMin; 76 unsigned RVVVectorBitsMax; 77 uint8_t MaxInterleaveFactor = 2; 78 RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; 79 std::bitset<RISCV::NUM_TARGET_REGS> UserReservedRegister; 80 const RISCVTuneInfoTable::RISCVTuneInfo *TuneInfo; 81 82 RISCVFrameLowering FrameLowering; 83 RISCVInstrInfo InstrInfo; 84 RISCVRegisterInfo RegInfo; 85 RISCVTargetLowering TLInfo; 86 SelectionDAGTargetInfo TSInfo; 87 88 /// Initializes using the passed in CPU and feature strings so that we can 89 /// use initializer lists for subtarget initialization. 90 RISCVSubtarget &initializeSubtargetDependencies(const Triple &TT, 91 StringRef CPU, 92 StringRef TuneCPU, 93 StringRef FS, 94 StringRef ABIName); 95 96 public: 97 // Initializes the data members to match that of the specified triple. 98 RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, 99 StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin, 100 unsigned RVVVectorLMULMax, const TargetMachine &TM); 101 102 // Parses features string setting specified subtarget options. The 103 // definition of this function is auto-generated by tblgen. 104 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 105 106 const RISCVFrameLowering *getFrameLowering() const override { 107 return &FrameLowering; 108 } 109 const RISCVInstrInfo *getInstrInfo() const override { return &InstrInfo; } 110 const RISCVRegisterInfo *getRegisterInfo() const override { 111 return &RegInfo; 112 } 113 const RISCVTargetLowering *getTargetLowering() const override { 114 return &TLInfo; 115 } 116 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 117 return &TSInfo; 118 } 119 bool enableMachineScheduler() const override { return true; } 120 121 bool enablePostRAScheduler() const override { 122 return getSchedModel().PostRAScheduler || UsePostRAScheduler; 123 } 124 125 Align getPrefFunctionAlignment() const { 126 return Align(TuneInfo->PrefFunctionAlignment); 127 } 128 Align getPrefLoopAlignment() const { 129 return Align(TuneInfo->PrefLoopAlignment); 130 } 131 132 /// Returns RISC-V processor family. 133 /// Avoid this function! CPU specifics should be kept local to this class 134 /// and preferably modeled with SubtargetFeatures or properties in 135 /// initializeProperties(). 136 RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; } 137 138 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ 139 bool GETTER() const { return ATTRIBUTE; } 140 #include "RISCVGenSubtargetInfo.inc" 141 142 bool hasStdExtCOrZca() const { return HasStdExtC || HasStdExtZca; } 143 bool hasStdExtZvl() const { return ZvlLen != 0; } 144 bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; } 145 bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; } 146 bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; } 147 bool hasStdExtZfhminOrZhinxmin() const { 148 return HasStdExtZfhmin || HasStdExtZhinxmin; 149 } 150 bool hasHalfFPLoadStoreMove() const { 151 return HasStdExtZfhmin || HasStdExtZfbfmin; 152 } 153 bool is64Bit() const { return IsRV64; } 154 MVT getXLenVT() const { 155 return is64Bit() ? MVT::i64 : MVT::i32; 156 } 157 unsigned getXLen() const { 158 return is64Bit() ? 64 : 32; 159 } 160 unsigned getFLen() const { 161 if (HasStdExtD) 162 return 64; 163 164 if (HasStdExtF) 165 return 32; 166 167 return 0; 168 } 169 unsigned getELen() const { 170 assert(hasVInstructions() && "Expected V extension"); 171 return hasVInstructionsI64() ? 64 : 32; 172 } 173 unsigned getRealMinVLen() const { 174 unsigned VLen = getMinRVVVectorSizeInBits(); 175 return VLen == 0 ? ZvlLen : VLen; 176 } 177 unsigned getRealMaxVLen() const { 178 unsigned VLen = getMaxRVVVectorSizeInBits(); 179 return VLen == 0 ? 65536 : VLen; 180 } 181 RISCVABI::ABI getTargetABI() const { return TargetABI; } 182 bool isSoftFPABI() const { 183 return TargetABI == RISCVABI::ABI_LP64 || 184 TargetABI == RISCVABI::ABI_ILP32 || 185 TargetABI == RISCVABI::ABI_ILP32E; 186 } 187 bool isRegisterReservedByUser(Register i) const { 188 assert(i < RISCV::NUM_TARGET_REGS && "Register out of range"); 189 return UserReservedRegister[i]; 190 } 191 192 bool hasMacroFusion() const { 193 return hasLUIADDIFusion() || hasAUIPCADDIFusion() || hasZExtHFusion() || 194 hasZExtWFusion() || hasShiftedZExtWFusion() || hasLDADDFusion(); 195 } 196 197 // Vector codegen related methods. 198 bool hasVInstructions() const { return HasStdExtZve32x; } 199 bool hasVInstructionsI64() const { return HasStdExtZve64x; } 200 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; } 201 bool hasVInstructionsF16() const { return HasStdExtZvfh; } 202 bool hasVInstructionsBF16() const { return HasStdExtZvfbfmin; } 203 bool hasVInstructionsF32() const { return HasStdExtZve32f; } 204 bool hasVInstructionsF64() const { return HasStdExtZve64d; } 205 // F16 and F64 both require F32. 206 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); } 207 bool hasVInstructionsFullMultiply() const { return HasStdExtV; } 208 unsigned getMaxInterleaveFactor() const { 209 return hasVInstructions() ? MaxInterleaveFactor : 1; 210 } 211 212 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the 213 // vector hardware implementation which may be less than VLEN. 214 unsigned getDLenFactor() const { 215 if (DLenFactor2) 216 return 2; 217 return 1; 218 } 219 220 protected: 221 // GlobalISel related APIs. 222 std::unique_ptr<CallLowering> CallLoweringInfo; 223 std::unique_ptr<InstructionSelector> InstSelector; 224 std::unique_ptr<LegalizerInfo> Legalizer; 225 std::unique_ptr<RegisterBankInfo> RegBankInfo; 226 227 // Return the known range for the bit length of RVV data registers as set 228 // at the command line. A value of 0 means nothing is known about that particular 229 // limit beyond what's implied by the architecture. 230 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead! 231 unsigned getMaxRVVVectorSizeInBits() const; 232 unsigned getMinRVVVectorSizeInBits() const; 233 234 public: 235 const CallLowering *getCallLowering() const override; 236 InstructionSelector *getInstructionSelector() const override; 237 const LegalizerInfo *getLegalizerInfo() const override; 238 const RegisterBankInfo *getRegBankInfo() const override; 239 240 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); } 241 242 bool useConstantPoolForLargeInts() const; 243 244 // Maximum cost used for building integers, integers will be put into constant 245 // pool if exceeded. 246 unsigned getMaxBuildIntsCost() const; 247 248 unsigned getMaxLMULForFixedLengthVectors() const; 249 bool useRVVForFixedLengthVectors() const; 250 251 bool enableSubRegLiveness() const override; 252 253 void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> 254 &Mutations) const override; 255 256 bool useAA() const override; 257 258 unsigned getCacheLineSize() const override { 259 return TuneInfo->CacheLineSize; 260 }; 261 unsigned getPrefetchDistance() const override { 262 return TuneInfo->PrefetchDistance; 263 }; 264 unsigned getMinPrefetchStride(unsigned NumMemAccesses, 265 unsigned NumStridedMemAccesses, 266 unsigned NumPrefetches, 267 bool HasCall) const override { 268 return TuneInfo->MinPrefetchStride; 269 }; 270 unsigned getMaxPrefetchIterationsAhead() const override { 271 return TuneInfo->MaxPrefetchIterationsAhead; 272 }; 273 274 unsigned getMinimumJumpTableEntries() const; 275 }; 276 } // End llvm namespace 277 278 #endif 279