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