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 154 bool hasConditionalMoveFusion() const { 155 // Do we support fusing a branch+mv or branch+c.mv as a conditional move. 156 return (hasConditionalCompressedMoveFusion() && hasStdExtCOrZca()) || 157 hasShortForwardBranchOpt(); 158 } 159 160 bool is64Bit() const { return IsRV64; } 161 MVT getXLenVT() const { 162 return is64Bit() ? MVT::i64 : MVT::i32; 163 } 164 unsigned getXLen() const { 165 return is64Bit() ? 64 : 32; 166 } 167 unsigned getFLen() const { 168 if (HasStdExtD) 169 return 64; 170 171 if (HasStdExtF) 172 return 32; 173 174 return 0; 175 } 176 unsigned getELen() const { 177 assert(hasVInstructions() && "Expected V extension"); 178 return hasVInstructionsI64() ? 64 : 32; 179 } 180 unsigned getRealMinVLen() const { 181 unsigned VLen = getMinRVVVectorSizeInBits(); 182 return VLen == 0 ? ZvlLen : VLen; 183 } 184 unsigned getRealMaxVLen() const { 185 unsigned VLen = getMaxRVVVectorSizeInBits(); 186 return VLen == 0 ? 65536 : VLen; 187 } 188 RISCVABI::ABI getTargetABI() const { return TargetABI; } 189 bool isSoftFPABI() const { 190 return TargetABI == RISCVABI::ABI_LP64 || 191 TargetABI == RISCVABI::ABI_ILP32 || 192 TargetABI == RISCVABI::ABI_ILP32E; 193 } 194 bool isRegisterReservedByUser(Register i) const { 195 assert(i < RISCV::NUM_TARGET_REGS && "Register out of range"); 196 return UserReservedRegister[i]; 197 } 198 199 bool hasMacroFusion() const { 200 return hasLUIADDIFusion() || hasAUIPCADDIFusion() || hasZExtHFusion() || 201 hasZExtWFusion() || hasShiftedZExtWFusion() || hasLDADDFusion(); 202 } 203 204 // Vector codegen related methods. 205 bool hasVInstructions() const { return HasStdExtZve32x; } 206 bool hasVInstructionsI64() const { return HasStdExtZve64x; } 207 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; } 208 bool hasVInstructionsF16() const { return HasStdExtZvfh; } 209 bool hasVInstructionsBF16() const { return HasStdExtZvfbfmin; } 210 bool hasVInstructionsF32() const { return HasStdExtZve32f; } 211 bool hasVInstructionsF64() const { return HasStdExtZve64d; } 212 // F16 and F64 both require F32. 213 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); } 214 bool hasVInstructionsFullMultiply() const { return HasStdExtV; } 215 unsigned getMaxInterleaveFactor() const { 216 return hasVInstructions() ? MaxInterleaveFactor : 1; 217 } 218 219 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the 220 // vector hardware implementation which may be less than VLEN. 221 unsigned getDLenFactor() const { 222 if (DLenFactor2) 223 return 2; 224 return 1; 225 } 226 227 protected: 228 // GlobalISel related APIs. 229 std::unique_ptr<CallLowering> CallLoweringInfo; 230 std::unique_ptr<InstructionSelector> InstSelector; 231 std::unique_ptr<LegalizerInfo> Legalizer; 232 std::unique_ptr<RegisterBankInfo> RegBankInfo; 233 234 // Return the known range for the bit length of RVV data registers as set 235 // at the command line. A value of 0 means nothing is known about that particular 236 // limit beyond what's implied by the architecture. 237 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead! 238 unsigned getMaxRVVVectorSizeInBits() const; 239 unsigned getMinRVVVectorSizeInBits() const; 240 241 public: 242 const CallLowering *getCallLowering() const override; 243 InstructionSelector *getInstructionSelector() const override; 244 const LegalizerInfo *getLegalizerInfo() const override; 245 const RegisterBankInfo *getRegBankInfo() const override; 246 247 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); } 248 249 bool useConstantPoolForLargeInts() const; 250 251 // Maximum cost used for building integers, integers will be put into constant 252 // pool if exceeded. 253 unsigned getMaxBuildIntsCost() const; 254 255 unsigned getMaxLMULForFixedLengthVectors() const; 256 bool useRVVForFixedLengthVectors() const; 257 258 bool enableSubRegLiveness() const override; 259 260 void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> 261 &Mutations) const override; 262 263 bool useAA() const override; 264 265 unsigned getCacheLineSize() const override { 266 return TuneInfo->CacheLineSize; 267 }; 268 unsigned getPrefetchDistance() const override { 269 return TuneInfo->PrefetchDistance; 270 }; 271 unsigned getMinPrefetchStride(unsigned NumMemAccesses, 272 unsigned NumStridedMemAccesses, 273 unsigned NumPrefetches, 274 bool HasCall) const override { 275 return TuneInfo->MinPrefetchStride; 276 }; 277 unsigned getMaxPrefetchIterationsAhead() const override { 278 return TuneInfo->MaxPrefetchIterationsAhead; 279 }; 280 281 unsigned getMinimumJumpTableEntries() const; 282 }; 283 } // End llvm namespace 284 285 #endif 286