LLVM 20.0.0git
RISCVSubtarget.h
Go to the documentation of this file.
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
18#include "RISCVFrameLowering.h"
19#include "RISCVISelLowering.h"
20#include "RISCVInstrInfo.h"
26#include "llvm/IR/DataLayout.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
36namespace llvm {
37class StringRef;
38
39namespace RISCVTuneInfoTable {
40
42 const char *Name;
45
46 // Information needed by LoopDataPrefetch.
51
53
54 // Tail duplication threshold at -O3.
56
59
63
66
69
70 // The direction of PostRA scheduling.
72};
73
74#define GET_RISCVTuneInfoTable_DECL
75#include "RISCVGenSearchableTables.inc"
76} // namespace RISCVTuneInfoTable
77
79public:
80 // clang-format off
86 };
87 // clang-format on
88private:
89 virtual void anchor();
90
91 RISCVProcFamilyEnum RISCVProcFamily = Others;
92
93#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
94 bool ATTRIBUTE = DEFAULT;
95#include "RISCVGenSubtargetInfo.inc"
96
97 unsigned ZvlLen = 0;
98 unsigned RVVVectorBitsMin;
99 unsigned RVVVectorBitsMax;
100 uint8_t MaxInterleaveFactor = 2;
102 std::bitset<RISCV::NUM_TARGET_REGS> UserReservedRegister;
103 const RISCVTuneInfoTable::RISCVTuneInfo *TuneInfo;
104
105 RISCVFrameLowering FrameLowering;
106 RISCVInstrInfo InstrInfo;
108 RISCVTargetLowering TLInfo;
109
110 /// Initializes using the passed in CPU and feature strings so that we can
111 /// use initializer lists for subtarget initialization.
112 RISCVSubtarget &initializeSubtargetDependencies(const Triple &TT,
113 StringRef CPU,
114 StringRef TuneCPU,
115 StringRef FS,
116 StringRef ABIName);
117
118public:
119 // Initializes the data members to match that of the specified triple.
120 RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
121 StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin,
122 unsigned RVVVectorLMULMax, const TargetMachine &TM);
123
124 ~RISCVSubtarget() override;
125
126 // Parses features string setting specified subtarget options. The
127 // definition of this function is auto-generated by tblgen.
129
130 const RISCVFrameLowering *getFrameLowering() const override {
131 return &FrameLowering;
132 }
133 const RISCVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
134 const RISCVRegisterInfo *getRegisterInfo() const override {
135 return &RegInfo;
136 }
137 const RISCVTargetLowering *getTargetLowering() const override {
138 return &TLInfo;
139 }
140
141 bool enableMachineScheduler() const override { return true; }
142
143 bool enablePostRAScheduler() const override { return UsePostRAScheduler; }
144
146 return Align(TuneInfo->PrefFunctionAlignment);
147 }
149 return Align(TuneInfo->PrefLoopAlignment);
150 }
151
152 /// Returns RISC-V processor family.
153 /// Avoid this function! CPU specifics should be kept local to this class
154 /// and preferably modeled with SubtargetFeatures or properties in
155 /// initializeProperties().
156 RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }
157
158#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
159 bool GETTER() const { return ATTRIBUTE; }
160#include "RISCVGenSubtargetInfo.inc"
161
162 bool hasStdExtCOrZca() const { return HasStdExtC || HasStdExtZca; }
163 bool hasStdExtCOrZcd() const { return HasStdExtC || HasStdExtZcd; }
164 bool hasStdExtCOrZcfOrZce() const {
165 return HasStdExtC || HasStdExtZcf || HasStdExtZce;
166 }
167 bool hasStdExtZvl() const { return ZvlLen != 0; }
168 bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; }
169 bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; }
170 bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; }
172 return HasStdExtZfhmin || HasStdExtZhinxmin;
173 }
175 return HasStdExtZfhmin || HasStdExtZfbfmin;
176 }
177
179 // Do we support fusing a branch+mv or branch+c.mv as a conditional move.
180 return (hasConditionalCompressedMoveFusion() && hasStdExtCOrZca()) ||
181 hasShortForwardBranchOpt();
182 }
183
184 bool is64Bit() const { return IsRV64; }
185 MVT getXLenVT() const {
186 return is64Bit() ? MVT::i64 : MVT::i32;
187 }
188 unsigned getXLen() const {
189 return is64Bit() ? 64 : 32;
190 }
191 unsigned getFLen() const {
192 if (HasStdExtD)
193 return 64;
194
195 if (HasStdExtF)
196 return 32;
197
198 return 0;
199 }
200 unsigned getELen() const {
201 assert(hasVInstructions() && "Expected V extension");
202 return hasVInstructionsI64() ? 64 : 32;
203 }
204 unsigned getRealMinVLen() const {
205 unsigned VLen = getMinRVVVectorSizeInBits();
206 return VLen == 0 ? ZvlLen : VLen;
207 }
208 unsigned getRealMaxVLen() const {
209 unsigned VLen = getMaxRVVVectorSizeInBits();
210 return VLen == 0 ? 65536 : VLen;
211 }
212 // If we know the exact VLEN, return it. Otherwise, return std::nullopt.
213 std::optional<unsigned> getRealVLen() const {
214 unsigned Min = getRealMinVLen();
215 if (Min != getRealMaxVLen())
216 return std::nullopt;
217 return Min;
218 }
219
220 /// If the ElementCount or TypeSize \p X is scalable and VScale (VLEN) is
221 /// exactly known, returns \p X converted to a fixed quantity. Otherwise
222 /// returns \p X unmodified.
223 template <typename Quantity> Quantity expandVScale(Quantity X) const {
224 if (auto VLen = getRealVLen(); VLen && X.isScalable()) {
225 const unsigned VScale = *VLen / RISCV::RVVBitsPerBlock;
226 X = Quantity::getFixed(X.getKnownMinValue() * VScale);
227 }
228 return X;
229 }
230
231 RISCVABI::ABI getTargetABI() const { return TargetABI; }
232 bool isSoftFPABI() const {
233 return TargetABI == RISCVABI::ABI_LP64 ||
234 TargetABI == RISCVABI::ABI_ILP32 ||
235 TargetABI == RISCVABI::ABI_ILP32E;
236 }
237 bool isRegisterReservedByUser(Register i) const override {
238 assert(i < RISCV::NUM_TARGET_REGS && "Register out of range");
239 return UserReservedRegister[i];
240 }
241
242 // XRay support - require D and C extensions.
243 bool isXRaySupported() const override { return hasStdExtD() && hasStdExtC(); }
244
245 // Vector codegen related methods.
246 bool hasVInstructions() const { return HasStdExtZve32x; }
247 bool hasVInstructionsI64() const { return HasStdExtZve64x; }
248 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }
249 bool hasVInstructionsF16() const { return HasStdExtZvfh; }
250 bool hasVInstructionsBF16Minimal() const { return HasStdExtZvfbfmin; }
251 bool hasVInstructionsF32() const { return HasStdExtZve32f; }
252 bool hasVInstructionsF64() const { return HasStdExtZve64d; }
253 // F16 and F64 both require F32.
254 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }
255 bool hasVInstructionsFullMultiply() const { return HasStdExtV; }
256 unsigned getMaxInterleaveFactor() const {
257 return hasVInstructions() ? MaxInterleaveFactor : 1;
258 }
259
260 bool hasOptimizedSegmentLoadStore(unsigned NF) const {
261 switch (NF) {
262 case 2:
263 return hasOptimizedNF2SegmentLoadStore();
264 case 3:
265 return hasOptimizedNF3SegmentLoadStore();
266 case 4:
267 return hasOptimizedNF4SegmentLoadStore();
268 case 5:
269 return hasOptimizedNF5SegmentLoadStore();
270 case 6:
271 return hasOptimizedNF6SegmentLoadStore();
272 case 7:
273 return hasOptimizedNF7SegmentLoadStore();
274 case 8:
275 return hasOptimizedNF8SegmentLoadStore();
276 default:
277 llvm_unreachable("Unexpected NF");
278 }
279 }
280
281 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the
282 // vector hardware implementation which may be less than VLEN.
283 unsigned getDLenFactor() const {
284 if (DLenFactor2)
285 return 2;
286 return 1;
287 }
288
289protected:
290 // SelectionDAGISel related APIs.
291 std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
292
293 // GlobalISel related APIs.
294 mutable std::unique_ptr<CallLowering> CallLoweringInfo;
295 mutable std::unique_ptr<InstructionSelector> InstSelector;
296 mutable std::unique_ptr<LegalizerInfo> Legalizer;
297 mutable std::unique_ptr<RISCVRegisterBankInfo> RegBankInfo;
298
299 // Return the known range for the bit length of RVV data registers as set
300 // at the command line. A value of 0 means nothing is known about that particular
301 // limit beyond what's implied by the architecture.
302 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead!
303 unsigned getMaxRVVVectorSizeInBits() const;
304 unsigned getMinRVVVectorSizeInBits() const;
305
306public:
307 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
308 const CallLowering *getCallLowering() const override;
310 const LegalizerInfo *getLegalizerInfo() const override;
311 const RISCVRegisterBankInfo *getRegBankInfo() const override;
312
313 bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }
314 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
315
316 bool useConstantPoolForLargeInts() const;
317
318 // Maximum cost used for building integers, integers will be put into constant
319 // pool if exceeded.
320 unsigned getMaxBuildIntsCost() const;
321
322 unsigned getMaxLMULForFixedLengthVectors() const;
323 bool useRVVForFixedLengthVectors() const;
324
325 bool enableSubRegLiveness() const override;
326
327 bool enableMachinePipeliner() const override;
328
329 bool useDFAforSMS() const override { return false; }
330
331 bool useAA() const override;
332
333 unsigned getCacheLineSize() const override {
334 return TuneInfo->CacheLineSize;
335 };
336 unsigned getPrefetchDistance() const override {
337 return TuneInfo->PrefetchDistance;
338 };
339 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
340 unsigned NumStridedMemAccesses,
341 unsigned NumPrefetches,
342 bool HasCall) const override {
343 return TuneInfo->MinPrefetchStride;
344 };
345 unsigned getMaxPrefetchIterationsAhead() const override {
346 return TuneInfo->MaxPrefetchIterationsAhead;
347 };
348
349 unsigned getMinimumJumpTableEntries() const;
350
352 return TuneInfo->TailDupAggressiveThreshold;
353 }
354
355 unsigned getMaxStoresPerMemset(bool OptSize) const {
356 return OptSize ? TuneInfo->MaxStoresPerMemsetOptSize
357 : TuneInfo->MaxStoresPerMemset;
358 }
359
360 unsigned getMaxGluedStoresPerMemcpy() const {
361 return TuneInfo->MaxGluedStoresPerMemcpy;
362 }
363
364 unsigned getMaxStoresPerMemcpy(bool OptSize) const {
365 return OptSize ? TuneInfo->MaxStoresPerMemcpyOptSize
366 : TuneInfo->MaxStoresPerMemcpy;
367 }
368
369 unsigned getMaxStoresPerMemmove(bool OptSize) const {
370 return OptSize ? TuneInfo->MaxStoresPerMemmoveOptSize
371 : TuneInfo->MaxStoresPerMemmove;
372 }
373
374 unsigned getMaxLoadsPerMemcmp(bool OptSize) const {
375 return OptSize ? TuneInfo->MaxLoadsPerMemcmpOptSize
376 : TuneInfo->MaxLoadsPerMemcmp;
377 }
378
380 return TuneInfo->PostRASchedDirection;
381 }
382
384 unsigned NumRegionInstrs) const override;
385
387 unsigned NumRegionInstrs) const override;
388};
389} // End llvm namespace
390
391#endif
This file describes how to lower LLVM calls to machine code calls.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Interface for Targets to specify which operations they can successfully select and how the others sho...
This file declares the targeting of the RegisterBankInfo class for RISC-V.
static cl::opt< unsigned > RVVVectorLMULMax("riscv-v-fixed-length-vector-lmul-max", cl::desc("The maximum LMUL value to use for fixed length vectors. " "Fractional LMUL values are not supported."), cl::init(8), cl::Hidden)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Machine Value Type.
This class provides the information for the target register banks.
RISCVABI::ABI getTargetABI() const
unsigned getMinimumJumpTableEntries() const
bool hasStdExtCOrZca() const
const LegalizerInfo * getLegalizerInfo() const override
std::unique_ptr< LegalizerInfo > Legalizer
unsigned getMaxLMULForFixedLengthVectors() const
bool hasVInstructionsI64() const
unsigned getMaxPrefetchIterationsAhead() const override
bool hasVInstructionsF64() const
unsigned getMaxStoresPerMemcpy(bool OptSize) const
bool hasStdExtDOrZdinx() const
unsigned getMaxLoadsPerMemcmp(bool OptSize) const
bool hasStdExtZfhOrZhinx() const
bool useDFAforSMS() const override
unsigned getTailDupAggressiveThreshold() const
unsigned getRealMinVLen() const
unsigned getMaxStoresPerMemset(bool OptSize) const
Quantity expandVScale(Quantity X) const
If the ElementCount or TypeSize X is scalable and VScale (VLEN) is exactly known, returns X converted...
bool useRVVForFixedLengthVectors() const
MISched::Direction getPostRASchedDirection() const
bool isTargetFuchsia() const
bool hasVInstructionsBF16Minimal() const
unsigned getDLenFactor() const
unsigned getMaxStoresPerMemmove(bool OptSize) const
unsigned getMinRVVVectorSizeInBits() const
std::unique_ptr< InstructionSelector > InstSelector
bool hasVInstructionsF16Minimal() const
unsigned getMaxGluedStoresPerMemcpy() const
unsigned getXLen() const
bool hasConditionalMoveFusion() const
bool hasVInstructionsF16() const
const RISCVRegisterBankInfo * getRegBankInfo() const override
void overridePostRASchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const override
const CallLowering * getCallLowering() const override
bool enableMachineScheduler() const override
InstructionSelector * getInstructionSelector() const override
unsigned getMaxBuildIntsCost() const
Align getPrefLoopAlignment() const
void overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const override
std::unique_ptr< const SelectionDAGTargetInfo > TSInfo
bool hasVInstructions() const
bool useAA() const override
Enable use of alias analysis during code generation (during MI scheduling, DAGCombine,...
bool isRegisterReservedByUser(Register i) const override
bool hasVInstructionsAnyF() const
std::optional< unsigned > getRealVLen() const
bool isXRaySupported() const override
bool enableMachinePipeliner() const override
bool hasOptimizedSegmentLoadStore(unsigned NF) const
bool useConstantPoolForLargeInts() const
bool hasStdExtCOrZcfOrZce() const
Align getPrefFunctionAlignment() const
~RISCVSubtarget() override
RISCVProcFamilyEnum getProcFamily() const
Returns RISC-V processor family.
unsigned getMaxRVVVectorSizeInBits() const
bool hasStdExtZfhminOrZhinxmin() const
unsigned getRealMaxVLen() const
unsigned getMinPrefetchStride(unsigned NumMemAccesses, unsigned NumStridedMemAccesses, unsigned NumPrefetches, bool HasCall) const override
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
const RISCVRegisterInfo * getRegisterInfo() const override
std::unique_ptr< RISCVRegisterBankInfo > RegBankInfo
const RISCVInstrInfo * getInstrInfo() const override
unsigned getCacheLineSize() const override
std::unique_ptr< CallLowering > CallLoweringInfo
bool hasStdExtCOrZcd() const
bool hasVInstructionsFullMultiply() const
const RISCVTargetLowering * getTargetLowering() const override
bool hasVInstructionsF32() const
unsigned getMaxInterleaveFactor() const
bool enableSubRegLiveness() const override
unsigned getELen() const
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
bool isTargetAndroid() const
bool hasStdExtFOrZfinx() const
bool enablePostRAScheduler() const override
bool hasStdExtZvl() const
bool isSoftFPABI() const
bool hasHalfFPLoadStoreMove() const
const RISCVFrameLowering * getFrameLowering() const override
unsigned getFLen() const
unsigned getPrefetchDistance() const override
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static constexpr unsigned RVVBitsPerBlock
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.