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"
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 // Can't be fatal: per-function subtargets mean this one may just be the
121 // module-level default with no matching function, e.g. -target-abi ilp32f
122 // with no global -mattr=+f but all functions have their own "+f" attribute.
123 if (auto ABIOrErr = RISCVABI::computeTargetABI(*this, ABIName)) {
124 TargetABI = *ABIOrErr;
125 } else {
126 errs() << "note: " << toString(ABIOrErr.takeError())
127 << " (ignoring target-abi)\n";
128 TargetABI = cantFail(RISCVABI::computeTargetABI(*this, ""));
129 }
130 RISCVFeatures::validate(TT, getFeatureBits());
131 return *this;
132}
133
135 StringRef TuneCPU, StringRef FS,
136 StringRef ABIName, unsigned RVVVectorBitsMin,
137 unsigned RVVVectorBitsMax,
138 const TargetMachine &TM)
139 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
140 IsLittleEndian(TT.isLittleEndian()), RVVVectorBitsMin(RVVVectorBitsMin),
141 RVVVectorBitsMax(RVVVectorBitsMax),
142 FrameLowering(
143 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
144 InstrInfo(*this), TLInfo(TM, *this) {
145 TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
146}
147
149
153
160
166
168 if (!InstSelector) {
170 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),
171 *this, *getRegBankInfo()));
172 }
173 return InstSelector.get();
174}
175
177 if (!Legalizer)
178 Legalizer.reset(new RISCVLegalizerInfo(*this));
179 return Legalizer.get();
180}
181
183 if (!RegBankInfo)
184 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));
185 return RegBankInfo.get();
186}
187
191
192// Returns true if VT is a P extension packed SIMD type.
194 if (!HasStdExtP)
195 return false;
196
197 // RV32 supports 32-bit and 64-bit vectors. RV64 only support 64-bit vectors.
198 if (!is64Bit() && (VT == MVT::v4i8 || VT == MVT::v2i16))
199 return true;
200
201 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
202}
203
204// Returns true if VT is a P extension packed double-wide SIMD type.
206 if (!HasStdExtP || is64Bit())
207 return false;
208
209 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
210}
211
213 // Loading integer from constant pool needs two instructions (the reason why
214 // the minimum cost is 2): an address calculation instruction and a load
215 // instruction. Usually, address calculation and instructions used for
216 // building integers (addi, slli, etc.) can be done in one cycle, so here we
217 // set the default cost to (LoadLatency + 1) if no threshold is provided.
218 return RISCVMaxBuildIntsCost == 0
219 ? getLoadLatency() + 1
220 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
221}
222
224 if (SchedMispredictPenalty.getNumOccurrences() > 0)
226 return getSchedModel().MispredictPenalty;
227}
228
230 if (SchedLoadLatency.getNumOccurrences() > 0)
231 return SchedLoadLatency;
232 return getSchedModel().LoadLatency;
233}
234
237 "Tried to get vector length without Zve or V extension support!");
238
239 // ZvlLen specifies the minimum required vlen. The upper bound provided by
240 // riscv-v-vector-bits-max should be no less than it.
241 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
242 report_fatal_error("riscv-v-vector-bits-max specified is lower "
243 "than the Zvl*b limitation");
244
245 return RVVVectorBitsMax;
246}
247
250 "Tried to get vector length without Zve or V extension support!");
251
252 if (RVVVectorBitsMin == -1U)
253 return ZvlLen;
254
255 // ZvlLen specifies the minimum required vlen. The lower bound provided by
256 // riscv-v-vector-bits-min should be no less than it.
257 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
258 report_fatal_error("riscv-v-vector-bits-min specified is lower "
259 "than the Zvl*b limitation");
260
261 return RVVVectorBitsMin;
262}
263
266 "Tried to get vector length without Zve or V extension support!");
267 return 8;
268}
269
274
275bool RISCVSubtarget::enableSubRegLiveness() const { return true; }
276
278 return getSchedModel().hasInstrSchedModel();
279}
280
282 // We usually compute max call frame size after ISel. Do the computation now
283 // if the .mir file didn't specify it. Note that this will probably give you
284 // bogus values after PEI has eliminated the callframe setup/destroy pseudo
285 // instructions, specify explicitly if you need it to be correct.
286 MachineFrameInfo &MFI = MF.getFrameInfo();
289}
290
291 /// Enable use of alias analysis during code generation (during MI
292 /// scheduling, DAGCombine, etc.).
293bool RISCVSubtarget::useAA() const { return UseAA; }
294
296 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
298 : TuneInfo->MinimumJumpTableEntries;
299}
300
302 const SchedRegion &Region) const {
303 // Do bidirectional scheduling since it provides a more balanced scheduling
304 // leading to better performance. This will increase compile time.
305 Policy.OnlyTopDown = false;
306 Policy.OnlyBottomUp = false;
307
308 // Disabling the latency heuristic can reduce the number of spills/reloads but
309 // will cause some regressions on some cores.
310 Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
311
312 // Spilling is generally expensive on all RISC-V cores, so always enable
313 // register-pressure tracking. This will increase compile time.
314 Policy.ShouldTrackPressure = true;
315}
316
318 MachineSchedPolicy &Policy, const SchedRegion &Region) const {
319 MISched::Direction PostRASchedDirection = getPostRASchedDirection();
320 if (PostRASchedDirection == MISched::TopDown) {
321 Policy.OnlyTopDown = true;
322 Policy.OnlyBottomUp = false;
323 } else if (PostRASchedDirection == MISched::BottomUp) {
324 Policy.OnlyTopDown = false;
325 Policy.OnlyBottomUp = true;
326 } else if (PostRASchedDirection == MISched::Bidirectional) {
327 Policy.OnlyTopDown = false;
328 Policy.OnlyBottomUp = false;
329 }
330}
331
333 return UseMIPSLoadStorePairsOpt && HasVendorXMIPSLSP;
334}
335
337 return UseMIPSCCMovInsn && HasVendorXMIPSCMov;
338}
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
Expected< 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
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
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.