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