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