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