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