LLVM 23.0.0git
RISCVSubtarget.cpp
Go to the documentation of this file.
1//===-- RISCVSubtarget.cpp - RISC-V Subtarget Information -----------------===//
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 implements the RISC-V specific subclass of TargetSubtargetInfo.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVSubtarget.h"
17#include "RISCV.h"
18#include "RISCVFrameLowering.h"
20#include "RISCVTargetMachine.h"
24
25using namespace llvm;
26
27#define DEBUG_TYPE "riscv-subtarget"
28
29#define GET_SUBTARGETINFO_TARGET_DESC
30#define GET_SUBTARGETINFO_CTOR
31#include "RISCVGenSubtargetInfo.inc"
32
33#define GET_RISCV_MACRO_FUSION_PRED_IMPL
34#include "RISCVGenMacroFusion.inc"
35
37
38#define GET_RISCVTuneInfoTable_IMPL
39#include "RISCVGenSearchableTables.inc"
40} // namespace llvm::RISCVTuneInfoTable
41
43 "riscv-disable-using-constant-pool-for-large-ints",
44 cl::desc("Disable using constant pool for large integers."),
45 cl::init(false), cl::Hidden);
46
48 "riscv-max-build-ints-cost",
49 cl::desc("The maximum cost used for building integers."), cl::init(0),
51
52static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),
53 cl::desc("Enable the use of AA during codegen."));
54
56 "riscv-min-jump-table-entries", cl::Hidden,
57 cl::desc("Set minimum number of entries to use a jump table on RISCV"));
58
60 "use-riscv-mips-load-store-pairs",
61 cl::desc("Enable the load/store pair optimization pass"), cl::init(false),
63
64static cl::opt<bool> UseMIPSCCMovInsn("use-riscv-mips-ccmov",
65 cl::desc("Use 'mips.ccmov' instruction"),
66 cl::init(true), cl::Hidden);
67
68void RISCVSubtarget::anchor() {}
69
71RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
72 StringRef TuneCPU, StringRef FS,
73 StringRef ABIName) {
74 // Determine default and user-specified characteristics
75 bool Is64Bit = TT.isArch64Bit();
76 if (CPU.empty() || CPU == "generic")
77 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
78
79 if (TuneCPU.empty())
80 TuneCPU = CPU;
81 if (TuneCPU == "generic")
82 TuneCPU = Is64Bit ? "generic-rv64" : "generic-rv32";
83
84 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
85 // If there is no TuneInfo for this CPU, we fail back to generic.
86 if (!TuneInfo)
87 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
88 assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
89
90 ParseSubtargetFeatures(CPU, TuneCPU, FS);
91
93
94 // Re-sync the flags.
95 HasStdExtZcd = hasFeature(RISCV::FeatureStdExtZcd);
96 HasStdExtZcf = hasFeature(RISCV::FeatureStdExtZcf);
97 HasStdExtC = hasFeature(RISCV::FeatureStdExtC);
98 HasStdExtZce = hasFeature(RISCV::FeatureStdExtZce);
99
100 TargetABI = RISCVABI::computeTargetABI(*this, ABIName);
101 RISCVFeatures::validate(TT, getFeatureBits());
102 return *this;
103}
104
106 StringRef TuneCPU, StringRef FS,
107 StringRef ABIName, unsigned RVVVectorBitsMin,
108 unsigned RVVVectorBitsMax,
109 const TargetMachine &TM)
110 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
111 IsLittleEndian(TT.isLittleEndian()), RVVVectorBitsMin(RVVVectorBitsMin),
112 RVVVectorBitsMax(RVVVectorBitsMax),
113 FrameLowering(
114 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
115 InstrInfo(*this), TLInfo(TM, *this) {
116 TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
117}
118
120
124
131
137
139 if (!InstSelector) {
141 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),
142 *this, *getRegBankInfo()));
143 }
144 return InstSelector.get();
145}
146
148 if (!Legalizer)
149 Legalizer.reset(new RISCVLegalizerInfo(*this));
150 return Legalizer.get();
151}
152
154 if (!RegBankInfo)
155 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));
156 return RegBankInfo.get();
157}
158
162
163// Returns true if VT is a P extension packed SIMD type.
165 if (!HasStdExtP)
166 return false;
167
168 // RV32 supports 32-bit and 64-bit vectors. RV64 only support 64-bit vectors.
169 if (!is64Bit() && (VT == MVT::v4i8 || VT == MVT::v2i16))
170 return true;
171
172 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
173}
174
175// Returns true if VT is a P extension packed double-wide SIMD type.
177 if (!HasStdExtP || is64Bit())
178 return false;
179
180 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
181}
182
184 // Loading integer from constant pool needs two instructions (the reason why
185 // the minimum cost is 2): an address calculation instruction and a load
186 // instruction. Usually, address calculation and instructions used for
187 // building integers (addi, slli, etc.) can be done in one cycle, so here we
188 // set the default cost to (LoadLatency + 1) if no threshold is provided.
189 return RISCVMaxBuildIntsCost == 0
190 ? getSchedModel().LoadLatency + 1
191 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
192}
193
196 "Tried to get vector length without Zve or V extension support!");
197
198 // ZvlLen specifies the minimum required vlen. The upper bound provided by
199 // riscv-v-vector-bits-max should be no less than it.
200 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
201 report_fatal_error("riscv-v-vector-bits-max specified is lower "
202 "than the Zvl*b limitation");
203
204 return RVVVectorBitsMax;
205}
206
209 "Tried to get vector length without Zve or V extension support!");
210
211 if (RVVVectorBitsMin == -1U)
212 return ZvlLen;
213
214 // ZvlLen specifies the minimum required vlen. The lower bound provided by
215 // riscv-v-vector-bits-min should be no less than it.
216 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
217 report_fatal_error("riscv-v-vector-bits-min specified is lower "
218 "than the Zvl*b limitation");
219
220 return RVVVectorBitsMin;
221}
222
225 "Tried to get vector length without Zve or V extension support!");
226 return 8;
227}
228
233
234bool RISCVSubtarget::enableSubRegLiveness() const { return true; }
235
237 return getSchedModel().hasInstrSchedModel();
238}
239
241 // We usually compute max call frame size after ISel. Do the computation now
242 // if the .mir file didn't specify it. Note that this will probably give you
243 // bogus values after PEI has eliminated the callframe setup/destroy pseudo
244 // instructions, specify explicitly if you need it to be correct.
245 MachineFrameInfo &MFI = MF.getFrameInfo();
248}
249
250 /// Enable use of alias analysis during code generation (during MI
251 /// scheduling, DAGCombine, etc.).
252bool RISCVSubtarget::useAA() const { return UseAA; }
253
255 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
257 : TuneInfo->MinimumJumpTableEntries;
258}
259
261 const SchedRegion &Region) const {
262 // Do bidirectional scheduling since it provides a more balanced scheduling
263 // leading to better performance. This will increase compile time.
264 Policy.OnlyTopDown = false;
265 Policy.OnlyBottomUp = false;
266
267 // Disabling the latency heuristic can reduce the number of spills/reloads but
268 // will cause some regressions on some cores.
269 Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
270
271 // Spilling is generally expensive on all RISC-V cores, so always enable
272 // register-pressure tracking. This will increase compile time.
273 Policy.ShouldTrackPressure = true;
274}
275
277 MachineSchedPolicy &Policy, const SchedRegion &Region) const {
278 MISched::Direction PostRASchedDirection = getPostRASchedDirection();
279 if (PostRASchedDirection == MISched::TopDown) {
280 Policy.OnlyTopDown = true;
281 Policy.OnlyBottomUp = false;
282 } else if (PostRASchedDirection == MISched::BottomUp) {
283 Policy.OnlyTopDown = false;
284 Policy.OnlyBottomUp = true;
285 } else if (PostRASchedDirection == MISched::Bidirectional) {
286 Policy.OnlyTopDown = false;
287 Policy.OnlyBottomUp = false;
288 }
289}
290
292 return UseMIPSLoadStorePairsOpt && HasVendorXMIPSLSP;
293}
294
296 return UseMIPSCCMovInsn && HasVendorXMIPSCMov;
297}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > UseAA("aarch64-use-aa", cl::init(true), cl::desc("Enable the use of AA during codegen."))
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
This file describes how to lower LLVM calls to machine code calls.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
This file declares the targeting of the Machinelegalizer class for RISC-V.
static cl::opt< bool > UseAA("riscv-use-aa", cl::init(true), cl::desc("Enable the use of AA during codegen."))
static cl::opt< bool > UseMIPSCCMovInsn("use-riscv-mips-ccmov", cl::desc("Use 'mips.ccmov' instruction"), cl::init(true), cl::Hidden)
static cl::opt< unsigned > RISCVMinimumJumpTableEntries("riscv-min-jump-table-entries", cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on RISCV"))
static cl::opt< bool > UseMIPSLoadStorePairsOpt("use-riscv-mips-load-store-pairs", cl::desc("Enable the load/store pair optimization pass"), cl::init(false), cl::Hidden)
static cl::opt< bool > RISCVDisableUsingConstantPoolForLargeInts("riscv-disable-using-constant-pool-for-large-ints", cl::desc("Disable using constant pool for large integers."), cl::init(false), cl::Hidden)
static cl::opt< unsigned > RISCVMaxBuildIntsCost("riscv-max-build-ints-cost", cl::desc("The maximum cost used for building integers."), cl::init(0), cl::Hidden)
Machine Value Type.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI void computeMaxCallFrameSize(MachineFunction &MF, std::vector< MachineBasicBlock::iterator > *FrameSDOps=nullptr)
Computes the maximum size of a callframe.
bool isMaxCallFrameSizeComputed() const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
This class provides the information for the target register banks.
unsigned getMinimumJumpTableEntries() const
const LegalizerInfo * getLegalizerInfo() const override
void overrideSchedPolicy(MachineSchedPolicy &Policy, const SchedRegion &Region) const override
std::unique_ptr< LegalizerInfo > Legalizer
unsigned getMaxLMULForFixedLengthVectors() const
bool isPExtPackedDoubleType(MVT VT) const
bool useMIPSLoadStorePairs() const
const InlineAsmLowering * getInlineAsmLowering() const override
bool useRVVForFixedLengthVectors() const
MISched::Direction getPostRASchedDirection() const
std::unique_ptr< InlineAsmLowering > InlineAsmLoweringInfo
bool isPExtPackedType(MVT VT) const
unsigned getMinRVVVectorSizeInBits() const
std::unique_ptr< InstructionSelector > InstSelector
RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin, unsigned RVVVectorLMULMax, const TargetMachine &TM)
bool useMIPSCCMovInsn() const
const RISCVRegisterBankInfo * getRegBankInfo() const override
const CallLowering * getCallLowering() const override
InstructionSelector * getInstructionSelector() const override
unsigned getMaxBuildIntsCost() 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 enableMachinePipeliner() const override
bool useConstantPoolForLargeInts() const
bool isLittleEndian() const
~RISCVSubtarget() override
unsigned getMaxRVVVectorSizeInBits() const
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
std::unique_ptr< RISCVRegisterBankInfo > RegBankInfo
void mirFileLoaded(MachineFunction &MF) const override
std::unique_ptr< CallLowering > CallLoweringInfo
const RISCVTargetLowering * getTargetLowering() const override
void overridePostRASchedPolicy(MachineSchedPolicy &Policy, const SchedRegion &Region) const override
bool enableSubRegLiveness() const override
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
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
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Primary interface to the complete machine description for the target machine.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
ABI computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
static constexpr unsigned RVVBitsPerBlock
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, const RISCVSubtarget &Subtarget, const RISCVRegisterBankInfo &RBI)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.
A region of an MBB for scheduling.