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