LLVM 17.0.0git
RISCVSubtarget.cpp
Go to the documentation of this file.
1//===-- RISCVSubtarget.cpp - RISCV 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 RISCV specific subclass of TargetSubtargetInfo.
10//
11//===----------------------------------------------------------------------===//
12
13#include "RISCVSubtarget.h"
17#include "RISCV.h"
18#include "RISCVFrameLowering.h"
19#include "RISCVMacroFusion.h"
20#include "RISCVTargetMachine.h"
23
24using namespace llvm;
25
26#define DEBUG_TYPE "riscv-subtarget"
27
28#define GET_SUBTARGETINFO_TARGET_DESC
29#define GET_SUBTARGETINFO_CTOR
30#include "RISCVGenSubtargetInfo.inc"
31
32static cl::opt<bool> EnableSubRegLiveness("riscv-enable-subreg-liveness",
33 cl::init(true), cl::Hidden);
34
36 "riscv-v-fixed-length-vector-lmul-max",
37 cl::desc("The maximum LMUL value to use for fixed length vectors. "
38 "Fractional LMUL values are not supported."),
40
42 "riscv-disable-using-constant-pool-for-large-ints",
43 cl::desc("Disable using constant pool for large integers."),
44 cl::init(false), cl::Hidden);
45
47 "riscv-max-build-ints-cost",
48 cl::desc("The maximum cost used for building integers."), cl::init(0),
50
51void RISCVSubtarget::anchor() {}
52
54RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
55 StringRef TuneCPU, StringRef FS,
56 StringRef ABIName) {
57 // Determine default and user-specified characteristics
58 bool Is64Bit = TT.isArch64Bit();
59 if (CPU.empty() || CPU == "generic")
60 CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
61
62 if (TuneCPU.empty())
63 TuneCPU = CPU;
64
65 ParseSubtargetFeatures(CPU, TuneCPU, FS);
66 if (Is64Bit) {
67 XLenVT = MVT::i64;
68 XLen = 64;
69 }
70
71 TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
72 RISCVFeatures::validate(TT, getFeatureBits());
73 return *this;
74}
75
77 StringRef TuneCPU, StringRef FS,
78 StringRef ABIName, unsigned RVVVectorBitsMin,
79 unsigned RVVVectorBitsMax,
80 const TargetMachine &TM)
81 : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
82 RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
83 FrameLowering(
84 initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
85 InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
87 UserReservedRegister.set(RISCV::X18);
88
90 Legalizer.reset(new RISCVLegalizerInfo(*this));
91
92 auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo());
93 RegBankInfo.reset(RBI);
95 *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
96}
97
99 return CallLoweringInfo.get();
100}
101
103 return InstSelector.get();
104}
105
107 return Legalizer.get();
108}
109
111 return RegBankInfo.get();
112}
113
116}
117
119 // Loading integer from constant pool needs two instructions (the reason why
120 // the minimum cost is 2): an address calculation instruction and a load
121 // instruction. Usually, address calculation and instructions used for
122 // building integers (addi, slli, etc.) can be done in one cycle, so here we
123 // set the default cost to (LoadLatency + 1) if no threshold is provided.
124 return RISCVMaxBuildIntsCost == 0
125 ? getSchedModel().LoadLatency + 1
126 : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
127}
128
131 "Tried to get vector length without Zve or V extension support!");
132
133 // ZvlLen specifies the minimum required vlen. The upper bound provided by
134 // riscv-v-vector-bits-max should be no less than it.
135 if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
136 report_fatal_error("riscv-v-vector-bits-max specified is lower "
137 "than the Zvl*b limitation");
138
139 return RVVVectorBitsMax;
140}
141
144 "Tried to get vector length without Zve or V extension support!");
145
146 if (RVVVectorBitsMin == -1U)
147 return ZvlLen;
148
149 // ZvlLen specifies the minimum required vlen. The lower bound provided by
150 // riscv-v-vector-bits-min should be no less than it.
151 if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
152 report_fatal_error("riscv-v-vector-bits-min specified is lower "
153 "than the Zvl*b limitation");
154
155 return RVVVectorBitsMin;
156}
157
160 "Tried to get vector length without Zve or V extension support!");
162 llvm::has_single_bit<uint32_t>(RVVVectorLMULMax) &&
163 "V extension requires a LMUL to be at most 8 and a power of 2!");
164 return llvm::bit_floor(std::clamp<unsigned>(RVVVectorLMULMax, 1, 8));
165}
166
169}
170
172 // FIXME: Enable subregister liveness by default for RVV to better handle
173 // LMUL>1 and segment load/store.
175}
176
178 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
179 Mutations.push_back(createRISCVMacroFusionDAGMutation());
180}
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.
return InstrInfo
This file declares the targeting of the Machinelegalizer class for RISCV.
This file declares the targeting of the RegisterBankInfo class for RISCV.
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 > 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())
Provides the logic to select generic machine instructions.
This class provides the information for the target register banks.
This class provides the information for the target register banks.
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 useConstantPoolForLargeInts() const
unsigned getMaxRVVVectorSizeInBits() const
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
const RISCVRegisterInfo * getRegisterInfo() const override
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:78
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, StringRef ABIName)
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
bool isX18ReservedByDefault(const Triple &TT)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::unique_ptr< ScheduleDAGMutation > createRISCVMacroFusionDAGMutation()
Note that you have to add: DAG.addMutation(createRISCVMacroFusionDAGMutation()); to RISCVPassConfig::...
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:291
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, RISCVSubtarget &Subtarget, RISCVRegisterBankInfo &RBI)