LLVM 22.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 bool enableMachineScheduler() const override { return true; }
151
152 bool enablePostRAScheduler() const override { return UsePostRAScheduler; }
153
155 return Align(TuneInfo->PrefFunctionAlignment);
156 }
158 return Align(TuneInfo->PrefLoopAlignment);
159 }
160
161 /// Returns RISC-V processor family.
162 /// Avoid this function! CPU specifics should be kept local to this class
163 /// and preferably modeled with SubtargetFeatures or properties in
164 /// initializeProperties().
165 RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }
166
167 RISCVVRGatherCostModelEnum getVRGatherCostModel() const { return RISCVVRGatherCostModel; }
168
169#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
170 bool GETTER() const { return ATTRIBUTE; }
171#include "RISCVGenSubtargetInfo.inc"
172
173 LLVM_DEPRECATED("Now Equivalent to hasStdExtZca", "hasStdExtZca")
174 bool hasStdExtCOrZca() const { return HasStdExtZca; }
175 bool hasStdExtCOrZcd() const { return HasStdExtC || HasStdExtZcd; }
176 bool hasStdExtCOrZcfOrZce() const {
177 return HasStdExtC || HasStdExtZcf || HasStdExtZce;
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 {
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
204 bool hasBEXTILike() const { return HasStdExtZbs || HasVendorXTHeadBs; }
205
206 bool hasCZEROLike() const {
207 return HasStdExtZicond || HasVendorXVentanaCondOps;
208 }
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 return Align(enableUnalignedScalarMem() ? 1
246 : allowZilsd4ByteAlign() ? 4
247 : 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
292 // XRay support - require D and C extensions.
293 bool isXRaySupported() const override { return hasStdExtD() && hasStdExtC(); }
294
295 // Vector codegen related methods.
296 bool hasVInstructions() const { return HasStdExtZve32x; }
297 bool hasVInstructionsI64() const { return HasStdExtZve64x; }
298 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }
299 bool hasVInstructionsF16() const { return HasStdExtZvfh; }
301 return HasStdExtZvfbfmin || HasStdExtZvfbfa;
302 }
303 bool hasVInstructionsF32() const { return HasStdExtZve32f; }
304 bool hasVInstructionsF64() const { return HasStdExtZve64d; }
305 bool hasVInstructionsBF16() const { return HasStdExtZvfbfa; }
306 // F16 and F64 both require F32.
307 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }
308 bool hasVInstructionsFullMultiply() const { return HasStdExtV; }
309 unsigned getMaxInterleaveFactor() const {
310 return hasVInstructions() ? MaxInterleaveFactor : 1;
311 }
312
313 bool hasOptimizedSegmentLoadStore(unsigned NF) const {
314 switch (NF) {
315 case 2:
316 return hasOptimizedNF2SegmentLoadStore();
317 case 3:
318 return hasOptimizedNF3SegmentLoadStore();
319 case 4:
320 return hasOptimizedNF4SegmentLoadStore();
321 case 5:
322 return hasOptimizedNF5SegmentLoadStore();
323 case 6:
324 return hasOptimizedNF6SegmentLoadStore();
325 case 7:
326 return hasOptimizedNF7SegmentLoadStore();
327 case 8:
328 return hasOptimizedNF8SegmentLoadStore();
329 default:
330 llvm_unreachable("Unexpected NF");
331 }
332 }
333
334 bool enablePExtSIMDCodeGen() const;
335
336 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the
337 // vector hardware implementation which may be less than VLEN.
338 unsigned getDLenFactor() const {
339 if (DLenFactor2)
340 return 2;
341 return 1;
342 }
343
344protected:
345 // SelectionDAGISel related APIs.
346 std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
347
348 // GlobalISel related APIs.
349 mutable std::unique_ptr<CallLowering> CallLoweringInfo;
350 mutable std::unique_ptr<InstructionSelector> InstSelector;
351 mutable std::unique_ptr<LegalizerInfo> Legalizer;
352 mutable std::unique_ptr<RISCVRegisterBankInfo> RegBankInfo;
353
354 // Return the known range for the bit length of RVV data registers as set
355 // at the command line. A value of 0 means nothing is known about that particular
356 // limit beyond what's implied by the architecture.
357 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead!
358 unsigned getMaxRVVVectorSizeInBits() const;
359 unsigned getMinRVVVectorSizeInBits() const;
360
361public:
362 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
363 const CallLowering *getCallLowering() const override;
365 const LegalizerInfo *getLegalizerInfo() const override;
366 const RISCVRegisterBankInfo *getRegBankInfo() const override;
367
368 bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }
369 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
370
371 bool useConstantPoolForLargeInts() const;
372
373 // Maximum cost used for building integers, integers will be put into constant
374 // pool if exceeded.
375 unsigned getMaxBuildIntsCost() const;
376
377 unsigned getMaxLMULForFixedLengthVectors() const;
378 bool useRVVForFixedLengthVectors() const;
379
380 bool enableSubRegLiveness() const override;
381
382 bool enableMachinePipeliner() const override;
383
384 bool useDFAforSMS() const override { return false; }
385
386 bool useAA() const override;
387
388 unsigned getCacheLineSize() const override {
389 return TuneInfo->CacheLineSize;
390 };
391 unsigned getPrefetchDistance() const override {
392 return TuneInfo->PrefetchDistance;
393 };
394 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
395 unsigned NumStridedMemAccesses,
396 unsigned NumPrefetches,
397 bool HasCall) const override {
398 return TuneInfo->MinPrefetchStride;
399 };
400 unsigned getMaxPrefetchIterationsAhead() const override {
401 return TuneInfo->MaxPrefetchIterationsAhead;
402 };
403 bool enableWritePrefetching() const override { return true; }
404
405 unsigned getMinimumJumpTableEntries() const;
406
408 return TuneInfo->TailDupAggressiveThreshold;
409 }
410
411 unsigned getMaxStoresPerMemset(bool OptSize) const {
412 return OptSize ? TuneInfo->MaxStoresPerMemsetOptSize
413 : TuneInfo->MaxStoresPerMemset;
414 }
415
416 unsigned getMaxGluedStoresPerMemcpy() const {
417 return TuneInfo->MaxGluedStoresPerMemcpy;
418 }
419
420 unsigned getMaxStoresPerMemcpy(bool OptSize) const {
421 return OptSize ? TuneInfo->MaxStoresPerMemcpyOptSize
422 : TuneInfo->MaxStoresPerMemcpy;
423 }
424
425 unsigned getMaxStoresPerMemmove(bool OptSize) const {
426 return OptSize ? TuneInfo->MaxStoresPerMemmoveOptSize
427 : TuneInfo->MaxStoresPerMemmove;
428 }
429
430 unsigned getMaxLoadsPerMemcmp(bool OptSize) const {
431 return OptSize ? TuneInfo->MaxLoadsPerMemcmpOptSize
432 : TuneInfo->MaxLoadsPerMemcmp;
433 }
434
436 return TuneInfo->PostRASchedDirection;
437 }
438
440 const SchedRegion &Region) const override;
441
443 const SchedRegion &Region) const override;
444};
445} // namespace llvm
446
447#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
bool hasStdExtCOrZca() 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 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
bool enablePExtSIMDCodeGen() 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
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.
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.