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