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-v-fixed-length-vector-lmul-max",
44 cl::desc("The maximum LMUL value to use for fixed length vectors. "
45 "Fractional LMUL values are not supported."),
47
49 "riscv-disable-using-constant-pool-for-large-ints",
50 cl::desc("Disable using constant pool for large integers."),
51 cl::init(false), cl::Hidden);
52
54 "riscv-max-build-ints-cost",
55 cl::desc("The maximum cost used for building integers."), cl::init(0),
57
58static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),
59 cl::desc("Enable the use of AA during codegen."));
60
62 "riscv-min-jump-table-entries", cl::Hidden,
63 cl::desc("Set minimum number of entries to use a jump table on RISCV"));
64
66 "use-riscv-mips-load-store-pairs",
67 cl::desc("Enable the load/store pair optimization pass"), cl::init(false),
69
70static cl::opt<bool> UseMIPSCCMovInsn("use-riscv-mips-ccmov",
71 cl::desc("Use 'mips.ccmov' instruction"),
72 cl::init(true), cl::Hidden);
73
74void RISCVSubtarget::anchor() {}
75
77RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
78 StringRef TuneCPU, StringRef FS,
79 StringRef ABIName) {
80 // Determine default and user-specified characteristics
81 bool Is64Bit = TT.isArch64Bit();
82 if (CPU.empty() || CPU == "generic")
83 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
84
85 if (TuneCPU.empty())
86 TuneCPU = CPU;
87 if (TuneCPU == "generic")
88 TuneCPU = Is64Bit ? "generic-rv64" : "generic-rv32";
89
90 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
91 // If there is no TuneInfo for this CPU, we fail back to generic.
92 if (!TuneInfo)
93 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
94 assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
95
96 ParseSubtargetFeatures(CPU, TuneCPU, FS);
97
99
100 // Re-sync the flags.
101 HasStdExtZcd = hasFeature(RISCV::FeatureStdExtZcd);
102 HasStdExtZcf = hasFeature(RISCV::FeatureStdExtZcf);
103 HasStdExtC = hasFeature(RISCV::FeatureStdExtC);
104 HasStdExtZce = hasFeature(RISCV::FeatureStdExtZce);
105
106 TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
107 RISCVFeatures::validate(TT, getFeatureBits());
108 return *this;
109}
110
112 StringRef TuneCPU, StringRef FS,
113 StringRef ABIName, unsigned RVVVectorBitsMin,
114 unsigned RVVVectorBitsMax,
115 const TargetMachine &TM)
116 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
117 IsLittleEndian(TT.isLittleEndian()), RVVVectorBitsMin(RVVVectorBitsMin),
118 RVVVectorBitsMax(RVVVectorBitsMax),
119 FrameLowering(
120 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
121 InstrInfo(*this), TLInfo(TM, *this) {
122 TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
123}
124
126
130
137
143
145 if (!InstSelector) {
147 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),
148 *this, *getRegBankInfo()));
149 }
150 return InstSelector.get();
151}
152
154 if (!Legalizer)
155 Legalizer.reset(new RISCVLegalizerInfo(*this));
156 return Legalizer.get();
157}
158
160 if (!RegBankInfo)
161 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));
162 return RegBankInfo.get();
163}
164
168
169// Returns true if VT is a P extension packed SIMD type that fits in XLen.
171 if (!HasStdExtP)
172 return false;
173
174 if (is64Bit())
175 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
176 return VT == MVT::v4i8 || VT == MVT::v2i16;
177}
178
180 // Loading integer from constant pool needs two instructions (the reason why
181 // the minimum cost is 2): an address calculation instruction and a load
182 // instruction. Usually, address calculation and instructions used for
183 // building integers (addi, slli, etc.) can be done in one cycle, so here we
184 // set the default cost to (LoadLatency + 1) if no threshold is provided.
185 return RISCVMaxBuildIntsCost == 0
186 ? getSchedModel().LoadLatency + 1
187 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
188}
189
192 "Tried to get vector length without Zve or V extension support!");
193
194 // ZvlLen specifies the minimum required vlen. The upper bound provided by
195 // riscv-v-vector-bits-max should be no less than it.
196 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
197 report_fatal_error("riscv-v-vector-bits-max specified is lower "
198 "than the Zvl*b limitation");
199
200 return RVVVectorBitsMax;
201}
202
205 "Tried to get vector length without Zve or V extension support!");
206
207 if (RVVVectorBitsMin == -1U)
208 return ZvlLen;
209
210 // ZvlLen specifies the minimum required vlen. The lower bound provided by
211 // riscv-v-vector-bits-min should be no less than it.
212 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
213 report_fatal_error("riscv-v-vector-bits-min specified is lower "
214 "than the Zvl*b limitation");
215
216 return RVVVectorBitsMin;
217}
218
221 "Tried to get vector length without Zve or V extension support!");
224 "V extension requires a LMUL to be at most 8 and a power of 2!");
225 return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8));
226}
227
232
233bool RISCVSubtarget::enableSubRegLiveness() const { return true; }
234
236 return getSchedModel().hasInstrSchedModel();
237}
238
240 // We usually compute max call frame size after ISel. Do the computation now
241 // if the .mir file didn't specify it. Note that this will probably give you
242 // bogus values after PEI has eliminated the callframe setup/destroy pseudo
243 // instructions, specify explicitly if you need it to be correct.
244 MachineFrameInfo &MFI = MF.getFrameInfo();
247}
248
249 /// Enable use of alias analysis during code generation (during MI
250 /// scheduling, DAGCombine, etc.).
251bool RISCVSubtarget::useAA() const { return UseAA; }
252
254 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
256 : TuneInfo->MinimumJumpTableEntries;
257}
258
260 const SchedRegion &Region) const {
261 // Do bidirectional scheduling since it provides a more balanced scheduling
262 // leading to better performance. This will increase compile time.
263 Policy.OnlyTopDown = false;
264 Policy.OnlyBottomUp = false;
265
266 // Disabling the latency heuristic can reduce the number of spills/reloads but
267 // will cause some regressions on some cores.
268 Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
269
270 // Spilling is generally expensive on all RISC-V cores, so always enable
271 // register-pressure tracking. This will increase compile time.
272 Policy.ShouldTrackPressure = true;
273}
274
276 MachineSchedPolicy &Policy, const SchedRegion &Region) const {
277 MISched::Direction PostRASchedDirection = getPostRASchedDirection();
278 if (PostRASchedDirection == MISched::TopDown) {
279 Policy.OnlyTopDown = true;
280 Policy.OnlyBottomUp = false;
281 } else if (PostRASchedDirection == MISched::BottomUp) {
282 Policy.OnlyTopDown = false;
283 Policy.OnlyBottomUp = true;
284 } else if (PostRASchedDirection == MISched::Bidirectional) {
285 Policy.OnlyTopDown = false;
286 Policy.OnlyBottomUp = false;
287 }
288}
289
291 return UseMIPSLoadStorePairsOpt && HasVendorXMIPSLSP;
292}
293
295 return UseMIPSCCMovInsn && HasVendorXMIPSCMov;
296}
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."))
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 > RVVVectorLMULMax("riscv-v-fixed-length-vector-lmul-max", cl::desc("The maximum LMUL value to use for fixed length vectors. " "Fractional LMUL values are not supported."), cl::init(8), cl::Hidden)
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 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...
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
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 Triple &TT, const FeatureBitset &FeatureBits, 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)
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:149
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.
A region of an MBB for scheduling.