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