LLVM 24.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"
21#include "llvm/ADT/Statistic.h"
24#include "llvm/MC/MCSchedule.h"
28
29using namespace llvm;
30
32 "riscv-sched-mispredict-penalty", cl::Hidden,
35 cl::desc("Override the mispredict penalty (in cycles) in the scheduler "
36 "model. A non-negative value overrides the target default."));
37
39 "riscv-sched-load-latency", cl::Hidden,
41 cl::desc("Override the load latency (in cycles) in the scheduler model. "
42 "A non-negative value overrides the target default."));
43
44#define DEBUG_TYPE "riscv-macro-fusion"
45
46#define GET_RISCV_MACRO_FUSION_PRED_IMPL
47#include "RISCVGenMacroFusion.inc"
48
49#undef DEBUG_TYPE
50#define DEBUG_TYPE "riscv-subtarget"
51
52#define GET_SUBTARGETINFO_TARGET_DESC
53#define GET_SUBTARGETINFO_CTOR
54#include "RISCVGenSubtargetInfo.inc"
55
57
58#define GET_RISCVTuneInfoTable_IMPL
59#include "RISCVGenSearchableTables.inc"
60} // namespace llvm::RISCVTuneInfoTable
61
63 "riscv-disable-using-constant-pool-for-large-ints",
64 cl::desc("Disable using constant pool for large integers."),
65 cl::init(false), cl::Hidden);
66
68 "riscv-max-build-ints-cost",
69 cl::desc("The maximum cost used for building integers."), cl::init(0),
71
72static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),
73 cl::desc("Enable the use of AA during codegen."));
74
76 "riscv-min-jump-table-entries", cl::Hidden,
77 cl::desc("Set minimum number of entries to use a jump table on RISCV"));
78
80 "use-riscv-mips-load-store-pairs",
81 cl::desc("Enable the load/store pair optimization pass"), cl::init(false),
83
84static cl::opt<bool> UseMIPSCCMovInsn("use-riscv-mips-ccmov",
85 cl::desc("Use 'mips.ccmov' instruction"),
86 cl::init(true), cl::Hidden);
87
88void RISCVSubtarget::anchor() {}
89
91RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
92 StringRef TuneCPU, StringRef FS,
93 StringRef ABIName) {
94 // Determine default and user-specified characteristics
95 bool Is64Bit = TT.isArch64Bit();
96 if (CPU.empty() || CPU == "generic")
97 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
98
99 if (TuneCPU.empty())
100 TuneCPU = CPU;
101 if (TuneCPU == "generic")
102 TuneCPU = Is64Bit ? "generic-rv64" : "generic-rv32";
103
104 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
105 // If there is no TuneInfo for this CPU, we fail back to generic.
106 if (!TuneInfo)
107 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
108 assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
109
110 ParseSubtargetFeatures(CPU, TuneCPU, FS);
111
113
114 // Re-sync the flags.
115 HasStdExtZcd = hasFeature(RISCV::FeatureStdExtZcd);
116 HasStdExtZcf = hasFeature(RISCV::FeatureStdExtZcf);
117 HasStdExtC = hasFeature(RISCV::FeatureStdExtC);
118 HasStdExtZce = hasFeature(RISCV::FeatureStdExtZce);
119
120 TargetABI = RISCVABI::computeTargetABI(*this, ABIName);
121 RISCVFeatures::validate(TT, getFeatureBits());
122 return *this;
123}
124
126 StringRef TuneCPU, StringRef FS,
127 StringRef ABIName, unsigned RVVVectorBitsMin,
128 unsigned RVVVectorBitsMax,
129 const TargetMachine &TM)
130 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
131 IsLittleEndian(TT.isLittleEndian()), RVVVectorBitsMin(RVVVectorBitsMin),
132 RVVVectorBitsMax(RVVVectorBitsMax),
133 FrameLowering(
134 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
135 InstrInfo(*this), TLInfo(TM, *this) {
136 TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
137}
138
140
144
151
157
159 if (!InstSelector) {
161 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),
162 *this, *getRegBankInfo()));
163 }
164 return InstSelector.get();
165}
166
168 if (!Legalizer)
169 Legalizer.reset(new RISCVLegalizerInfo(*this));
170 return Legalizer.get();
171}
172
174 if (!RegBankInfo)
175 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));
176 return RegBankInfo.get();
177}
178
182
183// Returns true if VT is a P extension packed SIMD type.
185 if (!HasStdExtP)
186 return false;
187
188 // RV32 supports 32-bit and 64-bit vectors. RV64 only support 64-bit vectors.
189 if (!is64Bit() && (VT == MVT::v4i8 || VT == MVT::v2i16))
190 return true;
191
192 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
193}
194
195// Returns true if VT is a P extension packed double-wide SIMD type.
197 if (!HasStdExtP || is64Bit())
198 return false;
199
200 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
201}
202
204 // Loading integer from constant pool needs two instructions (the reason why
205 // the minimum cost is 2): an address calculation instruction and a load
206 // instruction. Usually, address calculation and instructions used for
207 // building integers (addi, slli, etc.) can be done in one cycle, so here we
208 // set the default cost to (LoadLatency + 1) if no threshold is provided.
209 return RISCVMaxBuildIntsCost == 0
210 ? getLoadLatency() + 1
211 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
212}
213
215 if (SchedMispredictPenalty.getNumOccurrences() > 0)
217 return getSchedModel().MispredictPenalty;
218}
219
221 if (SchedLoadLatency.getNumOccurrences() > 0)
222 return SchedLoadLatency;
223 return getSchedModel().LoadLatency;
224}
225
228 "Tried to get vector length without Zve or V extension support!");
229
230 // ZvlLen specifies the minimum required vlen. The upper bound provided by
231 // riscv-v-vector-bits-max should be no less than it.
232 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
233 report_fatal_error("riscv-v-vector-bits-max specified is lower "
234 "than the Zvl*b limitation");
235
236 return RVVVectorBitsMax;
237}
238
241 "Tried to get vector length without Zve or V extension support!");
242
243 if (RVVVectorBitsMin == -1U)
244 return ZvlLen;
245
246 // ZvlLen specifies the minimum required vlen. The lower bound provided by
247 // riscv-v-vector-bits-min should be no less than it.
248 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
249 report_fatal_error("riscv-v-vector-bits-min specified is lower "
250 "than the Zvl*b limitation");
251
252 return RVVVectorBitsMin;
253}
254
257 "Tried to get vector length without Zve or V extension support!");
258 return 8;
259}
260
265
266bool RISCVSubtarget::enableSubRegLiveness() const { return true; }
267
269 return getSchedModel().hasInstrSchedModel();
270}
271
273 // We usually compute max call frame size after ISel. Do the computation now
274 // if the .mir file didn't specify it. Note that this will probably give you
275 // bogus values after PEI has eliminated the callframe setup/destroy pseudo
276 // instructions, specify explicitly if you need it to be correct.
277 MachineFrameInfo &MFI = MF.getFrameInfo();
280}
281
282 /// Enable use of alias analysis during code generation (during MI
283 /// scheduling, DAGCombine, etc.).
284bool RISCVSubtarget::useAA() const { return UseAA; }
285
287 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
289 : TuneInfo->MinimumJumpTableEntries;
290}
291
293 const SchedRegion &Region) const {
294 // Do bidirectional scheduling since it provides a more balanced scheduling
295 // leading to better performance. This will increase compile time.
296 Policy.OnlyTopDown = false;
297 Policy.OnlyBottomUp = false;
298
299 // Disabling the latency heuristic can reduce the number of spills/reloads but
300 // will cause some regressions on some cores.
301 Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
302
303 // Spilling is generally expensive on all RISC-V cores, so always enable
304 // register-pressure tracking. This will increase compile time.
305 Policy.ShouldTrackPressure = true;
306}
307
309 MachineSchedPolicy &Policy, const SchedRegion &Region) const {
310 MISched::Direction PostRASchedDirection = getPostRASchedDirection();
311 if (PostRASchedDirection == MISched::TopDown) {
312 Policy.OnlyTopDown = true;
313 Policy.OnlyBottomUp = false;
314 } else if (PostRASchedDirection == MISched::BottomUp) {
315 Policy.OnlyTopDown = false;
316 Policy.OnlyBottomUp = true;
317 } else if (PostRASchedDirection == MISched::Bidirectional) {
318 Policy.OnlyTopDown = false;
319 Policy.OnlyBottomUp = false;
320 }
321}
322
324 return UseMIPSLoadStorePairsOpt && HasVendorXMIPSLSP;
325}
326
328 return UseMIPSCCMovInsn && HasVendorXMIPSCMov;
329}
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< unsigned > SchedLoadLatency("riscv-sched-load-latency", cl::Hidden, cl::init(MCSchedModel::DefaultLoadLatency), cl::cat(MCScheduleOptions), cl::desc("Override the load latency (in cycles) in the scheduler model. " "A non-negative value overrides the target default."))
static cl::opt< unsigned > SchedMispredictPenalty("riscv-sched-mispredict-penalty", cl::Hidden, cl::init(MCSchedModel::DefaultMispredictPenalty), cl::cat(MCScheduleOptions), cl::desc("Override the mispredict penalty (in cycles) in the scheduler " "model. A non-negative value overrides the target default."))
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)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
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 getLoadLatency() const override
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
unsigned getMispredictionPenalty() const override
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:48
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
LLVM_ABI cl::OptionCategory MCScheduleOptions
static constexpr unsigned DefaultLoadLatency
Definition MCSchedule.h:315
static constexpr unsigned DefaultMispredictPenalty
Definition MCSchedule.h:327
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.
A region of an MBB for scheduling.