LLVM 19.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
17#include "RISCVFrameLowering.h"
18#include "RISCVISelLowering.h"
19#include "RISCVInstrInfo.h"
26#include "llvm/IR/DataLayout.h"
28#include <bitset>
29
30#define GET_RISCV_MACRO_FUSION_PRED_DECL
31#include "RISCVGenMacroFusion.inc"
32
33#define GET_SUBTARGETINFO_HEADER
34#include "RISCVGenSubtargetInfo.inc"
35
36namespace llvm {
37class StringRef;
38
39namespace RISCVTuneInfoTable {
40
42 const char *Name;
45
46 // Information needed by LoopDataPrefetch.
51
53};
54
55#define GET_RISCVTuneInfoTable_DECL
56#include "RISCVGenSearchableTables.inc"
57} // namespace RISCVTuneInfoTable
58
60public:
61 // clang-format off
62 enum RISCVProcFamilyEnum : uint8_t {
66 };
67 // clang-format on
68private:
69 virtual void anchor();
70
71 RISCVProcFamilyEnum RISCVProcFamily = Others;
72
73#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
74 bool ATTRIBUTE = DEFAULT;
75#include "RISCVGenSubtargetInfo.inc"
76
77 unsigned ZvlLen = 0;
78 unsigned RVVVectorBitsMin;
79 unsigned RVVVectorBitsMax;
80 uint8_t MaxInterleaveFactor = 2;
82 std::bitset<RISCV::NUM_TARGET_REGS> UserReservedRegister;
84
85 RISCVFrameLowering FrameLowering;
86 RISCVInstrInfo InstrInfo;
90
91 /// Initializes using the passed in CPU and feature strings so that we can
92 /// use initializer lists for subtarget initialization.
93 RISCVSubtarget &initializeSubtargetDependencies(const Triple &TT,
94 StringRef CPU,
95 StringRef TuneCPU,
96 StringRef FS,
97 StringRef ABIName);
98
99public:
100 // Initializes the data members to match that of the specified triple.
101 RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
102 StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin,
103 unsigned RVVVectorLMULMax, const TargetMachine &TM);
104
105 // Parses features string setting specified subtarget options. The
106 // definition of this function is auto-generated by tblgen.
108
109 const RISCVFrameLowering *getFrameLowering() const override {
110 return &FrameLowering;
111 }
112 const RISCVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
113 const RISCVRegisterInfo *getRegisterInfo() const override {
114 return &RegInfo;
115 }
116 const RISCVTargetLowering *getTargetLowering() const override {
117 return &TLInfo;
118 }
120 return &TSInfo;
121 }
122 bool enableMachineScheduler() const override { return true; }
123
124 bool enablePostRAScheduler() const override { return UsePostRAScheduler; }
125
127 return Align(TuneInfo->PrefFunctionAlignment);
128 }
130 return Align(TuneInfo->PrefLoopAlignment);
131 }
132
133 /// Returns RISC-V processor family.
134 /// Avoid this function! CPU specifics should be kept local to this class
135 /// and preferably modeled with SubtargetFeatures or properties in
136 /// initializeProperties().
137 RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }
138
139#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
140 bool GETTER() const { return ATTRIBUTE; }
141#include "RISCVGenSubtargetInfo.inc"
142
143 bool hasStdExtCOrZca() const { return HasStdExtC || HasStdExtZca; }
144 bool hasStdExtCOrZcd() const { return HasStdExtC || HasStdExtZcd; }
145 bool hasStdExtCOrZcfOrZce() const {
146 return HasStdExtC || HasStdExtZcf || HasStdExtZce;
147 }
148 bool hasStdExtZvl() const { return ZvlLen != 0; }
149 bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; }
150 bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; }
151 bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; }
153 return HasStdExtZfhmin || HasStdExtZhinxmin;
154 }
156 return HasStdExtZfhmin || HasStdExtZfbfmin;
157 }
158
160 // Do we support fusing a branch+mv or branch+c.mv as a conditional move.
161 return (hasConditionalCompressedMoveFusion() && hasStdExtCOrZca()) ||
162 hasShortForwardBranchOpt();
163 }
164
165 bool is64Bit() const { return IsRV64; }
166 MVT getXLenVT() const {
167 return is64Bit() ? MVT::i64 : MVT::i32;
168 }
169 unsigned getXLen() const {
170 return is64Bit() ? 64 : 32;
171 }
172 unsigned getFLen() const {
173 if (HasStdExtD)
174 return 64;
175
176 if (HasStdExtF)
177 return 32;
178
179 return 0;
180 }
181 unsigned getELen() const {
182 assert(hasVInstructions() && "Expected V extension");
183 return hasVInstructionsI64() ? 64 : 32;
184 }
185 unsigned getRealMinVLen() const {
186 unsigned VLen = getMinRVVVectorSizeInBits();
187 return VLen == 0 ? ZvlLen : VLen;
188 }
189 unsigned getRealMaxVLen() const {
190 unsigned VLen = getMaxRVVVectorSizeInBits();
191 return VLen == 0 ? 65536 : VLen;
192 }
193 // If we know the exact VLEN, return it. Otherwise, return std::nullopt.
194 std::optional<unsigned> getRealVLen() const {
195 unsigned Min = getRealMinVLen();
196 if (Min != getRealMaxVLen())
197 return std::nullopt;
198 return Min;
199 }
200
201 /// If the ElementCount or TypeSize \p X is scalable and VScale (VLEN) is
202 /// exactly known, returns \p X converted to a fixed quantity. Otherwise
203 /// returns \p X unmodified.
204 template <typename Quantity> Quantity expandVScale(Quantity X) const {
205 if (auto VLen = getRealVLen(); VLen && X.isScalable()) {
206 const unsigned VScale = *VLen / RISCV::RVVBitsPerBlock;
207 X = Quantity::getFixed(X.getKnownMinValue() * VScale);
208 }
209 return X;
210 }
211
212 RISCVABI::ABI getTargetABI() const { return TargetABI; }
213 bool isSoftFPABI() const {
214 return TargetABI == RISCVABI::ABI_LP64 ||
215 TargetABI == RISCVABI::ABI_ILP32 ||
216 TargetABI == RISCVABI::ABI_ILP32E;
217 }
219 assert(i < RISCV::NUM_TARGET_REGS && "Register out of range");
220 return UserReservedRegister[i];
221 }
222
223 // Vector codegen related methods.
224 bool hasVInstructions() const { return HasStdExtZve32x; }
225 bool hasVInstructionsI64() const { return HasStdExtZve64x; }
226 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }
227 bool hasVInstructionsF16() const { return HasStdExtZvfh; }
228 bool hasVInstructionsBF16() const { return HasStdExtZvfbfmin; }
229 bool hasVInstructionsF32() const { return HasStdExtZve32f; }
230 bool hasVInstructionsF64() const { return HasStdExtZve64d; }
231 // F16 and F64 both require F32.
232 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }
233 bool hasVInstructionsFullMultiply() const { return HasStdExtV; }
234 unsigned getMaxInterleaveFactor() const {
235 return hasVInstructions() ? MaxInterleaveFactor : 1;
236 }
237
238 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the
239 // vector hardware implementation which may be less than VLEN.
240 unsigned getDLenFactor() const {
241 if (DLenFactor2)
242 return 2;
243 return 1;
244 }
245
246protected:
247 // GlobalISel related APIs.
248 std::unique_ptr<CallLowering> CallLoweringInfo;
249 std::unique_ptr<InstructionSelector> InstSelector;
250 std::unique_ptr<LegalizerInfo> Legalizer;
251 std::unique_ptr<RegisterBankInfo> RegBankInfo;
252
253 // Return the known range for the bit length of RVV data registers as set
254 // at the command line. A value of 0 means nothing is known about that particular
255 // limit beyond what's implied by the architecture.
256 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead!
257 unsigned getMaxRVVVectorSizeInBits() const;
258 unsigned getMinRVVVectorSizeInBits() const;
259
260public:
261 const CallLowering *getCallLowering() const override;
263 const LegalizerInfo *getLegalizerInfo() const override;
264 const RegisterBankInfo *getRegBankInfo() const override;
265
266 bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }
267 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
268
269 bool useConstantPoolForLargeInts() const;
270
271 // Maximum cost used for building integers, integers will be put into constant
272 // pool if exceeded.
273 unsigned getMaxBuildIntsCost() const;
274
275 unsigned getMaxLMULForFixedLengthVectors() const;
276 bool useRVVForFixedLengthVectors() const;
277
278 bool enableSubRegLiveness() const override;
279
280 void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>>
281 &Mutations) const override;
282
283 bool useAA() const override;
284
285 unsigned getCacheLineSize() const override {
286 return TuneInfo->CacheLineSize;
287 };
288 unsigned getPrefetchDistance() const override {
289 return TuneInfo->PrefetchDistance;
290 };
291 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
292 unsigned NumStridedMemAccesses,
293 unsigned NumPrefetches,
294 bool HasCall) const override {
295 return TuneInfo->MinPrefetchStride;
296 };
297 unsigned getMaxPrefetchIterationsAhead() const override {
298 return TuneInfo->MaxPrefetchIterationsAhead;
299 };
300
301 unsigned getMinimumJumpTableEntries() const;
302
303 bool supportsInitUndef() const override { return hasVInstructions(); }
304};
305} // End llvm namespace
306
307#endif
This file describes how to lower LLVM calls to machine code calls.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Interface for Targets to specify which operations they can successfully select and how the others sho...
const char LLVMTargetMachineRef TM
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Machine Value Type.
RISCVABI::ABI getTargetABI() const
unsigned getMinimumJumpTableEntries() const
bool hasStdExtCOrZca() const
void getPostRAMutations(std::vector< std::unique_ptr< ScheduleDAGMutation > > &Mutations) const override
const LegalizerInfo * getLegalizerInfo() const override
std::unique_ptr< LegalizerInfo > Legalizer
const RegisterBankInfo * getRegBankInfo() const override
unsigned getMaxLMULForFixedLengthVectors() const
bool hasVInstructionsI64() const
unsigned getMaxPrefetchIterationsAhead() const override
bool hasVInstructionsF64() const
bool hasStdExtDOrZdinx() const
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
bool hasStdExtZfhOrZhinx() const
unsigned getRealMinVLen() 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
std::unique_ptr< RegisterBankInfo > RegBankInfo
bool isTargetFuchsia() const
unsigned getDLenFactor() const
unsigned getMinRVVVectorSizeInBits() const
std::unique_ptr< InstructionSelector > InstSelector
bool hasVInstructionsF16Minimal() const
unsigned getXLen() const
bool hasConditionalMoveFusion() const
bool isRegisterReservedByUser(Register i) const
bool hasVInstructionsF16() const
bool hasVInstructionsBF16() const
const CallLowering * getCallLowering() const override
bool enableMachineScheduler() const override
InstructionSelector * getInstructionSelector() const override
unsigned getMaxBuildIntsCost() const
Align getPrefLoopAlignment() const
bool hasVInstructions() const
bool useAA() const override
Enable use of alias analysis during code generation (during MI scheduling, DAGCombine,...
bool hasVInstructionsAnyF() const
std::optional< unsigned > getRealVLen() const
bool useConstantPoolForLargeInts() const
bool hasStdExtCOrZcfOrZce() const
Align getPrefFunctionAlignment() const
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
const RISCVInstrInfo * getInstrInfo() const override
unsigned getCacheLineSize() const override
std::unique_ptr< CallLowering > CallLoweringInfo
bool hasStdExtCOrZcd() const
bool hasVInstructionsFullMultiply() const
const RISCVTargetLowering * getTargetLowering() const override
bool hasVInstructionsF32() const
unsigned getMaxInterleaveFactor() const
bool supportsInitUndef() const override
bool enableSubRegLiveness() const override
unsigned getELen() const
bool isTargetAndroid() const
bool hasStdExtFOrZfinx() const
bool enablePostRAScheduler() const override
bool hasStdExtZvl() const
bool isSoftFPABI() const
bool hasHalfFPLoadStoreMove() const
const RISCVFrameLowering * getFrameLowering() const override
unsigned getFLen() const
unsigned getPrefetchDistance() const override
Holds all the information related to register banks.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
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:50
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
static constexpr unsigned RVVBitsPerBlock
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39