xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVSubtarget.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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