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