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