123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- //===-- RISCVSubtarget.cpp - RISCV Subtarget Information ------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements the RISCV specific subclass of TargetSubtargetInfo.
- //
- //===----------------------------------------------------------------------===//
- #include "RISCVSubtarget.h"
- #include "RISCV.h"
- #include "RISCVFrameLowering.h"
- #include "RISCVMacroFusion.h"
- #include "RISCVTargetMachine.h"
- #include "GISel/RISCVCallLowering.h"
- #include "GISel/RISCVLegalizerInfo.h"
- #include "GISel/RISCVRegisterBankInfo.h"
- #include "llvm/MC/TargetRegistry.h"
- #include "llvm/Support/ErrorHandling.h"
- using namespace llvm;
- #define DEBUG_TYPE "riscv-subtarget"
- #define GET_SUBTARGETINFO_TARGET_DESC
- #define GET_SUBTARGETINFO_CTOR
- #include "RISCVGenSubtargetInfo.inc"
- static cl::opt<bool> EnableSubRegLiveness("riscv-enable-subreg-liveness",
- cl::init(false), 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);
- void RISCVSubtarget::anchor() {}
- RISCVSubtarget &
- RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU,
- StringRef TuneCPU, StringRef FS,
- StringRef ABIName) {
- // Determine default and user-specified characteristics
- bool Is64Bit = TT.isArch64Bit();
- if (CPU.empty() || CPU == "generic")
- CPU = Is64Bit ? "generic-rv64" : "generic-rv32";
- if (TuneCPU.empty())
- TuneCPU = CPU;
- ParseSubtargetFeatures(CPU, TuneCPU, FS);
- if (Is64Bit) {
- XLenVT = MVT::i64;
- XLen = 64;
- }
- TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
- RISCVFeatures::validate(TT, getFeatureBits());
- return *this;
- }
- RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU,
- StringRef TuneCPU, StringRef FS,
- StringRef ABIName, unsigned RVVVectorBitsMin,
- unsigned RVVVectorBitsMax,
- const TargetMachine &TM)
- : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS),
- RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax),
- FrameLowering(
- initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
- InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
- if (RISCV::isX18ReservedByDefault(TT))
- UserReservedRegister.set(RISCV::X18);
- CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
- Legalizer.reset(new RISCVLegalizerInfo(*this));
- auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo());
- RegBankInfo.reset(RBI);
- InstSelector.reset(createRISCVInstructionSelector(
- *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
- }
- const CallLowering *RISCVSubtarget::getCallLowering() const {
- return CallLoweringInfo.get();
- }
- InstructionSelector *RISCVSubtarget::getInstructionSelector() const {
- return InstSelector.get();
- }
- const LegalizerInfo *RISCVSubtarget::getLegalizerInfo() const {
- return Legalizer.get();
- }
- const RegisterBankInfo *RISCVSubtarget::getRegBankInfo() const {
- return RegBankInfo.get();
- }
- bool RISCVSubtarget::useConstantPoolForLargeInts() const {
- return !RISCVDisableUsingConstantPoolForLargeInts;
- }
- unsigned RISCVSubtarget::getMaxBuildIntsCost() const {
- // Loading integer from constant pool needs two instructions (the reason why
- // the minimum cost is 2): an address calculation instruction and a load
- // instruction. Usually, address calculation and instructions used for
- // building integers (addi, slli, etc.) can be done in one cycle, so here we
- // set the default cost to (LoadLatency + 1) if no threshold is provided.
- return RISCVMaxBuildIntsCost == 0
- ? getSchedModel().LoadLatency + 1
- : std::max<unsigned>(2, RISCVMaxBuildIntsCost);
- }
- unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const {
- assert(hasVInstructions() &&
- "Tried to get vector length without Zve or V extension support!");
- // ZvlLen specifies the minimum required vlen. The upper bound provided by
- // riscv-v-vector-bits-max should be no less than it.
- if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen)
- report_fatal_error("riscv-v-vector-bits-max specified is lower "
- "than the Zvl*b limitation");
- return RVVVectorBitsMax;
- }
- unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {
- assert(hasVInstructions() &&
- "Tried to get vector length without Zve or V extension support!");
- if (RVVVectorBitsMin == -1U)
- return ZvlLen;
- // ZvlLen specifies the minimum required vlen. The lower bound provided by
- // riscv-v-vector-bits-min should be no less than it.
- if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen)
- report_fatal_error("riscv-v-vector-bits-min specified is lower "
- "than the Zvl*b limitation");
- return RVVVectorBitsMin;
- }
- unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {
- assert(hasVInstructions() &&
- "Tried to get vector length without Zve or V extension support!");
- assert(RVVVectorLMULMax <= 8 && isPowerOf2_32(RVVVectorLMULMax) &&
- "V extension requires a LMUL to be at most 8 and a power of 2!");
- return PowerOf2Floor(
- std::max<unsigned>(std::min<unsigned>(RVVVectorLMULMax, 8), 1));
- }
- bool RISCVSubtarget::useRVVForFixedLengthVectors() const {
- return hasVInstructions() && getMinRVVVectorSizeInBits() != 0;
- }
- bool RISCVSubtarget::enableSubRegLiveness() const {
- // FIXME: Enable subregister liveness by default for RVV to better handle
- // LMUL>1 and segment load/store.
- return EnableSubRegLiveness;
- }
- void RISCVSubtarget::getPostRAMutations(
- std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
- Mutations.push_back(createRISCVMacroFusionDAGMutation());
- }
|