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"
16#include "RISCV.h"
17#include "RISCVFrameLowering.h"
19#include "RISCVTargetMachine.h"
22
23using namespace llvm;
24
25#define DEBUG_TYPE "riscv-subtarget"
26
27#define GET_SUBTARGETINFO_TARGET_DESC
28#define GET_SUBTARGETINFO_CTOR
29#include "RISCVGenSubtargetInfo.inc"
30
31#define GET_RISCV_MACRO_FUSION_PRED_IMPL
32#include "RISCVGenMacroFusion.inc"
33
35
36#define GET_RISCVTuneInfoTable_IMPL
37#include "RISCVGenSearchableTables.inc"
38} // namespace llvm::RISCVTuneInfoTable
39
41 "riscv-v-fixed-length-vector-lmul-max",
42 cl::desc("The maximum LMUL value to use for fixed length vectors. "
43 "Fractional LMUL values are not supported."),
45
47 "riscv-disable-using-constant-pool-for-large-ints",
48 cl::desc("Disable using constant pool for large integers."),
49 cl::init(false), cl::Hidden);
50
52 "riscv-max-build-ints-cost",
53 cl::desc("The maximum cost used for building integers."), cl::init(0),
55
56static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),
57 cl::desc("Enable the use of AA during codegen."));
58
60 "riscv-min-jump-table-entries", cl::Hidden,
61 cl::desc("Set minimum number of entries to use a jump table on RISCV"));
62
64 "use-riscv-mips-load-store-pairs",
65 cl::desc("Enable the load/store pair optimization pass"), cl::init(false),
67
68static cl::opt<bool> UseMIPSCCMovInsn("use-riscv-mips-ccmov",
69 cl::desc("Use 'mips.ccmov' instruction"),
70 cl::init(true), cl::Hidden);
71
73 "riscv-enable-p-ext-simd-codegen",
74 cl::desc("Turn on P Extension SIMD codegen(This is a temporary switch "
75 "where only partial codegen is currently supported)"),
76 cl::init(false), cl::Hidden);
77
78void RISCVSubtarget::anchor() {}
79
81RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
82 StringRef TuneCPU, StringRef FS,
83 StringRef ABIName) {
84 // Determine default and user-specified characteristics
85 bool Is64Bit = TT.isArch64Bit();
86 if (CPU.empty() || CPU == "generic")
87 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
88
89 if (TuneCPU.empty())
90 TuneCPU = CPU;
91 if (TuneCPU == "generic")
92 TuneCPU = Is64Bit ? "generic-rv64" : "generic-rv32";
93
94 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
95 // If there is no TuneInfo for this CPU, we fail back to generic.
96 if (!TuneInfo)
97 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
98 assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
99
100 ParseSubtargetFeatures(CPU, TuneCPU, FS);
101 TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
102 RISCVFeatures::validate(TT, getFeatureBits());
103 return *this;
104}
105
107 StringRef TuneCPU, StringRef FS,
108 StringRef ABIName, unsigned RVVVectorBitsMin,
109 unsigned RVVVectorBitsMax,
110 const TargetMachine &TM)
111 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
112 IsLittleEndian(TT.isLittleEndian()), RVVVectorBitsMin(RVVVectorBitsMin),
113 RVVVectorBitsMax(RVVVectorBitsMax),
114 FrameLowering(
115 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
116 InstrInfo(*this), TLInfo(TM, *this) {
117 TSInfo = std::make_unique<RISCVSelectionDAGInfo>();
118}
119
121
125
131
133 if (!InstSelector) {
135 *static_cast<const RISCVTargetMachine *>(&TLInfo.getTargetMachine()),
136 *this, *getRegBankInfo()));
137 }
138 return InstSelector.get();
139}
140
142 if (!Legalizer)
143 Legalizer.reset(new RISCVLegalizerInfo(*this));
144 return Legalizer.get();
145}
146
148 if (!RegBankInfo)
149 RegBankInfo.reset(new RISCVRegisterBankInfo(getHwMode()));
150 return RegBankInfo.get();
151}
152
156
158 return HasStdExtP && EnablePExtSIMDCodeGen;
159}
160
161// Returns true if VT is a P extension packed SIMD type that fits in XLen.
164 return false;
165
166 if (is64Bit())
167 return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
168 return VT == MVT::v4i8 || VT == MVT::v2i16;
169}
170
172 // Loading integer from constant pool needs two instructions (the reason why
173 // the minimum cost is 2): an address calculation instruction and a load
174 // instruction. Usually, address calculation and instructions used for
175 // building integers (addi, slli, etc.) can be done in one cycle, so here we
176 // set the default cost to (LoadLatency + 1) if no threshold is provided.
177 return RISCVMaxBuildIntsCost == 0
178 ? getSchedModel().LoadLatency + 1
179 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
180}
181
184 "Tried to get vector length without Zve or V extension support!");
185
186 // ZvlLen specifies the minimum required vlen. The upper bound provided by
187 // riscv-v-vector-bits-max should be no less than it.
188 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
189 report_fatal_error("riscv-v-vector-bits-max specified is lower "
190 "than the Zvl*b limitation");
191
192 return RVVVectorBitsMax;
193}
194
197 "Tried to get vector length without Zve or V extension support!");
198
199 if (RVVVectorBitsMin == -1U)
200 return ZvlLen;
201
202 // ZvlLen specifies the minimum required vlen. The lower bound provided by
203 // riscv-v-vector-bits-min should be no less than it.
204 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
205 report_fatal_error("riscv-v-vector-bits-min specified is lower "
206 "than the Zvl*b limitation");
207
208 return RVVVectorBitsMin;
209}
210
213 "Tried to get vector length without Zve or V extension support!");
216 "V extension requires a LMUL to be at most 8 and a power of 2!");
217 return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8));
218}
219
224
225bool RISCVSubtarget::enableSubRegLiveness() const { return true; }
226
228 return getSchedModel().hasInstrSchedModel();
229}
230
231 /// Enable use of alias analysis during code generation (during MI
232 /// scheduling, DAGCombine, etc.).
233bool RISCVSubtarget::useAA() const { return UseAA; }
234
236 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
238 : TuneInfo->MinimumJumpTableEntries;
239}
240
242 const SchedRegion &Region) const {
243 // Do bidirectional scheduling since it provides a more balanced scheduling
244 // leading to better performance. This will increase compile time.
245 Policy.OnlyTopDown = false;
246 Policy.OnlyBottomUp = false;
247
248 // Disabling the latency heuristic can reduce the number of spills/reloads but
249 // will cause some regressions on some cores.
250 Policy.DisableLatencyHeuristic = DisableLatencySchedHeuristic;
251
252 // Spilling is generally expensive on all RISC-V cores, so always enable
253 // register-pressure tracking. This will increase compile time.
254 Policy.ShouldTrackPressure = true;
255}
256
258 MachineSchedPolicy &Policy, const SchedRegion &Region) const {
259 MISched::Direction PostRASchedDirection = getPostRASchedDirection();
260 if (PostRASchedDirection == MISched::TopDown) {
261 Policy.OnlyTopDown = true;
262 Policy.OnlyBottomUp = false;
263 } else if (PostRASchedDirection == MISched::BottomUp) {
264 Policy.OnlyTopDown = false;
265 Policy.OnlyBottomUp = true;
266 } else if (PostRASchedDirection == MISched::Bidirectional) {
267 Policy.OnlyTopDown = false;
268 Policy.OnlyBottomUp = false;
269 }
270}
271
273 return UseMIPSLoadStorePairsOpt && HasVendorXMIPSLSP;
274}
275
277 return UseMIPSCCMovInsn && HasVendorXMIPSCMov;
278}
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 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 > EnablePExtSIMDCodeGen("riscv-enable-p-ext-simd-codegen", cl::desc("Turn on P Extension SIMD codegen(This is a temporary switch " "where only partial codegen is currently supported)"), 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.
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
bool useRVVForFixedLengthVectors() const
MISched::Direction getPostRASchedDirection() const
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
bool enablePExtSIMDCodeGen() const
~RISCVSubtarget() override
unsigned getMaxRVVVectorSizeInBits() const
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
std::unique_ptr< RISCVRegisterBankInfo > RegBankInfo
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:143
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)
static constexpr unsigned RVVBitsPerBlock
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, const RISCVSubtarget &Subtarget, const RISCVRegisterBankInfo &RBI)
constexpr bool has_single_bit(T Value) noexcept
Definition bit.h:147
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:330
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.
A region of an MBB for scheduling.