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 {
125 return getSchedModel().PostRAScheduler || UsePostRAScheduler;
126 }
127
129 return Align(TuneInfo->PrefFunctionAlignment);
130 }
132 return Align(TuneInfo->PrefLoopAlignment);
133 }
134
135 /// Returns RISC-V processor family.
136 /// Avoid this function! CPU specifics should be kept local to this class
137 /// and preferably modeled with SubtargetFeatures or properties in
138 /// initializeProperties().
139 RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }
140
141#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
142 bool GETTER() const { return ATTRIBUTE; }
143#include "RISCVGenSubtargetInfo.inc"
144
145 bool hasStdExtCOrZca() const { return HasStdExtC || HasStdExtZca; }
146 bool hasStdExtCOrZcd() const { return HasStdExtC || HasStdExtZcd; }
147 bool hasStdExtCOrZcfOrZce() const {
148 return HasStdExtC || HasStdExtZcf || HasStdExtZce;
149 }
150 bool hasStdExtZvl() const { return ZvlLen != 0; }
151 bool hasStdExtFOrZfinx() const { return HasStdExtF || HasStdExtZfinx; }
152 bool hasStdExtDOrZdinx() const { return HasStdExtD || HasStdExtZdinx; }
153 bool hasStdExtZfhOrZhinx() const { return HasStdExtZfh || HasStdExtZhinx; }
155 return HasStdExtZfhmin || HasStdExtZhinxmin;
156 }
158 return HasStdExtZfhmin || HasStdExtZfbfmin;
159 }
160
162 // Do we support fusing a branch+mv or branch+c.mv as a conditional move.
163 return (hasConditionalCompressedMoveFusion() && hasStdExtCOrZca()) ||
164 hasShortForwardBranchOpt();
165 }
166
167 bool is64Bit() const { return IsRV64; }
168 MVT getXLenVT() const {
169 return is64Bit() ? MVT::i64 : MVT::i32;
170 }
171 unsigned getXLen() const {
172 return is64Bit() ? 64 : 32;
173 }
174 unsigned getFLen() const {
175 if (HasStdExtD)
176 return 64;
177
178 if (HasStdExtF)
179 return 32;
180
181 return 0;
182 }
183 unsigned getELen() const {
184 assert(hasVInstructions() && "Expected V extension");
185 return hasVInstructionsI64() ? 64 : 32;
186 }
187 unsigned getRealMinVLen() const {
188 unsigned VLen = getMinRVVVectorSizeInBits();
189 return VLen == 0 ? ZvlLen : VLen;
190 }
191 unsigned getRealMaxVLen() const {
192 unsigned VLen = getMaxRVVVectorSizeInBits();
193 return VLen == 0 ? 65536 : VLen;
194 }
195 // If we know the exact VLEN, return it. Otherwise, return std::nullopt.
196 std::optional<unsigned> getRealVLen() const {
197 unsigned Min = getRealMinVLen();
198 if (Min != getRealMaxVLen())
199 return std::nullopt;
200 return Min;
201 }
202
203 /// If the ElementCount or TypeSize \p X is scalable and VScale (VLEN) is
204 /// exactly known, returns \p X converted to a fixed quantity. Otherwise
205 /// returns \p X unmodified.
206 template <typename Quantity> Quantity expandVScale(Quantity X) const {
207 if (auto VLen = getRealVLen(); VLen && X.isScalable()) {
208 const unsigned VScale = *VLen / RISCV::RVVBitsPerBlock;
209 X = Quantity::getFixed(X.getKnownMinValue() * VScale);
210 }
211 return X;
212 }
213
214 RISCVABI::ABI getTargetABI() const { return TargetABI; }
215 bool isSoftFPABI() const {
216 return TargetABI == RISCVABI::ABI_LP64 ||
217 TargetABI == RISCVABI::ABI_ILP32 ||
218 TargetABI == RISCVABI::ABI_ILP32E;
219 }
221 assert(i < RISCV::NUM_TARGET_REGS && "Register out of range");
222 return UserReservedRegister[i];
223 }
224
225 // Vector codegen related methods.
226 bool hasVInstructions() const { return HasStdExtZve32x; }
227 bool hasVInstructionsI64() const { return HasStdExtZve64x; }
228 bool hasVInstructionsF16Minimal() const { return HasStdExtZvfhmin; }
229 bool hasVInstructionsF16() const { return HasStdExtZvfh; }
230 bool hasVInstructionsBF16() const { return HasStdExtZvfbfmin; }
231 bool hasVInstructionsF32() const { return HasStdExtZve32f; }
232 bool hasVInstructionsF64() const { return HasStdExtZve64d; }
233 // F16 and F64 both require F32.
234 bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }
235 bool hasVInstructionsFullMultiply() const { return HasStdExtV; }
236 unsigned getMaxInterleaveFactor() const {
237 return hasVInstructions() ? MaxInterleaveFactor : 1;
238 }
239
240 // Returns VLEN divided by DLEN. Where DLEN is the datapath width of the
241 // vector hardware implementation which may be less than VLEN.
242 unsigned getDLenFactor() const {
243 if (DLenFactor2)
244 return 2;
245 return 1;
246 }
247
248protected:
249 // GlobalISel related APIs.
250 std::unique_ptr<CallLowering> CallLoweringInfo;
251 std::unique_ptr<InstructionSelector> InstSelector;
252 std::unique_ptr<LegalizerInfo> Legalizer;
253 std::unique_ptr<RegisterBankInfo> RegBankInfo;
254
255 // Return the known range for the bit length of RVV data registers as set
256 // at the command line. A value of 0 means nothing is known about that particular
257 // limit beyond what's implied by the architecture.
258 // NOTE: Please use getRealMinVLen and getRealMaxVLen instead!
259 unsigned getMaxRVVVectorSizeInBits() const;
260 unsigned getMinRVVVectorSizeInBits() const;
261
262public:
263 const CallLowering *getCallLowering() const override;
265 const LegalizerInfo *getLegalizerInfo() const override;
266 const RegisterBankInfo *getRegBankInfo() const override;
267
268 bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }
269 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
270
271 bool useConstantPoolForLargeInts() const;
272
273 // Maximum cost used for building integers, integers will be put into constant
274 // pool if exceeded.
275 unsigned getMaxBuildIntsCost() const;
276
277 unsigned getMaxLMULForFixedLengthVectors() const;
278 bool useRVVForFixedLengthVectors() const;
279
280 bool enableSubRegLiveness() const override;
281
282 void getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>>
283 &Mutations) const override;
284
285 bool useAA() const override;
286
287 unsigned getCacheLineSize() const override {
288 return TuneInfo->CacheLineSize;
289 };
290 unsigned getPrefetchDistance() const override {
291 return TuneInfo->PrefetchDistance;
292 };
293 unsigned getMinPrefetchStride(unsigned NumMemAccesses,
294 unsigned NumStridedMemAccesses,
295 unsigned NumPrefetches,
296 bool HasCall) const override {
297 return TuneInfo->MinPrefetchStride;
298 };
299 unsigned getMaxPrefetchIterationsAhead() const override {
300 return TuneInfo->MaxPrefetchIterationsAhead;
301 };
302
303 unsigned getMinimumJumpTableEntries() const;
304
305 bool supportsInitUndef() const override { return hasVInstructions(); }
306};
307} // End llvm namespace
308
309#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:76
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