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"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "riscv-macro-fusion"
33
34#define GET_RISCV_MACRO_FUSION_PRED_IMPL
35#include "RISCVGenMacroFusion.inc"
36
37#undef DEBUG_TYPE
38#define DEBUG_TYPE "riscv-subtarget"
39
40#define GET_SUBTARGETINFO_TARGET_DESC
41#define GET_SUBTARGETINFO_CTOR
42#include "RISCVGenSubtargetInfo.inc"
43
44#define OPTIONS_STRUCT_DEFS
45#include "RISCVOptions.inc"
46
48
49#define GET_RISCVTuneInfoTable_IMPL
50#include "RISCVGenSearchableTables.inc"
51} // namespace llvm::RISCVTuneInfoTable
52
53void RISCVSubtarget::anchor() {}
54
56RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
57 StringRef TuneCPU, StringRef FS,
58 StringRef ABIName) {
59 // Determine default and user-specified characteristics
60 bool Is64Bit = TT.isArch64Bit();
61 if (CPU.empty() || CPU == "generic")
62 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
63
64 if (TuneCPU.empty())
65 TuneCPU = CPU;
66 if (TuneCPU == "generic")
67 TuneCPU = Is64Bit ? "generic-rv64" : "generic-rv32";
68
69 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
70 // If there is no TuneInfo for this CPU, we fail back to generic.
71 if (!TuneInfo)
72 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
73 assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
74
75 ParseSubtargetFeatures(CPU, TuneCPU, FS);
76
78
79 // Re-sync the flags.
80 HasStdExtZcd = hasFeature(RISCV::FeatureStdExtZcd);
81 HasStdExtZcf = hasFeature(RISCV::FeatureStdExtZcf);
82 HasStdExtC = hasFeature(RISCV::FeatureStdExtC);
83 HasStdExtZce = hasFeature(RISCV::FeatureStdExtZce);
84
85 // Can't be fatal: per-function subtargets mean this one may just be the
86 // module-level default with no matching function, e.g. -target-abi ilp32f
87 // with no global -mattr=+f but all functions have their own "+f" attribute.
88 if (auto ABIOrErr = RISCVABI::computeTargetABI(*this, ABIName)) {
89 TargetABI = *ABIOrErr;
90 } else {
91 errs() << "note: " << toString(ABIOrErr.takeError())
92 << " (ignoring target-abi)\n";
93 TargetABI = cantFail(RISCVABI::computeTargetABI(*this, ""));
94 }
95 RISCVFeatures::validate(TT, getFeatureBits());
96 return *this;
97}
98
100 StringRef TuneCPU, StringRef FS,
101 StringRef ABIName, unsigned RVVVectorBitsMin,
102 unsigned RVVVectorBitsMax,
103 const TargetMachine &TM)
104 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
105 CLOpts(static_cast<const RISCVTargetMachine &>(TM).getCLOpts()),
106 IsLittleEndian(TT.isLittleEndian()), RVVVectorBitsMin(RVVVectorBitsMin),
107 RVVVectorBitsMax(RVVVectorBitsMax),
108 FrameLowering(
109 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
110 InstrInfo(*this), TLInfo(TM, *this) {
111 TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
112}
113
115
119
126
132
134 if (!InstSelector) {
136 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),
137 *this, *getRegBankInfo()));
138 }
139 return InstSelector.get();
140}
141
143 if (!Legalizer)
144 Legalizer.reset(new RISCVLegalizerInfo(*this));
145 return Legalizer.get();
146}
147
149 if (!RegBankInfo)
150 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));
151 return RegBankInfo.get();
152}
153
155 return CLOpts.constant_pool_for_large_ints;
156}
157
158// Returns true if VT is a P extension packed SIMD type.
160 if (!HasStdExtP)
161 return false;
162
163 // RV32 supports 32-bit and 64-bit vectors. RV64 only support 64-bit vectors.
164 if (!is64Bit() && (VT == MVT::v4i8 || VT == MVT::v2i16))
165 return true;
166
167 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
168}
169
170// Returns true if VT is a P extension packed double-wide SIMD type.
172 if (!HasStdExtP || is64Bit())
173 return false;
174
175 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
176}
177
179 // Loading integer from constant pool needs two instructions (the reason why
180 // the minimum cost is 2): an address calculation instruction and a load
181 // instruction. Usually, address calculation and instructions used for
182 // building integers (addi, slli, etc.) can be done in one cycle, so here we
183 // set the default cost to (LoadLatency + 1) if no threshold is provided.
184 return CLOpts.max_build_ints_cost == 0
185 ? getLoadLatency() + 1
186 : std::max<unsigned>(2, CLOpts.max_build_ints_cost);
187}
188
190 return CLOpts.sched_mispredict_penalty.value_or(
191 getSchedModel().MispredictPenalty);
192}
193
195 return CLOpts.sched_load_latency.value_or(getSchedModel().LoadLatency);
196}
197
200 "Tried to get vector length without Zve or V extension support!");
201
202 // ZvlLen specifies the minimum required vlen. The upper bound provided by
203 // riscv-v-vector-bits-max should be no less than it.
204 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
205 report_fatal_error("riscv-v-vector-bits-max specified is lower "
206 "than the Zvl*b limitation");
207
208 return RVVVectorBitsMax;
209}
210
213 "Tried to get vector length without Zve or V extension support!");
214
215 if (RVVVectorBitsMin == -1U)
216 return ZvlLen;
217
218 // ZvlLen specifies the minimum required vlen. The lower bound provided by
219 // riscv-v-vector-bits-min should be no less than it.
220 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
221 report_fatal_error("riscv-v-vector-bits-min specified is lower "
222 "than the Zvl*b limitation");
223
224 return RVVVectorBitsMin;
225}
226
231
232bool RISCVSubtarget::enableSubRegLiveness() const { return true; }
233
235 return getSchedModel().hasInstrSchedModel();
236}
237
239 // We usually compute max call frame size after ISel. Do the computation now
240 // if the .mir file didn't specify it. Note that this will probably give you
241 // bogus values after PEI has eliminated the callframe setup/destroy pseudo
242 // instructions, specify explicitly if you need it to be correct.
243 MachineFrameInfo &MFI = MF.getFrameInfo();
246}
247
248 /// Enable use of alias analysis during code generation (during MI
249 /// scheduling, DAGCombine, etc.).
250bool RISCVSubtarget::useAA() const { return CLOpts.use_aa; }
251
253 return CLOpts.min_jump_table_entries.value_or(
254 TuneInfo->MinimumJumpTableEntries);
255}
256
258 const SchedRegion &Region) const {
259 // Do bidirectional scheduling since it provides a more balanced scheduling
260 // leading to better performance. This will increase compile time.
261 Policy.OnlyTopDown = false;
262 Policy.OnlyBottomUp = false;
263
264 // Disabling the latency heuristic can reduce the number of spills/reloads but
265 // will cause some regressions on some cores.
266 Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
267
268 // Spilling is generally expensive on all RISC-V cores, so always enable
269 // register-pressure tracking. This will increase compile time.
270 Policy.ShouldTrackPressure = true;
271}
272
274 MachineSchedPolicy &Policy, const SchedRegion &Region) const {
275 MISched::Direction PostRASchedDirection = getPostRASchedDirection();
276 if (PostRASchedDirection == MISched::TopDown) {
277 Policy.OnlyTopDown = true;
278 Policy.OnlyBottomUp = false;
279 } else if (PostRASchedDirection == MISched::BottomUp) {
280 Policy.OnlyTopDown = false;
281 Policy.OnlyBottomUp = true;
282 } else if (PostRASchedDirection == MISched::Bidirectional) {
283 Policy.OnlyTopDown = false;
284 Policy.OnlyBottomUp = false;
285 }
286}
287
289 return CLOpts.mips_load_store_pairs && HasVendorXMIPSLSP;
290}
291
293 return CLOpts.mips_ccmov && HasVendorXMIPSCMov;
294}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
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.
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
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
const RISCVOptions & getCLOpts() const
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
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 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)
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.
A region of an MBB for scheduling.