1 //===-- RISCVSubtarget.h - Define Subtarget for the RISC-V ------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file declares the RISC-V specific subclass of TargetSubtargetInfo.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H
14 #define LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H
16 #include "MCTargetDesc/RISCVBaseInfo.h"
17 #include "RISCVFrameLowering.h"
18 #include "RISCVISelLowering.h"
19 #include "RISCVInstrInfo.h"
20 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
21 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
22 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
23 #include "llvm/CodeGen/RegisterBankInfo.h"
24 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
25 #include "llvm/CodeGen/TargetSubtargetInfo.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/Target/TargetMachine.h"
30 #define GET_RISCV_MACRO_FUSION_PRED_DECL
31 #include "RISCVGenMacroFusion.inc"
33 #define GET_SUBTARGETINFO_HEADER
34 #include "RISCVGenSubtargetInfo.inc"
39 namespace RISCVTuneInfoTable
{
41 struct RISCVTuneInfo
{
43 uint8_t PrefFunctionAlignment
;
44 uint8_t PrefLoopAlignment
;
46 // Information needed by LoopDataPrefetch.
47 uint16_t CacheLineSize
;
48 uint16_t PrefetchDistance
;
49 uint16_t MinPrefetchStride
;
50 unsigned MaxPrefetchIterationsAhead
;
52 unsigned MinimumJumpTableEntries
;
55 #define GET_RISCVTuneInfoTable_DECL
56 #include "RISCVGenSearchableTables.inc"
57 } // namespace RISCVTuneInfoTable
59 class RISCVSubtarget
: public RISCVGenSubtargetInfo
{
62 enum RISCVProcFamilyEnum
: uint8_t {
69 virtual void anchor();
71 RISCVProcFamilyEnum RISCVProcFamily
= Others
;
73 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
74 bool ATTRIBUTE = DEFAULT;
75 #include "RISCVGenSubtargetInfo.inc"
78 unsigned RVVVectorBitsMin
;
79 unsigned RVVVectorBitsMax
;
80 uint8_t MaxInterleaveFactor
= 2;
81 RISCVABI::ABI TargetABI
= RISCVABI::ABI_Unknown
;
82 std::bitset
<RISCV::NUM_TARGET_REGS
> UserReservedRegister
;
83 const RISCVTuneInfoTable::RISCVTuneInfo
*TuneInfo
;
85 RISCVFrameLowering FrameLowering
;
86 RISCVInstrInfo InstrInfo
;
87 RISCVRegisterInfo RegInfo
;
88 RISCVTargetLowering TLInfo
;
89 SelectionDAGTargetInfo TSInfo
;
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
,
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
);
105 // Parses features string setting specified subtarget options. The
106 // definition of this function is auto-generated by tblgen.
107 void ParseSubtargetFeatures(StringRef CPU
, StringRef TuneCPU
, StringRef FS
);
109 const RISCVFrameLowering
*getFrameLowering() const override
{
110 return &FrameLowering
;
112 const RISCVInstrInfo
*getInstrInfo() const override
{ return &InstrInfo
; }
113 const RISCVRegisterInfo
*getRegisterInfo() const override
{
116 const RISCVTargetLowering
*getTargetLowering() const override
{
119 const SelectionDAGTargetInfo
*getSelectionDAGInfo() const override
{
122 bool enableMachineScheduler() const override
{ return true; }
124 bool enablePostRAScheduler() const override
{
125 return getSchedModel().PostRAScheduler
|| UsePostRAScheduler
;
128 Align
getPrefFunctionAlignment() const {
129 return Align(TuneInfo
->PrefFunctionAlignment
);
131 Align
getPrefLoopAlignment() const {
132 return Align(TuneInfo
->PrefLoopAlignment
);
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
; }
141 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
142 bool GETTER() const { return ATTRIBUTE; }
143 #include "RISCVGenSubtargetInfo.inc"
145 bool hasStdExtCOrZca() const { return HasStdExtC
|| HasStdExtZca
; }
146 bool hasStdExtCOrZcd() const { return HasStdExtC
|| HasStdExtZcd
; }
147 bool hasStdExtCOrZcfOrZce() const {
148 return HasStdExtC
|| HasStdExtZcf
|| HasStdExtZce
;
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
; }
154 bool hasStdExtZfhminOrZhinxmin() const {
155 return HasStdExtZfhmin
|| HasStdExtZhinxmin
;
157 bool hasHalfFPLoadStoreMove() const {
158 return HasStdExtZfhmin
|| HasStdExtZfbfmin
;
161 bool hasConditionalMoveFusion() const {
162 // Do we support fusing a branch+mv or branch+c.mv as a conditional move.
163 return (hasConditionalCompressedMoveFusion() && hasStdExtCOrZca()) ||
164 hasShortForwardBranchOpt();
167 bool is64Bit() const { return IsRV64
; }
168 MVT
getXLenVT() const {
169 return is64Bit() ? MVT::i64
: MVT::i32
;
171 unsigned getXLen() const {
172 return is64Bit() ? 64 : 32;
174 unsigned getFLen() const {
183 unsigned getELen() const {
184 assert(hasVInstructions() && "Expected V extension");
185 return hasVInstructionsI64() ? 64 : 32;
187 unsigned getRealMinVLen() const {
188 unsigned VLen
= getMinRVVVectorSizeInBits();
189 return VLen
== 0 ? ZvlLen
: VLen
;
191 unsigned getRealMaxVLen() const {
192 unsigned VLen
= getMaxRVVVectorSizeInBits();
193 return VLen
== 0 ? 65536 : VLen
;
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())
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
);
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
;
220 bool isRegisterReservedByUser(Register i
) const {
221 assert(i
< RISCV::NUM_TARGET_REGS
&& "Register out of range");
222 return UserReservedRegister
[i
];
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;
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 {
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
;
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;
263 const CallLowering
*getCallLowering() const override
;
264 InstructionSelector
*getInstructionSelector() const override
;
265 const LegalizerInfo
*getLegalizerInfo() const override
;
266 const RegisterBankInfo
*getRegBankInfo() const override
;
268 bool isTargetAndroid() const { return getTargetTriple().isAndroid(); }
269 bool isTargetFuchsia() const { return getTargetTriple().isOSFuchsia(); }
271 bool useConstantPoolForLargeInts() const;
273 // Maximum cost used for building integers, integers will be put into constant
275 unsigned getMaxBuildIntsCost() const;
277 unsigned getMaxLMULForFixedLengthVectors() const;
278 bool useRVVForFixedLengthVectors() const;
280 bool enableSubRegLiveness() const override
;
282 void getPostRAMutations(std::vector
<std::unique_ptr
<ScheduleDAGMutation
>>
283 &Mutations
) const override
;
285 bool useAA() const override
;
287 unsigned getCacheLineSize() const override
{
288 return TuneInfo
->CacheLineSize
;
290 unsigned getPrefetchDistance() const override
{
291 return TuneInfo
->PrefetchDistance
;
293 unsigned getMinPrefetchStride(unsigned NumMemAccesses
,
294 unsigned NumStridedMemAccesses
,
295 unsigned NumPrefetches
,
296 bool HasCall
) const override
{
297 return TuneInfo
->MinPrefetchStride
;
299 unsigned getMaxPrefetchIterationsAhead() const override
{
300 return TuneInfo
->MaxPrefetchIterationsAhead
;
303 unsigned getMinimumJumpTableEntries() const;
305 bool supportsInitUndef() const override
{ return hasVInstructions(); }
307 } // End llvm namespace