LLVM 19.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"
19#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
42static cl::opt<bool> EnableSubRegLiveness("riscv-enable-subreg-liveness",
43 cl::init(true), cl::Hidden);
44
46 "riscv-v-fixed-length-vector-lmul-max",
47 cl::desc("The maximum LMUL value to use for fixed length vectors. "
48 "Fractional LMUL values are not supported."),
50
52 "riscv-disable-using-constant-pool-for-large-ints",
53 cl::desc("Disable using constant pool for large integers."),
54 cl::init(false), cl::Hidden);
55
57 "riscv-max-build-ints-cost",
58 cl::desc("The maximum cost used for building integers."), cl::init(0),
60
61static cl::opt<bool> UseAA("riscv-use-aa", cl::init(true),
62 cl::desc("Enable the use of AA during codegen."));
63
65 "riscv-min-jump-table-entries", cl::Hidden,
66 cl::desc("Set minimum number of entries to use a jump table on RISCV"));
67
68void RISCVSubtarget::anchor() {}
69
71RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
72 StringRef TuneCPU, StringRef FS,
73 StringRef ABIName) {
74 // Determine default and user-specified characteristics
75 bool Is64Bit = TT.isArch64Bit();
76 if (CPU.empty() || CPU == "generic")
77 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
78
79 if (TuneCPU.empty())
80 TuneCPU = CPU;
81
82 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo(TuneCPU);
83 // If there is no TuneInfo for this CPU, we fail back to generic.
84 if (!TuneInfo)
85 TuneInfo = RISCVTuneInfoTable::getRISCVTuneInfo("generic");
86 assert(TuneInfo && "TuneInfo shouldn't be nullptr!");
87
88 ParseSubtargetFeatures(CPU, TuneCPU, FS);
89 TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
90 RISCVFeatures::validate(TT, getFeatureBits());
91 return *this;
92}
93
95 StringRef TuneCPU, StringRef FS,
96 StringRef ABIName, unsigned RVVVectorBitsMin,
97 unsigned RVVVectorBitsMax,
98 const TargetMachine &TM)
99 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
100 RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
101 FrameLowering(
102 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
103 InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
105 Legalizer.reset(new RISCVLegalizerInfo(*this));
106
107 auto *RBI = new RISCVRegisterBankInfo(getHwMode());
108 RegBankInfo.reset(RBI);
110 *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
111}
112
114 return CallLoweringInfo.get();
115}
116
118 return InstSelector.get();
119}
120
122 return Legalizer.get();
123}
124
126 return RegBankInfo.get();
127}
128
131}
132
134 // Loading integer from constant pool needs two instructions (the reason why
135 // the minimum cost is 2): an address calculation instruction and a load
136 // instruction. Usually, address calculation and instructions used for
137 // building integers (addi, slli, etc.) can be done in one cycle, so here we
138 // set the default cost to (LoadLatency + 1) if no threshold is provided.
139 return RISCVMaxBuildIntsCost == 0
140 ? getSchedModel().LoadLatency + 1
141 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
142}
143
146 "Tried to get vector length without Zve or V extension support!");
147
148 // ZvlLen specifies the minimum required vlen. The upper bound provided by
149 // riscv-v-vector-bits-max should be no less than it.
150 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
151 report_fatal_error("riscv-v-vector-bits-max specified is lower "
152 "than the Zvl*b limitation");
153
154 return RVVVectorBitsMax;
155}
156
159 "Tried to get vector length without Zve or V extension support!");
160
161 if (RVVVectorBitsMin == -1U)
162 return ZvlLen;
163
164 // ZvlLen specifies the minimum required vlen. The lower bound provided by
165 // riscv-v-vector-bits-min should be no less than it.
166 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
167 report_fatal_error("riscv-v-vector-bits-min specified is lower "
168 "than the Zvl*b limitation");
169
170 return RVVVectorBitsMin;
171}
172
175 "Tried to get vector length without Zve or V extension support!");
177 llvm::has_single_bit<uint32_t>(RVVVectorLMULMax) &&
178 "V extension requires a LMUL to be at most 8 and a power of 2!");
179 return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8));
180}
181
184}
185
187 // FIXME: Enable subregister liveness by default for RVV to better handle
188 // LMUL>1 and segment load/store.
190}
191
193 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
194 Mutations.push_back(createMacroFusionDAGMutation(getMacroFusions()));
195}
196
197 /// Enable use of alias analysis during code generation (during MI
198 /// scheduling, DAGCombine, etc.).
199bool RISCVSubtarget::useAA() const { return UseAA; }
200
202 return RISCVMinimumJumpTableEntries.getNumOccurrences() > 0
204 : TuneInfo->MinimumJumpTableEntries;
205}
static cl::opt< bool > UseAA("aarch64-use-aa", cl::init(true), cl::desc("Enable the use of AA during codegen."))
static cl::opt< bool > EnableSubRegLiveness("enable-subreg-liveness", cl::Hidden, cl::init(true), cl::desc("Enable subregister liveness tracking."))
const char LLVMTargetMachineRef TM
This file describes how to lower LLVM calls to machine code calls.
This file declares the targeting of the Machinelegalizer class for RISC-V.
This file declares the targeting of the RegisterBankInfo class for RISC-V.
static cl::opt< bool > EnableSubRegLiveness("riscv-enable-subreg-liveness", cl::init(true), cl::Hidden)
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< 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 > 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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class provides the information for the target register banks.
unsigned getMinimumJumpTableEntries() const
void getPostRAMutations(std::vector< std::unique_ptr< ScheduleDAGMutation > > &Mutations) const override
const LegalizerInfo * getLegalizerInfo() const override
const RegisterBankInfo * getRegBankInfo() const override
unsigned getMaxLMULForFixedLengthVectors() const
bool useRVVForFixedLengthVectors() const
std::unique_ptr< RegisterBankInfo > RegBankInfo
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)
const CallLowering * getCallLowering() const override
InstructionSelector * getInstructionSelector() const override
unsigned getMaxBuildIntsCost() const
bool hasVInstructions() const
bool useAA() const override
Enable use of alias analysis during code generation (during MI scheduling, DAGCombine,...
bool useConstantPoolForLargeInts() const
unsigned getMaxRVVVectorSizeInBits() const
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
std::unique_ptr< CallLowering > CallLoweringInfo
const RISCVTargetLowering * getTargetLowering() const override
bool enableSubRegLiveness() const override
Holds all the information related to register banks.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::unique_ptr< ScheduleDAGMutation > createMacroFusionDAGMutation(ArrayRef< MacroFusionPredTy > Predicates, bool BranchOnly=false)
Create a DAG scheduling mutation to pair instructions back to back for instructions that benefit acco...
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, RISCVSubtarget &Subtarget, RISCVRegisterBankInfo &RBI)