1085 lines · cpp
1//===-- RISCVRegisterInfo.cpp - RISC-V Register Information -----*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the RISC-V implementation of the TargetRegisterInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "RISCVRegisterInfo.h"14#include "RISCV.h"15#include "RISCVSubtarget.h"16#include "llvm/ADT/SmallSet.h"17#include "llvm/BinaryFormat/Dwarf.h"18#include "llvm/CodeGen/MachineFrameInfo.h"19#include "llvm/CodeGen/MachineFunction.h"20#include "llvm/CodeGen/MachineInstrBuilder.h"21#include "llvm/CodeGen/RegisterScavenging.h"22#include "llvm/CodeGen/TargetFrameLowering.h"23#include "llvm/CodeGen/TargetInstrInfo.h"24#include "llvm/IR/DebugInfoMetadata.h"25#include "llvm/Support/ErrorHandling.h"26 27#define GET_REGINFO_TARGET_DESC28#include "RISCVGenRegisterInfo.inc"29 30using namespace llvm;31 32static cl::opt<bool> DisableCostPerUse("riscv-disable-cost-per-use",33 cl::init(false), cl::Hidden);34static cl::opt<bool>35 DisableRegAllocHints("riscv-disable-regalloc-hints", cl::Hidden,36 cl::init(false),37 cl::desc("Disable two address hints for register "38 "allocation"));39 40static_assert(RISCV::X1 == RISCV::X0 + 1, "Register list not consecutive");41static_assert(RISCV::X31 == RISCV::X0 + 31, "Register list not consecutive");42static_assert(RISCV::F1_H == RISCV::F0_H + 1, "Register list not consecutive");43static_assert(RISCV::F31_H == RISCV::F0_H + 31,44 "Register list not consecutive");45static_assert(RISCV::F1_F == RISCV::F0_F + 1, "Register list not consecutive");46static_assert(RISCV::F31_F == RISCV::F0_F + 31,47 "Register list not consecutive");48static_assert(RISCV::F1_D == RISCV::F0_D + 1, "Register list not consecutive");49static_assert(RISCV::F31_D == RISCV::F0_D + 31,50 "Register list not consecutive");51static_assert(RISCV::F1_Q == RISCV::F0_Q + 1, "Register list not consecutive");52static_assert(RISCV::F31_Q == RISCV::F0_Q + 31,53 "Register list not consecutive");54static_assert(RISCV::V1 == RISCV::V0 + 1, "Register list not consecutive");55static_assert(RISCV::V31 == RISCV::V0 + 31, "Register list not consecutive");56 57RISCVRegisterInfo::RISCVRegisterInfo(unsigned HwMode)58 : RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0,59 /*PC*/0, HwMode) {}60 61const MCPhysReg *62RISCVRegisterInfo::getIPRACSRegs(const MachineFunction *MF) const {63 return CSR_IPRA_SaveList;64}65 66const MCPhysReg *67RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {68 auto &Subtarget = MF->getSubtarget<RISCVSubtarget>();69 if (MF->getFunction().getCallingConv() == CallingConv::GHC)70 return CSR_NoRegs_SaveList;71 if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)72 return Subtarget.hasStdExtE() ? CSR_RT_MostRegs_RVE_SaveList73 : CSR_RT_MostRegs_SaveList;74 if (MF->getFunction().hasFnAttribute("interrupt")) {75 if (Subtarget.hasVInstructions()) {76 if (Subtarget.hasStdExtD())77 return Subtarget.hasStdExtE() ? CSR_XLEN_F64_V_Interrupt_RVE_SaveList78 : CSR_XLEN_F64_V_Interrupt_SaveList;79 if (Subtarget.hasStdExtF())80 return Subtarget.hasStdExtE() ? CSR_XLEN_F32_V_Interrupt_RVE_SaveList81 : CSR_XLEN_F32_V_Interrupt_SaveList;82 return Subtarget.hasStdExtE() ? CSR_XLEN_V_Interrupt_RVE_SaveList83 : CSR_XLEN_V_Interrupt_SaveList;84 }85 if (Subtarget.hasStdExtD())86 return Subtarget.hasStdExtE() ? CSR_XLEN_F64_Interrupt_RVE_SaveList87 : CSR_XLEN_F64_Interrupt_SaveList;88 if (Subtarget.hasStdExtF())89 return Subtarget.hasStdExtE() ? CSR_XLEN_F32_Interrupt_RVE_SaveList90 : CSR_XLEN_F32_Interrupt_SaveList;91 return Subtarget.hasStdExtE() ? CSR_Interrupt_RVE_SaveList92 : CSR_Interrupt_SaveList;93 }94 95 bool HasVectorCSR =96 MF->getFunction().getCallingConv() == CallingConv::RISCV_VectorCall &&97 Subtarget.hasVInstructions();98 99 switch (Subtarget.getTargetABI()) {100 default:101 llvm_unreachable("Unrecognized ABI");102 case RISCVABI::ABI_ILP32E:103 case RISCVABI::ABI_LP64E:104 return CSR_ILP32E_LP64E_SaveList;105 case RISCVABI::ABI_ILP32:106 case RISCVABI::ABI_LP64:107 if (HasVectorCSR)108 return CSR_ILP32_LP64_V_SaveList;109 return CSR_ILP32_LP64_SaveList;110 case RISCVABI::ABI_ILP32F:111 case RISCVABI::ABI_LP64F:112 if (HasVectorCSR)113 return CSR_ILP32F_LP64F_V_SaveList;114 return CSR_ILP32F_LP64F_SaveList;115 case RISCVABI::ABI_ILP32D:116 case RISCVABI::ABI_LP64D:117 if (HasVectorCSR)118 return CSR_ILP32D_LP64D_V_SaveList;119 return CSR_ILP32D_LP64D_SaveList;120 }121}122 123BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {124 const RISCVFrameLowering *TFI = getFrameLowering(MF);125 BitVector Reserved(getNumRegs());126 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();127 128 for (size_t Reg = 0; Reg < getNumRegs(); Reg++) {129 // Mark any GPRs requested to be reserved as such130 if (Subtarget.isRegisterReservedByUser(Reg))131 markSuperRegs(Reserved, Reg);132 133 // Mark all the registers defined as constant in TableGen as reserved.134 if (isConstantPhysReg(Reg))135 markSuperRegs(Reserved, Reg);136 }137 138 // Use markSuperRegs to ensure any register aliases are also reserved139 markSuperRegs(Reserved, RISCV::X2_H); // sp140 markSuperRegs(Reserved, RISCV::X3_H); // gp141 markSuperRegs(Reserved, RISCV::X4_H); // tp142 if (TFI->hasFP(MF))143 markSuperRegs(Reserved, RISCV::X8_H); // fp144 // Reserve the base register if we need to realign the stack and allocate145 // variable-sized objects at runtime.146 if (TFI->hasBP(MF))147 markSuperRegs(Reserved, RISCVABI::getBPReg()); // bp148 149 // Additionally reserve dummy register used to form the register pair150 // beginning with 'x0' for instructions that take register pairs.151 markSuperRegs(Reserved, RISCV::DUMMY_REG_PAIR_WITH_X0);152 153 // There are only 16 GPRs for RVE.154 if (Subtarget.hasStdExtE())155 for (MCPhysReg Reg = RISCV::X16_H; Reg <= RISCV::X31_H; Reg++)156 markSuperRegs(Reserved, Reg);157 158 // V registers for code generation. We handle them manually.159 markSuperRegs(Reserved, RISCV::VL);160 markSuperRegs(Reserved, RISCV::VTYPE);161 markSuperRegs(Reserved, RISCV::VXSAT);162 markSuperRegs(Reserved, RISCV::VXRM);163 164 // Floating point environment registers.165 markSuperRegs(Reserved, RISCV::FRM);166 markSuperRegs(Reserved, RISCV::FFLAGS);167 168 // SiFive VCIX state registers.169 markSuperRegs(Reserved, RISCV::SF_VCIX_STATE);170 171 if (MF.getFunction().getCallingConv() == CallingConv::GRAAL) {172 if (Subtarget.hasStdExtE())173 reportFatalUsageError("Graal reserved registers do not exist in RVE");174 markSuperRegs(Reserved, RISCV::X23_H);175 markSuperRegs(Reserved, RISCV::X27_H);176 }177 178 // Shadow stack pointer.179 markSuperRegs(Reserved, RISCV::SSP);180 181 // XSfmmbase182 for (MCPhysReg Reg = RISCV::T0; Reg <= RISCV::T15; Reg++)183 markSuperRegs(Reserved, Reg);184 185 assert(checkAllSuperRegsMarked(Reserved));186 return Reserved;187}188 189bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF,190 MCRegister PhysReg) const {191 return !MF.getSubtarget().isRegisterReservedByUser(PhysReg);192}193 194const uint32_t *RISCVRegisterInfo::getNoPreservedMask() const {195 return CSR_NoRegs_RegMask;196}197 198void RISCVRegisterInfo::adjustReg(MachineBasicBlock &MBB,199 MachineBasicBlock::iterator II,200 const DebugLoc &DL, Register DestReg,201 Register SrcReg, StackOffset Offset,202 MachineInstr::MIFlag Flag,203 MaybeAlign RequiredAlign) const {204 205 if (DestReg == SrcReg && !Offset.getFixed() && !Offset.getScalable())206 return;207 208 MachineFunction &MF = *MBB.getParent();209 MachineRegisterInfo &MRI = MF.getRegInfo();210 const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();211 const RISCVInstrInfo *TII = ST.getInstrInfo();212 213 // Optimize compile time offset case214 if (Offset.getScalable()) {215 if (auto VLEN = ST.getRealVLen()) {216 // 1. Multiply the number of v-slots by the (constant) length of register217 const int64_t VLENB = *VLEN / 8;218 assert(Offset.getScalable() % RISCV::RVVBytesPerBlock == 0 &&219 "Reserve the stack by the multiple of one vector size.");220 const int64_t NumOfVReg = Offset.getScalable() / 8;221 const int64_t FixedOffset = NumOfVReg * VLENB;222 if (!isInt<32>(FixedOffset)) {223 reportFatalUsageError(224 "Frame size outside of the signed 32-bit range not supported");225 }226 Offset = StackOffset::getFixed(FixedOffset + Offset.getFixed());227 }228 }229 230 bool KillSrcReg = false;231 232 if (Offset.getScalable()) {233 unsigned ScalableAdjOpc = RISCV::ADD;234 int64_t ScalableValue = Offset.getScalable();235 if (ScalableValue < 0) {236 ScalableValue = -ScalableValue;237 ScalableAdjOpc = RISCV::SUB;238 }239 // Get vlenb and multiply vlen with the number of vector registers.240 Register ScratchReg = DestReg;241 if (DestReg == SrcReg)242 ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);243 244 assert(ScalableValue > 0 && "There is no need to get VLEN scaled value.");245 assert(ScalableValue % RISCV::RVVBytesPerBlock == 0 &&246 "Reserve the stack by the multiple of one vector size.");247 assert(isInt<32>(ScalableValue / RISCV::RVVBytesPerBlock) &&248 "Expect the number of vector registers within 32-bits.");249 uint32_t NumOfVReg = ScalableValue / RISCV::RVVBytesPerBlock;250 // Only use vsetvli rather than vlenb if adjusting in the prologue or251 // epilogue, otherwise it may disturb the VTYPE and VL status.252 bool IsPrologueOrEpilogue =253 Flag == MachineInstr::FrameSetup || Flag == MachineInstr::FrameDestroy;254 bool UseVsetvliRatherThanVlenb =255 IsPrologueOrEpilogue && ST.preferVsetvliOverReadVLENB();256 if (UseVsetvliRatherThanVlenb && (NumOfVReg == 1 || NumOfVReg == 2 ||257 NumOfVReg == 4 || NumOfVReg == 8)) {258 BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENBViaVSETVLIX0),259 ScratchReg)260 .addImm(NumOfVReg)261 .setMIFlag(Flag);262 BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), DestReg)263 .addReg(SrcReg)264 .addReg(ScratchReg, RegState::Kill)265 .setMIFlag(Flag);266 } else {267 if (UseVsetvliRatherThanVlenb)268 BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENBViaVSETVLIX0),269 ScratchReg)270 .addImm(1)271 .setMIFlag(Flag);272 else273 BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), ScratchReg)274 .setMIFlag(Flag);275 276 if (ScalableAdjOpc == RISCV::ADD && ST.hasStdExtZba() &&277 (NumOfVReg == 2 || NumOfVReg == 4 || NumOfVReg == 8)) {278 unsigned Opc = NumOfVReg == 2279 ? RISCV::SH1ADD280 : (NumOfVReg == 4 ? RISCV::SH2ADD : RISCV::SH3ADD);281 BuildMI(MBB, II, DL, TII->get(Opc), DestReg)282 .addReg(ScratchReg, RegState::Kill)283 .addReg(SrcReg)284 .setMIFlag(Flag);285 } else {286 TII->mulImm(MF, MBB, II, DL, ScratchReg, NumOfVReg, Flag);287 BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), DestReg)288 .addReg(SrcReg)289 .addReg(ScratchReg, RegState::Kill)290 .setMIFlag(Flag);291 }292 }293 SrcReg = DestReg;294 KillSrcReg = true;295 }296 297 int64_t Val = Offset.getFixed();298 if (DestReg == SrcReg && Val == 0)299 return;300 301 const uint64_t Align = RequiredAlign.valueOrOne().value();302 303 if (isInt<12>(Val)) {304 BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)305 .addReg(SrcReg, getKillRegState(KillSrcReg))306 .addImm(Val)307 .setMIFlag(Flag);308 return;309 }310 311 // Use the QC_E_ADDI instruction from the Xqcilia extension that can take a312 // signed 26-bit immediate.313 if (ST.hasVendorXqcilia() && isInt<26>(Val)) {314 // The one case where using this instruction is sub-optimal is if Val can be315 // materialized with a single compressible LUI and following add/sub is also316 // compressible. Avoid doing this if that is the case.317 int Hi20 = (Val & 0xFFFFF000) >> 12;318 bool IsCompressLUI =319 ((Val & 0xFFF) == 0) && (Hi20 != 0) &&320 (isUInt<5>(Hi20) || (Hi20 >= 0xfffe0 && Hi20 <= 0xfffff));321 bool IsCompressAddSub =322 (SrcReg == DestReg) &&323 ((Val > 0 && RISCV::GPRNoX0RegClass.contains(SrcReg)) ||324 (Val < 0 && RISCV::GPRCRegClass.contains(SrcReg)));325 326 if (!(IsCompressLUI && IsCompressAddSub)) {327 BuildMI(MBB, II, DL, TII->get(RISCV::QC_E_ADDI), DestReg)328 .addReg(SrcReg, getKillRegState(KillSrcReg))329 .addImm(Val)330 .setMIFlag(Flag);331 return;332 }333 }334 335 // Try to split the offset across two ADDIs. We need to keep the intermediate336 // result aligned after each ADDI. We need to determine the maximum value we337 // can put in each ADDI. In the negative direction, we can use -2048 which is338 // always sufficiently aligned. In the positive direction, we need to find the339 // largest 12-bit immediate that is aligned. Exclude -4096 since it can be340 // created with LUI.341 assert(Align < 2048 && "Required alignment too large");342 int64_t MaxPosAdjStep = 2048 - Align;343 if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) {344 int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep;345 Val -= FirstAdj;346 BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)347 .addReg(SrcReg, getKillRegState(KillSrcReg))348 .addImm(FirstAdj)349 .setMIFlag(Flag);350 BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)351 .addReg(DestReg, RegState::Kill)352 .addImm(Val)353 .setMIFlag(Flag);354 return;355 }356 357 // Use shNadd if doing so lets us materialize a 12 bit immediate with a single358 // instruction. This saves 1 instruction over the full lui/addi+add fallback359 // path. We avoid anything which can be done with a single lui as it might360 // be compressible. Note that the sh1add case is fully covered by the 2x addi361 // case just above and is thus omitted.362 if (ST.hasStdExtZba() && (Val & 0xFFF) != 0) {363 unsigned Opc = 0;364 if (isShiftedInt<12, 3>(Val)) {365 Opc = RISCV::SH3ADD;366 Val = Val >> 3;367 } else if (isShiftedInt<12, 2>(Val)) {368 Opc = RISCV::SH2ADD;369 Val = Val >> 2;370 }371 if (Opc) {372 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);373 TII->movImm(MBB, II, DL, ScratchReg, Val, Flag);374 BuildMI(MBB, II, DL, TII->get(Opc), DestReg)375 .addReg(ScratchReg, RegState::Kill)376 .addReg(SrcReg, getKillRegState(KillSrcReg))377 .setMIFlag(Flag);378 return;379 }380 }381 382 unsigned Opc = RISCV::ADD;383 if (Val < 0) {384 Val = -Val;385 Opc = RISCV::SUB;386 }387 388 Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);389 TII->movImm(MBB, II, DL, ScratchReg, Val, Flag);390 BuildMI(MBB, II, DL, TII->get(Opc), DestReg)391 .addReg(SrcReg, getKillRegState(KillSrcReg))392 .addReg(ScratchReg, RegState::Kill)393 .setMIFlag(Flag);394}395 396static std::tuple<RISCVVType::VLMUL, const TargetRegisterClass &, unsigned>397getSpillReloadInfo(unsigned NumRemaining, uint16_t RegEncoding, bool IsSpill) {398 if (NumRemaining >= 8 && RegEncoding % 8 == 0)399 return {RISCVVType::LMUL_8, RISCV::VRM8RegClass,400 IsSpill ? RISCV::VS8R_V : RISCV::VL8RE8_V};401 if (NumRemaining >= 4 && RegEncoding % 4 == 0)402 return {RISCVVType::LMUL_4, RISCV::VRM4RegClass,403 IsSpill ? RISCV::VS4R_V : RISCV::VL4RE8_V};404 if (NumRemaining >= 2 && RegEncoding % 2 == 0)405 return {RISCVVType::LMUL_2, RISCV::VRM2RegClass,406 IsSpill ? RISCV::VS2R_V : RISCV::VL2RE8_V};407 return {RISCVVType::LMUL_1, RISCV::VRRegClass,408 IsSpill ? RISCV::VS1R_V : RISCV::VL1RE8_V};409}410 411// Split a VSPILLx_Mx/VSPILLx_Mx pseudo into multiple whole register stores412// separated by LMUL*VLENB bytes.413void RISCVRegisterInfo::lowerSegmentSpillReload(MachineBasicBlock::iterator II,414 bool IsSpill) const {415 DebugLoc DL = II->getDebugLoc();416 MachineBasicBlock &MBB = *II->getParent();417 MachineFunction &MF = *MBB.getParent();418 MachineRegisterInfo &MRI = MF.getRegInfo();419 const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>();420 const TargetInstrInfo *TII = STI.getInstrInfo();421 const TargetRegisterInfo *TRI = STI.getRegisterInfo();422 423 auto ZvlssegInfo = RISCV::isRVVSpillForZvlsseg(II->getOpcode());424 unsigned NF = ZvlssegInfo->first;425 unsigned LMUL = ZvlssegInfo->second;426 unsigned NumRegs = NF * LMUL;427 assert(NumRegs <= 8 && "Invalid NF/LMUL combinations.");428 429 Register Reg = II->getOperand(0).getReg();430 uint16_t RegEncoding = TRI->getEncodingValue(Reg);431 Register Base = II->getOperand(1).getReg();432 bool IsBaseKill = II->getOperand(1).isKill();433 Register NewBase = MRI.createVirtualRegister(&RISCV::GPRRegClass);434 435 auto *OldMMO = *(II->memoperands_begin());436 LocationSize OldLoc = OldMMO->getSize();437 assert(OldLoc.isPrecise() && OldLoc.getValue().isKnownMultipleOf(NF));438 TypeSize VRegSize = OldLoc.getValue().divideCoefficientBy(NumRegs);439 440 Register VLENB = 0;441 unsigned VLENBShift = 0;442 unsigned PrevHandledNum = 0;443 unsigned I = 0;444 while (I != NumRegs) {445 auto [LMulHandled, RegClass, Opcode] =446 getSpillReloadInfo(NumRegs - I, RegEncoding, IsSpill);447 auto [RegNumHandled, _] = RISCVVType::decodeVLMUL(LMulHandled);448 bool IsLast = I + RegNumHandled == NumRegs;449 if (PrevHandledNum) {450 Register Step;451 // Optimize for constant VLEN.452 if (auto VLEN = STI.getRealVLen()) {453 int64_t Offset = *VLEN / 8 * PrevHandledNum;454 Step = MRI.createVirtualRegister(&RISCV::GPRRegClass);455 STI.getInstrInfo()->movImm(MBB, II, DL, Step, Offset);456 } else {457 if (!VLENB) {458 VLENB = MRI.createVirtualRegister(&RISCV::GPRRegClass);459 BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VLENB);460 }461 uint32_t ShiftAmount = Log2_32(PrevHandledNum);462 // To avoid using an extra register, we shift the VLENB register and463 // remember how much it has been shifted. We can then use relative464 // shifts to adjust to the desired shift amount.465 if (VLENBShift > ShiftAmount) {466 BuildMI(MBB, II, DL, TII->get(RISCV::SRLI), VLENB)467 .addReg(VLENB, RegState::Kill)468 .addImm(VLENBShift - ShiftAmount);469 } else if (VLENBShift < ShiftAmount) {470 BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VLENB)471 .addReg(VLENB, RegState::Kill)472 .addImm(ShiftAmount - VLENBShift);473 }474 VLENBShift = ShiftAmount;475 Step = VLENB;476 }477 478 BuildMI(MBB, II, DL, TII->get(RISCV::ADD), NewBase)479 .addReg(Base, getKillRegState(I != 0 || IsBaseKill))480 .addReg(Step, getKillRegState(Step != VLENB || IsLast));481 Base = NewBase;482 }483 484 MCRegister ActualReg = findVRegWithEncoding(RegClass, RegEncoding);485 MachineInstrBuilder MIB =486 BuildMI(MBB, II, DL, TII->get(Opcode))487 .addReg(ActualReg, getDefRegState(!IsSpill))488 .addReg(Base, getKillRegState(IsLast))489 .addMemOperand(MF.getMachineMemOperand(OldMMO, OldMMO->getOffset(),490 VRegSize * RegNumHandled));491 492 // Adding implicit-use of super register to describe we are using part of493 // super register, that prevents machine verifier complaining when part of494 // subreg is undef, see comment in MachineVerifier::checkLiveness for more495 // detail.496 if (IsSpill)497 MIB.addReg(Reg, RegState::Implicit);498 499 PrevHandledNum = RegNumHandled;500 RegEncoding += RegNumHandled;501 I += RegNumHandled;502 }503 II->eraseFromParent();504}505 506bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,507 int SPAdj, unsigned FIOperandNum,508 RegScavenger *RS) const {509 assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");510 511 MachineInstr &MI = *II;512 MachineFunction &MF = *MI.getParent()->getParent();513 MachineRegisterInfo &MRI = MF.getRegInfo();514 DebugLoc DL = MI.getDebugLoc();515 516 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();517 Register FrameReg;518 StackOffset Offset =519 getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);520 bool IsRVVSpill = RISCV::isRVVSpill(MI);521 if (!IsRVVSpill)522 Offset += StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm());523 524 if (!isInt<32>(Offset.getFixed())) {525 reportFatalUsageError(526 "Frame offsets outside of the signed 32-bit range not supported");527 }528 529 if (!IsRVVSpill) {530 int64_t Val = Offset.getFixed();531 int64_t Lo12 = SignExtend64<12>(Val);532 unsigned Opc = MI.getOpcode();533 534 if (Opc == RISCV::ADDI && !isInt<12>(Val)) {535 // We chose to emit the canonical immediate sequence rather than folding536 // the offset into the using add under the theory that doing so doesn't537 // save dynamic instruction count and some target may fuse the canonical538 // 32 bit immediate sequence. We still need to clear the portion of the539 // offset encoded in the immediate.540 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);541 } else if ((Opc == RISCV::PREFETCH_I || Opc == RISCV::PREFETCH_R ||542 Opc == RISCV::PREFETCH_W) &&543 (Lo12 & 0b11111) != 0) {544 // Prefetch instructions require the offset to be 32 byte aligned.545 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);546 } else if (Opc == RISCV::MIPS_PREF && !isUInt<9>(Val)) {547 // MIPS Prefetch instructions require the offset to be 9 bits encoded.548 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);549 } else if ((Opc == RISCV::PseudoRV32ZdinxLD ||550 Opc == RISCV::PseudoRV32ZdinxSD) &&551 Lo12 >= 2044) {552 // This instruction will be split into 2 instructions. The second553 // instruction will add 4 to the immediate. If that would overflow 12554 // bits, we can't fold the offset.555 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);556 } else {557 // We can encode an add with 12 bit signed immediate in the immediate558 // operand of our user instruction. As a result, the remaining559 // offset can by construction, at worst, a LUI and a ADD.560 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);561 Offset = StackOffset::get((uint64_t)Val - (uint64_t)Lo12,562 Offset.getScalable());563 }564 }565 566 if (Offset.getScalable() || Offset.getFixed()) {567 Register DestReg;568 if (MI.getOpcode() == RISCV::ADDI)569 DestReg = MI.getOperand(0).getReg();570 else571 DestReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);572 adjustReg(*II->getParent(), II, DL, DestReg, FrameReg, Offset,573 MachineInstr::NoFlags, std::nullopt);574 MI.getOperand(FIOperandNum).ChangeToRegister(DestReg, /*IsDef*/false,575 /*IsImp*/false,576 /*IsKill*/true);577 } else {578 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*IsDef*/false,579 /*IsImp*/false,580 /*IsKill*/false);581 }582 583 // If after materializing the adjustment, we have a pointless ADDI, remove it584 if (MI.getOpcode() == RISCV::ADDI &&585 MI.getOperand(0).getReg() == MI.getOperand(1).getReg() &&586 MI.getOperand(2).getImm() == 0) {587 MI.eraseFromParent();588 return true;589 }590 591 // Handle spill/fill of synthetic register classes for segment operations to592 // ensure correctness in the edge case one gets spilled.593 switch (MI.getOpcode()) {594 case RISCV::PseudoVSPILL2_M1:595 case RISCV::PseudoVSPILL2_M2:596 case RISCV::PseudoVSPILL2_M4:597 case RISCV::PseudoVSPILL3_M1:598 case RISCV::PseudoVSPILL3_M2:599 case RISCV::PseudoVSPILL4_M1:600 case RISCV::PseudoVSPILL4_M2:601 case RISCV::PseudoVSPILL5_M1:602 case RISCV::PseudoVSPILL6_M1:603 case RISCV::PseudoVSPILL7_M1:604 case RISCV::PseudoVSPILL8_M1:605 lowerSegmentSpillReload(II, /*IsSpill=*/true);606 return true;607 case RISCV::PseudoVRELOAD2_M1:608 case RISCV::PseudoVRELOAD2_M2:609 case RISCV::PseudoVRELOAD2_M4:610 case RISCV::PseudoVRELOAD3_M1:611 case RISCV::PseudoVRELOAD3_M2:612 case RISCV::PseudoVRELOAD4_M1:613 case RISCV::PseudoVRELOAD4_M2:614 case RISCV::PseudoVRELOAD5_M1:615 case RISCV::PseudoVRELOAD6_M1:616 case RISCV::PseudoVRELOAD7_M1:617 case RISCV::PseudoVRELOAD8_M1:618 lowerSegmentSpillReload(II, /*IsSpill=*/false);619 return true;620 }621 622 return false;623}624 625bool RISCVRegisterInfo::requiresVirtualBaseRegisters(626 const MachineFunction &MF) const {627 return true;628}629 630// Returns true if the instruction's frame index reference would be better631// served by a base register other than FP or SP.632// Used by LocalStackSlotAllocation pass to determine which frame index633// references it should create new base registers for.634bool RISCVRegisterInfo::needsFrameBaseReg(MachineInstr *MI,635 int64_t Offset) const {636 unsigned FIOperandNum = 0;637 for (; !MI->getOperand(FIOperandNum).isFI(); FIOperandNum++)638 assert(FIOperandNum < MI->getNumOperands() &&639 "Instr doesn't have FrameIndex operand");640 641 // For RISC-V, The machine instructions that include a FrameIndex operand642 // are load/store, ADDI instructions.643 unsigned MIFrm = RISCVII::getFormat(MI->getDesc().TSFlags);644 if (MIFrm != RISCVII::InstFormatI && MIFrm != RISCVII::InstFormatS)645 return false;646 // We only generate virtual base registers for loads and stores, so647 // return false for everything else.648 if (!MI->mayLoad() && !MI->mayStore())649 return false;650 651 const MachineFunction &MF = *MI->getMF();652 const MachineFrameInfo &MFI = MF.getFrameInfo();653 const RISCVFrameLowering *TFI = getFrameLowering(MF);654 const MachineRegisterInfo &MRI = MF.getRegInfo();655 656 if (TFI->hasFP(MF) && !shouldRealignStack(MF)) {657 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();658 // Estimate the stack size used to store callee saved registers(659 // excludes reserved registers).660 unsigned CalleeSavedSize = 0;661 for (const MCPhysReg *R = MRI.getCalleeSavedRegs(); MCPhysReg Reg = *R;662 ++R) {663 if (Subtarget.isRegisterReservedByUser(Reg))664 continue;665 666 if (RISCV::GPRRegClass.contains(Reg))667 CalleeSavedSize += getSpillSize(RISCV::GPRRegClass);668 else if (RISCV::FPR64RegClass.contains(Reg))669 CalleeSavedSize += getSpillSize(RISCV::FPR64RegClass);670 else if (RISCV::FPR32RegClass.contains(Reg))671 CalleeSavedSize += getSpillSize(RISCV::FPR32RegClass);672 // Ignore vector registers.673 }674 675 int64_t MaxFPOffset = Offset - CalleeSavedSize;676 return !isFrameOffsetLegal(MI, RISCV::X8, MaxFPOffset);677 }678 679 // Assume 128 bytes spill slots size to estimate the maximum possible680 // offset relative to the stack pointer.681 // FIXME: The 128 is copied from ARM. We should run some statistics and pick a682 // real one for RISC-V.683 int64_t MaxSPOffset = Offset + 128;684 MaxSPOffset += MFI.getLocalFrameSize();685 return !isFrameOffsetLegal(MI, RISCV::X2, MaxSPOffset);686}687 688// Determine whether a given base register plus offset immediate is689// encodable to resolve a frame index.690bool RISCVRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,691 Register BaseReg,692 int64_t Offset) const {693 unsigned FIOperandNum = 0;694 while (!MI->getOperand(FIOperandNum).isFI()) {695 FIOperandNum++;696 assert(FIOperandNum < MI->getNumOperands() &&697 "Instr does not have a FrameIndex operand!");698 }699 700 Offset += getFrameIndexInstrOffset(MI, FIOperandNum);701 return isInt<12>(Offset);702}703 704// Insert defining instruction(s) for a pointer to FrameIdx before705// insertion point I.706// Return materialized frame pointer.707Register RISCVRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,708 int FrameIdx,709 int64_t Offset) const {710 MachineBasicBlock::iterator MBBI = MBB->begin();711 DebugLoc DL;712 if (MBBI != MBB->end())713 DL = MBBI->getDebugLoc();714 MachineFunction *MF = MBB->getParent();715 MachineRegisterInfo &MFI = MF->getRegInfo();716 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();717 718 Register BaseReg = MFI.createVirtualRegister(&RISCV::GPRRegClass);719 BuildMI(*MBB, MBBI, DL, TII->get(RISCV::ADDI), BaseReg)720 .addFrameIndex(FrameIdx)721 .addImm(Offset);722 return BaseReg;723}724 725// Resolve a frame index operand of an instruction to reference the726// indicated base register plus offset instead.727void RISCVRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg,728 int64_t Offset) const {729 unsigned FIOperandNum = 0;730 while (!MI.getOperand(FIOperandNum).isFI()) {731 FIOperandNum++;732 assert(FIOperandNum < MI.getNumOperands() &&733 "Instr does not have a FrameIndex operand!");734 }735 736 Offset += getFrameIndexInstrOffset(&MI, FIOperandNum);737 // FrameIndex Operands are always represented as a738 // register followed by an immediate.739 MI.getOperand(FIOperandNum).ChangeToRegister(BaseReg, false);740 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);741}742 743// Get the offset from the referenced frame index in the instruction,744// if there is one.745int64_t RISCVRegisterInfo::getFrameIndexInstrOffset(const MachineInstr *MI,746 int Idx) const {747 assert((RISCVII::getFormat(MI->getDesc().TSFlags) == RISCVII::InstFormatI ||748 RISCVII::getFormat(MI->getDesc().TSFlags) == RISCVII::InstFormatS) &&749 "The MI must be I or S format.");750 assert(MI->getOperand(Idx).isFI() && "The Idx'th operand of MI is not a "751 "FrameIndex operand");752 return MI->getOperand(Idx + 1).getImm();753}754 755Register RISCVRegisterInfo::getFrameRegister(const MachineFunction &MF) const {756 const TargetFrameLowering *TFI = getFrameLowering(MF);757 return TFI->hasFP(MF) ? RISCV::X8 : RISCV::X2;758}759 760StringRef RISCVRegisterInfo::getRegAsmName(MCRegister Reg) const {761 if (Reg == RISCV::SF_VCIX_STATE)762 return "sf.vcix_state";763 return TargetRegisterInfo::getRegAsmName(Reg);764}765 766const uint32_t *767RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF,768 CallingConv::ID CC) const {769 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();770 771 if (CC == CallingConv::GHC)772 return CSR_NoRegs_RegMask;773 RISCVABI::ABI ABI = Subtarget.getTargetABI();774 if (CC == CallingConv::PreserveMost) {775 if (ABI == RISCVABI::ABI_ILP32E || ABI == RISCVABI::ABI_LP64E)776 return CSR_RT_MostRegs_RVE_RegMask;777 return CSR_RT_MostRegs_RegMask;778 }779 switch (ABI) {780 default:781 llvm_unreachable("Unrecognized ABI");782 case RISCVABI::ABI_ILP32E:783 case RISCVABI::ABI_LP64E:784 return CSR_ILP32E_LP64E_RegMask;785 case RISCVABI::ABI_ILP32:786 case RISCVABI::ABI_LP64:787 if (CC == CallingConv::RISCV_VectorCall)788 return CSR_ILP32_LP64_V_RegMask;789 return CSR_ILP32_LP64_RegMask;790 case RISCVABI::ABI_ILP32F:791 case RISCVABI::ABI_LP64F:792 if (CC == CallingConv::RISCV_VectorCall)793 return CSR_ILP32F_LP64F_V_RegMask;794 return CSR_ILP32F_LP64F_RegMask;795 case RISCVABI::ABI_ILP32D:796 case RISCVABI::ABI_LP64D:797 if (CC == CallingConv::RISCV_VectorCall)798 return CSR_ILP32D_LP64D_V_RegMask;799 return CSR_ILP32D_LP64D_RegMask;800 }801}802 803const TargetRegisterClass *804RISCVRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,805 const MachineFunction &) const {806 if (RC == &RISCV::VMV0RegClass)807 return &RISCV::VRRegClass;808 if (RC == &RISCV::VRNoV0RegClass)809 return &RISCV::VRRegClass;810 if (RC == &RISCV::VRM2NoV0RegClass)811 return &RISCV::VRM2RegClass;812 if (RC == &RISCV::VRM4NoV0RegClass)813 return &RISCV::VRM4RegClass;814 if (RC == &RISCV::VRM8NoV0RegClass)815 return &RISCV::VRM8RegClass;816 return RC;817}818 819void RISCVRegisterInfo::getOffsetOpcodes(const StackOffset &Offset,820 SmallVectorImpl<uint64_t> &Ops) const {821 // VLENB is the length of a vector register in bytes. We use <vscale x 8 x i8>822 // to represent one vector register. The dwarf offset is823 // VLENB * scalable_offset / 8.824 assert(Offset.getScalable() % 8 == 0 && "Invalid frame offset");825 826 // Add fixed-sized offset using existing DIExpression interface.827 DIExpression::appendOffset(Ops, Offset.getFixed());828 829 unsigned VLENB = getDwarfRegNum(RISCV::VLENB, true);830 int64_t VLENBSized = Offset.getScalable() / 8;831 if (VLENBSized > 0) {832 Ops.push_back(dwarf::DW_OP_constu);833 Ops.push_back(VLENBSized);834 Ops.append({dwarf::DW_OP_bregx, VLENB, 0ULL});835 Ops.push_back(dwarf::DW_OP_mul);836 Ops.push_back(dwarf::DW_OP_plus);837 } else if (VLENBSized < 0) {838 Ops.push_back(dwarf::DW_OP_constu);839 Ops.push_back(-VLENBSized);840 Ops.append({dwarf::DW_OP_bregx, VLENB, 0ULL});841 Ops.push_back(dwarf::DW_OP_mul);842 Ops.push_back(dwarf::DW_OP_minus);843 }844}845 846unsigned847RISCVRegisterInfo::getRegisterCostTableIndex(const MachineFunction &MF) const {848 return MF.getSubtarget<RISCVSubtarget>().hasStdExtZca() && !DisableCostPerUse849 ? 1850 : 0;851}852 853float RISCVRegisterInfo::getSpillWeightScaleFactor(854 const TargetRegisterClass *RC) const {855 return getRegClassWeight(RC).RegWeight;856}857 858// Add two address hints to improve chances of being able to use a compressed859// instruction.860bool RISCVRegisterInfo::getRegAllocationHints(861 Register VirtReg, ArrayRef<MCPhysReg> Order,862 SmallVectorImpl<MCPhysReg> &Hints, const MachineFunction &MF,863 const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const {864 const MachineRegisterInfo *MRI = &MF.getRegInfo();865 auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();866 867 // Handle RegPairEven/RegPairOdd hints for Zilsd register pairs868 std::pair<unsigned, Register> Hint = MRI->getRegAllocationHint(VirtReg);869 unsigned HintType = Hint.first;870 Register Partner = Hint.second;871 872 MCRegister TargetReg;873 if (HintType == RISCVRI::RegPairEven || HintType == RISCVRI::RegPairOdd) {874 // Check if we want the even or odd register of a consecutive pair875 bool WantOdd = (HintType == RISCVRI::RegPairOdd);876 877 // First priority: Check if partner is already allocated878 if (Partner.isVirtual() && VRM && VRM->hasPhys(Partner)) {879 MCRegister PartnerPhys = VRM->getPhys(Partner);880 // Calculate the exact register we need for consecutive pairing881 TargetReg = PartnerPhys.id() + (WantOdd ? 1 : -1);882 883 // Verify it's valid and available884 if (RISCV::GPRRegClass.contains(TargetReg) &&885 is_contained(Order, TargetReg))886 Hints.push_back(TargetReg.id());887 }888 889 // Second priority: Try to find consecutive register pairs in the allocation890 // order891 for (MCPhysReg PhysReg : Order) {892 // Don't add the hint if we already added above.893 if (TargetReg == PhysReg)894 continue;895 896 unsigned RegNum = getEncodingValue(PhysReg);897 // Check if this register matches the even/odd requirement898 bool IsOdd = (RegNum % 2 != 0);899 900 // Don't provide hints that are paired to a reserved register.901 MCRegister Paired = PhysReg + (IsOdd ? -1 : 1);902 if (WantOdd == IsOdd && !MRI->isReserved(Paired))903 Hints.push_back(PhysReg);904 }905 }906 907 bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(908 VirtReg, Order, Hints, MF, VRM, Matrix);909 910 if (!VRM || DisableRegAllocHints)911 return BaseImplRetVal;912 913 // Add any two address hints after any copy hints.914 SmallSet<Register, 4> TwoAddrHints;915 916 auto tryAddHint = [&](const MachineOperand &VRRegMO, const MachineOperand &MO,917 bool NeedGPRC) -> void {918 Register Reg = MO.getReg();919 Register PhysReg = Reg.isPhysical() ? Reg : Register(VRM->getPhys(Reg));920 // TODO: Support GPRPair subregisters? Need to be careful with even/odd921 // registers. If the virtual register is an odd register of a pair and the922 // physical register is even (or vice versa), we should not add the hint.923 if (PhysReg && (!NeedGPRC || RISCV::GPRCRegClass.contains(PhysReg)) &&924 !MO.getSubReg() && !VRRegMO.getSubReg()) {925 if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))926 TwoAddrHints.insert(PhysReg);927 }928 };929 930 // This is all of the compressible binary instructions. If an instruction931 // needs GPRC register class operands \p NeedGPRC will be set to true.932 auto isCompressible = [&Subtarget](const MachineInstr &MI, bool &NeedGPRC) {933 NeedGPRC = false;934 switch (MI.getOpcode()) {935 default:936 return false;937 case RISCV::AND:938 case RISCV::OR:939 case RISCV::XOR:940 case RISCV::SUB:941 case RISCV::ADDW:942 case RISCV::SUBW:943 NeedGPRC = true;944 return true;945 case RISCV::ANDI: {946 NeedGPRC = true;947 if (!MI.getOperand(2).isImm())948 return false;949 int64_t Imm = MI.getOperand(2).getImm();950 if (isInt<6>(Imm))951 return true;952 // c.zext.b953 return Subtarget.hasStdExtZcb() && Imm == 255;954 }955 case RISCV::SRAI:956 case RISCV::SRLI:957 NeedGPRC = true;958 return true;959 case RISCV::ADD:960 case RISCV::SLLI:961 return true;962 case RISCV::ADDI:963 case RISCV::ADDIW:964 return MI.getOperand(2).isImm() && isInt<6>(MI.getOperand(2).getImm());965 case RISCV::MUL:966 case RISCV::SEXT_B:967 case RISCV::SEXT_H:968 case RISCV::ZEXT_H_RV32:969 case RISCV::ZEXT_H_RV64:970 // c.mul, c.sext.b, c.sext.h, c.zext.h971 NeedGPRC = true;972 return Subtarget.hasStdExtZcb();973 case RISCV::ADD_UW:974 // c.zext.w975 NeedGPRC = true;976 return Subtarget.hasStdExtZcb() && MI.getOperand(2).isReg() &&977 MI.getOperand(2).getReg() == RISCV::X0;978 case RISCV::XORI:979 // c.not980 NeedGPRC = true;981 return Subtarget.hasStdExtZcb() && MI.getOperand(2).isImm() &&982 MI.getOperand(2).getImm() == -1;983 }984 };985 986 // Returns true if this operand is compressible. For non-registers it always987 // returns true. Immediate range was already checked in isCompressible.988 // For registers, it checks if the register is a GPRC register. reg-reg989 // instructions that require GPRC need all register operands to be GPRC.990 auto isCompressibleOpnd = [&](const MachineOperand &MO) {991 if (!MO.isReg())992 return true;993 Register Reg = MO.getReg();994 Register PhysReg = Reg.isPhysical() ? Reg : Register(VRM->getPhys(Reg));995 return PhysReg && RISCV::GPRCRegClass.contains(PhysReg);996 };997 998 for (auto &MO : MRI->reg_nodbg_operands(VirtReg)) {999 const MachineInstr &MI = *MO.getParent();1000 unsigned OpIdx = MO.getOperandNo();1001 bool NeedGPRC;1002 if (isCompressible(MI, NeedGPRC)) {1003 if (OpIdx == 0 && MI.getOperand(1).isReg()) {1004 if (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||1005 MI.getOpcode() == RISCV::ADD_UW ||1006 isCompressibleOpnd(MI.getOperand(2)))1007 tryAddHint(MO, MI.getOperand(1), NeedGPRC);1008 if (MI.isCommutable() && MI.getOperand(2).isReg() &&1009 (!NeedGPRC || isCompressibleOpnd(MI.getOperand(1))))1010 tryAddHint(MO, MI.getOperand(2), NeedGPRC);1011 } else if (OpIdx == 1 && (!NeedGPRC || MI.getNumExplicitOperands() < 3 ||1012 isCompressibleOpnd(MI.getOperand(2)))) {1013 tryAddHint(MO, MI.getOperand(0), NeedGPRC);1014 } else if (MI.isCommutable() && OpIdx == 2 &&1015 (!NeedGPRC || isCompressibleOpnd(MI.getOperand(1)))) {1016 tryAddHint(MO, MI.getOperand(0), NeedGPRC);1017 }1018 }1019 1020 // Add a hint if it would allow auipc/lui+addi(w) fusion. We do this even1021 // without the fusions explicitly enabled as the impact is rarely negative1022 // and some cores do implement this fusion.1023 if ((MI.getOpcode() == RISCV::ADDIW || MI.getOpcode() == RISCV::ADDI) &&1024 MI.getOperand(1).isReg()) {1025 const MachineBasicBlock &MBB = *MI.getParent();1026 MachineBasicBlock::const_iterator I = MI.getIterator();1027 // Is the previous instruction a LUI or AUIPC that can be fused?1028 if (I != MBB.begin()) {1029 I = skipDebugInstructionsBackward(std::prev(I), MBB.begin());1030 if ((I->getOpcode() == RISCV::LUI || I->getOpcode() == RISCV::AUIPC) &&1031 I->getOperand(0).getReg() == MI.getOperand(1).getReg()) {1032 if (OpIdx == 0)1033 tryAddHint(MO, MI.getOperand(1), /*NeedGPRC=*/false);1034 else1035 tryAddHint(MO, MI.getOperand(0), /*NeedGPRC=*/false);1036 }1037 }1038 }1039 }1040 1041 for (MCPhysReg OrderReg : Order)1042 if (TwoAddrHints.count(OrderReg))1043 Hints.push_back(OrderReg);1044 1045 return BaseImplRetVal;1046}1047 1048void RISCVRegisterInfo::updateRegAllocHint(Register Reg, Register NewReg,1049 MachineFunction &MF) const {1050 MachineRegisterInfo *MRI = &MF.getRegInfo();1051 std::pair<unsigned, Register> Hint = MRI->getRegAllocationHint(Reg);1052 1053 // Handle RegPairEven/RegPairOdd hints for Zilsd register pairs1054 if ((Hint.first == RISCVRI::RegPairOdd ||1055 Hint.first == RISCVRI::RegPairEven) &&1056 Hint.second.isVirtual()) {1057 // If 'Reg' is one of the even/odd register pair and it's now changed1058 // (e.g. coalesced) into a different register, the other register of the1059 // pair allocation hint must be updated to reflect the relationship change.1060 Register Partner = Hint.second;1061 std::pair<unsigned, Register> PartnerHint =1062 MRI->getRegAllocationHint(Partner);1063 1064 // Make sure partner still points to us1065 if (PartnerHint.second == Reg) {1066 // Update partner to point to NewReg instead of Reg1067 MRI->setRegAllocationHint(Partner, PartnerHint.first, NewReg);1068 1069 // If NewReg is virtual, set up the reciprocal hint1070 // NewReg takes over Reg's role, so it gets the SAME hint type as Reg1071 if (NewReg.isVirtual())1072 MRI->setRegAllocationHint(NewReg, Hint.first, Partner);1073 }1074 }1075}1076 1077Register1078RISCVRegisterInfo::findVRegWithEncoding(const TargetRegisterClass &RegClass,1079 uint16_t Encoding) const {1080 MCRegister Reg = RISCV::V0 + Encoding;1081 if (RISCVRI::getLMul(RegClass.TSFlags) == RISCVVType::LMUL_1)1082 return Reg;1083 return getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, &RegClass);1084}1085