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