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