LLVM 24.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"
28#include "llvm/IR/DataLayout.h"
31#include <bitset>
32#include <cstdint>
33#include <memory>
34#include <optional>
35
36#define OPTIONS_STRUCT_DECL
37#include "RISCVOptions.inc"
38
39#define GET_RISCV_MACRO_FUSION_PRED_DECL
40#include "RISCVGenMacroFusion.inc"
41
42#define GET_SUBTARGETINFO_HEADER
43#include "RISCVGenSubtargetInfo.inc"
44
45namespace llvm {
46class StringRef;
47
48namespace RISCVTuneInfoTable {
49
54
55 // Information needed by LoopDataPrefetch.
60
62
63 // Tail duplication threshold at -O3.
65
68
72
75
78
79 // How many vector elements can be coalesced if on the
80 // same cache line
82
83 // The direction of PostRA scheduling.
85
87};
88
89#define GET_RISCVTuneInfoTable_DECL
90#include "RISCVGenSearchableTables.inc"
91} // namespace RISCVTuneInfoTable
92
94public:
95 // clang-format off
106 // clang-format on
107private:
108 const RISCVOptions &CLOpts;
109
110 virtual void anchor();
111
112 RISCVProcFamilyEnum RISCVProcFamily = Others;
113 RISCVVRGatherCostModelEnum RISCVVRGatherCostModel = Quadratic;
114
115 bool IsLittleEndian = true;
116
117#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
118 bool ATTRIBUTE = DEFAULT;
119#include "RISCVGenSubtargetInfo.inc"
120
121 unsigned XSfmmTE = 0;
122 unsigned ZvlLen = 0;
123 unsigned RVVVectorBitsMin;
124 unsigned RVVVectorBitsMax;
127 // Set by the reserve-xN subtarget features, indexed by N. RISCVRegisterInfo
128 // expands this to include aliases.
129 std::bitset<32> UserReservedXRegs;
130 const RISCVTuneInfoTable::RISCVTuneInfo *TuneInfo;
131
132 RISCVFrameLowering FrameLowering;
133 RISCVInstrInfo InstrInfo;
134 RISCVTargetLowering TLInfo;
135
136 /// Initializes using the passed in CPU and feature strings so that we can
137 /// use initializer lists for subtarget initialization.
138 RISCVSubtarget &initializeSubtargetDependencies(const Triple &TT,
139 StringRef CPU,
140 StringRef TuneCPU,
141 StringRef FS,
142 StringRef ABIName);
143
144public:
145 // Initializes the data members to match that of the specified triple.
146 RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
147 StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin,
148 unsigned RVVVectorLMULMax, const TargetMachine &TM);
149
150 ~RISCVSubtarget() override;
151
152 // Parses features string setting specified subtarget options. The
153 // definition of this function is auto-generated by tblgen.
155
156 const RISCVFrameLowering *getFrameLowering() const override {
157 return &FrameLowering;
158 }
159 const RISCVOptions &getCLOpts() const { return CLOpts; }
160 const RISCVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
161 const RISCVRegisterInfo *getRegisterInfo() const override {
162 return &InstrInfo.getRegisterInfo();
163 }
164 const RISCVTargetLowering *getTargetLowering() const override {
165 return &TLInfo;
166 }
167
168 void mirFileLoaded(MachineFunction &MF) const override;
169
170 bool enableMachineScheduler() const override { return true; }
171
172 bool enablePostRAScheduler() const override { return UsePostRAScheduler; }
173
175 return Align(TuneInfo->PrefFunctionAlignment);
176 }
178 return Align(TuneInfo->PrefLoopAlignment);
179 }
180
181 /// Returns RISC-V processor family.
182 /// Avoid this function! CPU specifics should be kept local to this class
183 /// and preferably modeled with SubtargetFeatures or properties in
184 /// initializeProperties().
185 RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }
186
187 RISCVVRGatherCostModelEnum getVRGatherCostModel() const { return RISCVVRGatherCostModel; }
188
189#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
190 bool GETTER() const { return ATTRIBUTE; }
191#include "RISCVGenSubtargetInfo.inc"
192
193 bool hasYInstructions() const {
194 return HasStdExtYCapMode || HasStdExtZyhybrid;
195 }
196 bool hasStdExtZvl() const { return ZvlLen != 0; }
197 bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; }
198 bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; }
199 bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; }
201 return HasStdExtZfhmin || HasStdExtZhinxmin;
202 }
204 return HasStdExtZfhmin || HasStdExtZfbfmin;
205 }
206
207 bool hasCLZLike() const { return HasStdExtZbb || HasVendorXTHeadBb; }
208 bool hasCTZLike() const {
209 return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);
210 }
211 bool hasCPOPLike() const {
212 return HasStdExtZbb || (HasVendorXCVbitmanip && !IsRV64);
213 }
214 bool hasREV8Like() const {
215 return HasStdExtZbb || HasStdExtZbkb || HasVendorXTHeadBb;
216 }
217 bool hasREVLike() const {
218 return HasStdExtP || ((HasVendorXCVbitmanip || HasVendorXqcibm) && !IsRV64);
219 }
220
221 bool hasBEXTILike() const { return HasStdExtZbs || HasVendorXTHeadBs; }
222
224 // Do we support fusing a branch+mv or branch+c.mv as a conditional move.
225 return (hasConditionalCompressedMoveFusion() && hasStdExtZca()) ||
226 hasShortForwardBranchIALU();
227 }
228
229 bool hasShlAdd(int64_t ShAmt) const {
230 if (ShAmt <= 0)
231 return false;
232 if (ShAmt <= 3)
233 return HasStdExtZba || HasVendorXAndesPerf || HasVendorXTHeadBa;
234 return ShAmt <= 31 && HasVendorXqciac;
235 }
236
237 bool is64Bit() const { return IsRV64; }
238 bool isLittleEndian() const { return IsLittleEndian; }
239 MVT getXLenVT() const {
240 return is64Bit() ? MVT::i64 : MVT::i32;
241 }
242 unsigned getXLen() const {
243 return is64Bit() ? 64 : 32;
244 }
245 bool useMIPSLoadStorePairs() const;
246 bool useMIPSCCMovInsn() const;
247 unsigned getFLen() const {
248 if (HasStdExtD)
249 return 64;
250
251 if (HasStdExtF)
252 return 32;
253
254 return 0;
255 }
256
258 if (enableUnalignedScalarMem())
259 return Align(1);
260
261 if (allowZilsdWordAlign())
262 return Align(4);
263
264 return Align(8);
265 }
266
267 unsigned getELen() const {
268 assert(hasVInstructions() && "Expected V extension");
269 return hasVInstructionsI64() ? 64 : 32;
270 }
271 unsigned getRealMinVLen() const {
272 unsigned VLen = getMinRVVVectorSizeInBits();
273 return VLen == 0 ? ZvlLen : VLen;
274 }
275 unsigned getRealMaxVLen() const {
276 unsigned VLen = getMaxRVVVectorSizeInBits();
277 return VLen == 0 ? 65536 : VLen;
278 }
279 // If we know the exact VLEN, return it. Otherwise, return std::nullopt.
280 std::optional<unsigned> getRealVLen() const {
281 unsigned Min = getRealMinVLen();
282 if (Min != getRealMaxVLen())
283 return std::nullopt;
284 return Min;
285 }
286
287 /// If the ElementCount or TypeSize \p X is scalable and VScale (VLEN) is
288 /// exactly known, returns \p X converted to a fixed quantity. Otherwise
289 /// returns \p X unmodified.
290 template <typename Quantity> Quantity expandVScale(Quantity X) const {
291 if (auto VLen = getRealVLen(); VLen && X.isScalable()) {
292 const unsigned VScale = *VLen / RISCV::RVVBitsPerBlock;
293 X = Quantity::getFixed(X.getKnownMinValue() * VScale);
294 }
295 return X;
296 }
297
298 RISCVABI::ABI getTargetABI() const { return TargetABI; }
299 bool isSoftFPABI() const { return RISCVABI::isSoftFP(TargetABI); }
300 /// Returns the X registers reserved by the reserve-xN features, indexed by N.
301 /// Aliases of these registers are not included.
302 const std::bitset<32> &getUserReservedXRegs() const {
303 return UserReservedXRegs;
304 }
305 bool isRegisterReservedByUser(Register i) const override {
306 assert(i.id() < RISCV::NUM_TARGET_REGS && "Register out of range");
308 }
309
311 if (HasStdExtQ)
312 return &RISCV::FPR128RegClass;
313 if (HasStdExtD)
314 return &RISCV::FPR64RegClass;
315 if (HasStdExtF)
316 return &RISCV::FPR32RegClass;
317 return nullptr;
318 };
319
320 // XRay support - require D and Zcf/Zcd extensions. Effectively D and C
321 // without checking the C feature.
322 bool isXRaySupported() const override {
323 return hasStdExtD() && (is64Bit() || hasStdExtZcf()) && hasStdExtZcd();
324 }
325
326 // Vector codegen related methods.
327 bool hasVInstructions() const { return HasStdExtZve32x; }
328 bool hasVInstructionsI64() const { return HasStdExtZve64x; }
329 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }
330 bool hasVInstructionsF16() const { return HasStdExtZvfh; }
332 return HasStdExtZvfbfmin || HasStdExtZvfbfa;
333 }
334 bool hasVInstructionsF32() const { return HasStdExtZve32f; }
335 bool hasVInstructionsF64() const { return HasStdExtZve64d; }
336 bool hasVInstructionsBF16() const { return HasStdExtZvfbfa; }
337 // F16 and F64 both require F32.
338 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }
339 bool hasVInstructionsFullMultiply() const { return HasStdExtV; }
340 unsigned getMaxInterleaveFactor() const {
341 return hasVInstructions() ? MaxInterleaveFactor : 1;
342 }
343
344 bool hasOptimizedSegmentLoadStore(unsigned NF) const {
345 switch (NF) {
346 case 2:
347 return hasOptimizedNF2SegmentLoadStore();
348 case 3:
349 return hasOptimizedNF3SegmentLoadStore();
350 case 4:
351 return hasOptimizedNF4SegmentLoadStore();
352 case 5:
353 return hasOptimizedNF5SegmentLoadStore();
354 case 6:
355 return hasOptimizedNF6SegmentLoadStore();
356 case 7:
357 return hasOptimizedNF7SegmentLoadStore();
358 case 8:
359 return hasOptimizedNF8SegmentLoadStore();
360 default:
361 llvm_unreachable("Unexpected NF");
362 }
363 }
364
365 bool isPExtPackedType(MVT VT) const;
366 bool isPExtPackedDoubleType(MVT VT) const;
367
368 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the
369 // vector hardware implementation which may be less than VLEN.
370 unsigned getDLenFactor() const {
371 if (DLenFactor2)
372 return 2;
373 return 1;
374 }
375
376protected:
377 // SelectionDAGISel related APIs.
378 std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
379
380 // GlobalISel related APIs.
381 mutable std::unique_ptr<CallLowering> CallLoweringInfo;
382 mutable std::unique_ptr<InstructionSelector> InstSelector;
383 mutable std::unique_ptr<LegalizerInfo> Legalizer;
384 mutable std::unique_ptr<RISCVRegisterBankInfo> RegBankInfo;
385 mutable std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
386
387 // Return the known range for the bit length of RVV data registers as set
388 // at the command line. A value of 0 means nothing is known about that particular
389 // limit beyond what's implied by the architecture.
390 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead!
391 unsigned getMaxRVVVectorSizeInBits() const;
392 unsigned getMinRVVVectorSizeInBits() const;
393
394public:
395 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
396 const CallLowering *getCallLowering() const override;
398 const LegalizerInfo *getLegalizerInfo() const override;
399 const RISCVRegisterBankInfo *getRegBankInfo() const override;
400 const InlineAsmLowering *getInlineAsmLowering() const override;
401
402 bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }
403 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
404
405 bool useConstantPoolForLargeInts() const;
406
407 // Maximum cost used for building integers, integers will be put into constant
408 // pool if exceeded.
409 unsigned getMaxBuildIntsCost() const;
410
411 unsigned getMispredictionPenalty() const override;
412 unsigned getLoadLatency() const override;
413
414 bool useRVVForFixedLengthVectors() const;
415
416 bool enableSubRegLiveness() const override;
417
418 bool enableMachinePipeliner() const override;
419
420 bool useDFAforSMS() const override { return false; }
421
422 bool useAA() const override;
423
424 unsigned getCacheLineSize() const override {
425 return TuneInfo->CacheLineSize;
426 };
427 unsigned getPrefetchDistance() const override {
428 return TuneInfo->PrefetchDistance;
429 };
430 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
431 unsigned NumStridedMemAccesses,
432 unsigned NumPrefetches,
433 bool HasCall) const override {
434 return TuneInfo->MinPrefetchStride;
435 };
436 unsigned getMaxPrefetchIterationsAhead() const override {
437 return TuneInfo->MaxPrefetchIterationsAhead;
438 };
439 bool enableWritePrefetching() const override { return true; }
440
441 unsigned getMinimumJumpTableEntries() const;
442
444 return TuneInfo->TailDupAggressiveThreshold;
445 }
446
447 unsigned getMaxStoresPerMemset(bool OptSize) const {
448 return OptSize ? TuneInfo->MaxStoresPerMemsetOptSize
449 : TuneInfo->MaxStoresPerMemset;
450 }
451
452 unsigned getMaxGluedStoresPerMemcpy() const {
453 return TuneInfo->MaxGluedStoresPerMemcpy;
454 }
455
456 unsigned getMaxStoresPerMemcpy(bool OptSize) const {
457 return OptSize ? TuneInfo->MaxStoresPerMemcpyOptSize
458 : TuneInfo->MaxStoresPerMemcpy;
459 }
460
461 unsigned getMaxStoresPerMemmove(bool OptSize) const {
462 return OptSize ? TuneInfo->MaxStoresPerMemmoveOptSize
463 : TuneInfo->MaxStoresPerMemmove;
464 }
465
466 unsigned getMaxLoadsPerMemcmp(bool OptSize) const {
467 return OptSize ? TuneInfo->MaxLoadsPerMemcmpOptSize
468 : TuneInfo->MaxLoadsPerMemcmp;
469 }
470
472 return TuneInfo->MaxVectorCoalesceElts;
473 }
474
476 return TuneInfo->PostRASchedDirection;
477 }
478
479 bool isJumpExpensive() const { return TuneInfo->IsJumpExpensive; }
480
482 const SchedRegion &Region) const override;
483
485 const SchedRegion &Region) const override;
486};
487} // namespace llvm
488
489#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
This file describes how to lower LLVM calls to machine code calls.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
Interface for Targets to specify which operations they can successfully select and how the others sho...
static const unsigned MaxInterleaveFactor
Maximum vectorization interleave count.
This file declares the targeting of the RegisterBankInfo class for RISC-V.
Machine Value Type.
This class provides the information for the target register banks.
RISCVABI::ABI getTargetABI() const
unsigned getMinimumJumpTableEntries() const
const LegalizerInfo * getLegalizerInfo() const override
bool isJumpExpensive() const
void overrideSchedPolicy(MachineSchedPolicy &Policy, const SchedRegion &Region) const override
bool enableWritePrefetching() const override
std::unique_ptr< LegalizerInfo > Legalizer
bool hasVInstructionsI64() const
bool isPExtPackedDoubleType(MVT VT) 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 hasShlAdd(int64_t ShAmt) const
bool useDFAforSMS() const override
unsigned getTailDupAggressiveThreshold() const
unsigned getRealMinVLen() const
unsigned getMaxStoresPerMemset(bool OptSize) const
const std::bitset< 32 > & getUserReservedXRegs() const
Returns the X registers reserved by the reserve-xN features, indexed by N.
bool useMIPSLoadStorePairs() const
const InlineAsmLowering * getInlineAsmLowering() const override
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
RISCVVRGatherCostModelEnum getVRGatherCostModel() const
MISched::Direction getPostRASchedDirection() const
std::unique_ptr< InlineAsmLowering > InlineAsmLoweringInfo
const RISCVOptions & getCLOpts() const
bool isPExtPackedType(MVT VT) const
unsigned getLoadLatency() const override
bool isTargetFuchsia() const
bool hasVInstructionsBF16Minimal() const
unsigned getDLenFactor() const
TargetRegisterClass const * getLargestFPRegClass() const
unsigned getMaxStoresPerMemmove(bool OptSize) const
unsigned getMinRVVVectorSizeInBits() const
std::unique_ptr< InstructionSelector > InstSelector
bool hasVInstructionsF16Minimal() const
RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin, unsigned RVVVectorLMULMax, const TargetMachine &TM)
unsigned getMaxGluedStoresPerMemcpy() const
unsigned getXLen() const
bool hasConditionalMoveFusion() const
bool useMIPSCCMovInsn() const
bool hasVInstructionsF16() const
unsigned getMispredictionPenalty() const override
bool hasVInstructionsBF16() const
const RISCVRegisterBankInfo * getRegBankInfo() const override
const CallLowering * getCallLowering() const override
bool enableMachineScheduler() const override
InstructionSelector * getInstructionSelector() const override
unsigned getMaxBuildIntsCost() const
Align getPrefLoopAlignment() const
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 isLittleEndian() 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
Align getZilsdAlign() const
std::unique_ptr< RISCVRegisterBankInfo > RegBankInfo
void mirFileLoaded(MachineFunction &MF) const override
const RISCVInstrInfo * getInstrInfo() const override
unsigned getCacheLineSize() const override
std::unique_ptr< CallLowering > CallLoweringInfo
bool hasBEXTILike() const
uint8_t getMaxVectorCoalesceElts() const
bool hasVInstructionsFullMultiply() const
const RISCVTargetLowering * getTargetLowering() const override
void overridePostRASchedPolicy(MachineSchedPolicy &Policy, const SchedRegion &Region) 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 hasYInstructions() 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:20
constexpr unsigned id() const
Definition Register.h:100
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isSoftFP(ABI TargetABI)
static constexpr unsigned RVVBitsPerBlock
This is an optimization pass for GlobalISel generic memory operations.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
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.
bool isRegisterReservedByUser(MCRegister Reg) const
Returns true if Reg is, or overlaps, a register reserved by the reserve-xN features,...
A region of an MBB for scheduling.