28#define GET_REGINFO_TARGET_DESC
29#include "RISCVGenRegisterInfo.inc"
36 cl::desc(
"Disable two address hints for register "
39static_assert(RISCV::X1 == RISCV::X0 + 1,
"Register list not consecutive");
40static_assert(RISCV::X31 == RISCV::X0 + 31,
"Register list not consecutive");
41static_assert(RISCV::F1_H == RISCV::F0_H + 1,
"Register list not consecutive");
42static_assert(RISCV::F31_H == RISCV::F0_H + 31,
43 "Register list not consecutive");
44static_assert(RISCV::F1_F == RISCV::F0_F + 1,
"Register list not consecutive");
45static_assert(RISCV::F31_F == RISCV::F0_F + 31,
46 "Register list not consecutive");
47static_assert(RISCV::F1_D == RISCV::F0_D + 1,
"Register list not consecutive");
48static_assert(RISCV::F31_D == RISCV::F0_D + 31,
49 "Register list not consecutive");
50static_assert(RISCV::V1 == RISCV::V0 + 1,
"Register list not consecutive");
51static_assert(RISCV::V31 == RISCV::V0 + 31,
"Register list not consecutive");
61 return CSR_NoRegs_SaveList;
63 if (Subtarget.hasStdExtD())
64 return CSR_XLEN_F64_Interrupt_SaveList;
65 if (Subtarget.hasStdExtF())
66 return CSR_XLEN_F32_Interrupt_SaveList;
67 return CSR_Interrupt_SaveList;
70 switch (Subtarget.getTargetABI()) {
75 return CSR_ILP32_LP64_SaveList;
78 return CSR_ILP32F_LP64F_SaveList;
81 return CSR_ILP32D_LP64D_SaveList;
90 for (
size_t Reg = 0; Reg < getNumRegs(); Reg++) {
109 markSuperRegs(
Reserved, RISCV::DUMMY_REG_PAIR_WITH_X0);
113 markSuperRegs(
Reserved, RISCV::VTYPE);
114 markSuperRegs(
Reserved, RISCV::VXSAT);
115 markSuperRegs(
Reserved, RISCV::VXRM);
116 markSuperRegs(
Reserved, RISCV::VLENB);
119 markSuperRegs(
Reserved, RISCV::FRM);
120 markSuperRegs(
Reserved, RISCV::FFLAGS);
132 return CSR_NoRegs_RegMask;
155 int &FrameIdx)
const {
157 if (!RVFI->useSaveRestoreLibCalls(MF) && !RVFI->isPushable(MF))
165 FrameIdx = FII->second;
176 if (DestReg == SrcReg && !
Offset.getFixed() && !
Offset.getScalable())
184 bool KillSrcReg =
false;
186 if (
Offset.getScalable()) {
187 unsigned ScalableAdjOpc = RISCV::ADD;
188 int64_t ScalableValue =
Offset.getScalable();
189 if (ScalableValue < 0) {
190 ScalableValue = -ScalableValue;
191 ScalableAdjOpc = RISCV::SUB;
195 if (DestReg == SrcReg)
196 ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
197 TII->getVLENFactoredAmount(MF,
MBB, II,
DL, ScratchReg, ScalableValue, Flag);
205 int64_t Val =
Offset.getFixed();
206 if (DestReg == SrcReg && Val == 0)
211 if (isInt<12>(Val)) {
225 assert(
Align < 2048 &&
"Required alignment too large");
226 int64_t MaxPosAdjStep = 2048 -
Align;
227 if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) {
228 int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep;
241 unsigned Opc = RISCV::ADD;
247 Register ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
248 TII->movImm(
MBB, II,
DL, ScratchReg, Val, Flag);
266 unsigned NF = ZvlssegInfo->first;
267 unsigned LMUL = ZvlssegInfo->second;
268 assert(NF * LMUL <= 8 &&
"Invalid NF/LMUL combinations.");
269 unsigned Opcode, SubRegIdx;
274 Opcode = RISCV::VS1R_V;
275 SubRegIdx = RISCV::sub_vrm1_0;
278 Opcode = RISCV::VS2R_V;
279 SubRegIdx = RISCV::sub_vrm2_0;
282 Opcode = RISCV::VS4R_V;
283 SubRegIdx = RISCV::sub_vrm4_0;
286 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
287 "Unexpected subreg numbering");
288 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
289 "Unexpected subreg numbering");
290 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
291 "Unexpected subreg numbering");
293 Register VL =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
296 if (ShiftAmount != 0)
301 Register SrcReg = II->getOperand(0).getReg();
303 bool IsBaseKill = II->getOperand(1).isKill();
304 Register NewBase =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
305 for (
unsigned I = 0;
I < NF; ++
I) {
311 .
addReg(
TRI->getSubReg(SrcReg, SubRegIdx +
I))
321 II->eraseFromParent();
335 unsigned NF = ZvlssegInfo->first;
336 unsigned LMUL = ZvlssegInfo->second;
337 assert(NF * LMUL <= 8 &&
"Invalid NF/LMUL combinations.");
338 unsigned Opcode, SubRegIdx;
343 Opcode = RISCV::VL1RE8_V;
344 SubRegIdx = RISCV::sub_vrm1_0;
347 Opcode = RISCV::VL2RE8_V;
348 SubRegIdx = RISCV::sub_vrm2_0;
351 Opcode = RISCV::VL4RE8_V;
352 SubRegIdx = RISCV::sub_vrm4_0;
355 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
356 "Unexpected subreg numbering");
357 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
358 "Unexpected subreg numbering");
359 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
360 "Unexpected subreg numbering");
362 Register VL =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
365 if (ShiftAmount != 0)
370 Register DestReg = II->getOperand(0).getReg();
372 bool IsBaseKill = II->getOperand(1).isKill();
373 Register NewBase =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
374 for (
unsigned I = 0;
I < NF; ++
I) {
376 TRI->getSubReg(DestReg, SubRegIdx +
I))
385 II->eraseFromParent();
389 int SPAdj,
unsigned FIOperandNum,
391 assert(SPAdj == 0 &&
"Unexpected non-zero SPAdj value");
399 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
402 getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
407 if (
Offset.getScalable() &&
408 ST.getRealMinVLen() == ST.getRealMaxVLen()) {
411 int64_t FixedValue =
Offset.getFixed();
412 int64_t ScalableValue =
Offset.getScalable();
413 assert(ScalableValue % 8 == 0 &&
414 "Scalable offset is not a multiple of a single vector size.");
415 int64_t NumOfVReg = ScalableValue / 8;
416 int64_t VLENB = ST.getRealMinVLen() / 8;
420 if (!isInt<32>(
Offset.getFixed())) {
422 "Frame offsets outside of the signed 32-bit range not supported");
426 if (
MI.getOpcode() == RISCV::ADDI && !isInt<12>(
Offset.getFixed())) {
432 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
437 int64_t Val =
Offset.getFixed();
438 int64_t Lo12 = SignExtend64<12>(Val);
439 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
447 if (
MI.getOpcode() == RISCV::ADDI)
448 DestReg =
MI.getOperand(0).getReg();
450 DestReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
453 MI.getOperand(FIOperandNum).ChangeToRegister(DestReg,
false,
457 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg,
false,
463 if (
MI.getOpcode() == RISCV::ADDI &&
464 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg() &&
465 MI.getOperand(2).getImm() == 0) {
466 MI.eraseFromParent();
474 switch (
MI.getOpcode()) {
475 case RISCV::PseudoVSPILL2_M1:
476 case RISCV::PseudoVSPILL2_M2:
477 case RISCV::PseudoVSPILL2_M4:
478 case RISCV::PseudoVSPILL3_M1:
479 case RISCV::PseudoVSPILL3_M2:
480 case RISCV::PseudoVSPILL4_M1:
481 case RISCV::PseudoVSPILL4_M2:
482 case RISCV::PseudoVSPILL5_M1:
483 case RISCV::PseudoVSPILL6_M1:
484 case RISCV::PseudoVSPILL7_M1:
485 case RISCV::PseudoVSPILL8_M1:
488 case RISCV::PseudoVRELOAD2_M1:
489 case RISCV::PseudoVRELOAD2_M2:
490 case RISCV::PseudoVRELOAD2_M4:
491 case RISCV::PseudoVRELOAD3_M1:
492 case RISCV::PseudoVRELOAD3_M2:
493 case RISCV::PseudoVRELOAD4_M1:
494 case RISCV::PseudoVRELOAD4_M2:
495 case RISCV::PseudoVRELOAD5_M1:
496 case RISCV::PseudoVRELOAD6_M1:
497 case RISCV::PseudoVRELOAD7_M1:
498 case RISCV::PseudoVRELOAD8_M1:
517 unsigned FIOperandNum = 0;
518 for (; !
MI->getOperand(FIOperandNum).isFI(); FIOperandNum++)
519 assert(FIOperandNum < MI->getNumOperands() &&
520 "Instr doesn't have FrameIndex operand");
529 if (!
MI->mayLoad() && !
MI->mayStore())
536 unsigned CalleeSavedSize = 0;
543 if (!ReservedRegs.
test(Reg))
544 CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg));
547 int64_t MaxFPOffset =
Offset - CalleeSavedSize;
548 if (TFI->
hasFP(MF) && !shouldRealignStack(MF))
555 int64_t MaxSPOffset =
Offset + 128;
565 unsigned FIOperandNum = 0;
566 while (!
MI->getOperand(FIOperandNum).isFI()) {
568 assert(FIOperandNum < MI->getNumOperands() &&
569 "Instr does not have a FrameIndex operand!");
601 unsigned FIOperandNum = 0;
602 while (!
MI.getOperand(FIOperandNum).isFI()) {
604 assert(FIOperandNum <
MI.getNumOperands() &&
605 "Instr does not have a FrameIndex operand!");
611 MI.getOperand(FIOperandNum).ChangeToRegister(BaseReg,
false);
612 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(
Offset);
621 "The MI must be I or S format.");
622 assert(
MI->getOperand(
Idx).isFI() &&
"The Idx'th operand of MI is not a "
623 "FrameIndex operand");
624 return MI->getOperand(
Idx + 1).getImm();
629 return TFI->
hasFP(MF) ? RISCV::X8 : RISCV::X2;
638 return CSR_NoRegs_RegMask;
639 switch (Subtarget.getTargetABI()) {
644 return CSR_ILP32_LP64_RegMask;
647 return CSR_ILP32F_LP64F_RegMask;
650 return CSR_ILP32D_LP64D_RegMask;
657 if (RC == &RISCV::VMV0RegClass)
658 return &RISCV::VRRegClass;
667 assert(
Offset.getScalable() % 8 == 0 &&
"Invalid frame offset");
673 int64_t VLENBSized =
Offset.getScalable() / 8;
674 if (VLENBSized > 0) {
677 Ops.
append({dwarf::DW_OP_bregx, VLENB, 0ULL});
680 }
else if (VLENBSized < 0) {
683 Ops.
append({dwarf::DW_OP_bregx, VLENB, 0ULL});
703 VirtReg, Order, Hints, MF, VRM,
Matrix);
706 return BaseImplRetVal;
712 bool NeedGPRC) ->
void {
715 if (PhysReg && (!NeedGPRC || RISCV::GPRCRegClass.
contains(PhysReg))) {
716 assert(!MO.getSubReg() && !VRRegMO.
getSubReg() &&
"Unexpected subreg!");
718 TwoAddrHints.
insert(PhysReg);
724 auto isCompressible = [](
const MachineInstr &
MI,
bool &NeedGPRC) {
726 switch (
MI.getOpcode()) {
739 return MI.getOperand(2).isImm() && isInt<6>(
MI.getOperand(2).getImm());
749 return MI.getOperand(2).isImm() && isInt<6>(
MI.getOperand(2).getImm());
762 return PhysReg && RISCV::GPRCRegClass.contains(PhysReg);
765 for (
auto &MO :
MRI->reg_nodbg_operands(VirtReg)) {
767 unsigned OpIdx = MO.getOperandNo();
769 if (isCompressible(
MI, NeedGPRC)) {
770 if (OpIdx == 0 &&
MI.getOperand(1).isReg()) {
771 if (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(2)))
772 tryAddHint(MO,
MI.getOperand(1), NeedGPRC);
773 if (
MI.isCommutable() &&
MI.getOperand(2).isReg() &&
774 (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(1))))
775 tryAddHint(MO,
MI.getOperand(2), NeedGPRC);
776 }
else if (OpIdx == 1 &&
777 (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(2)))) {
778 tryAddHint(MO,
MI.getOperand(0), NeedGPRC);
779 }
else if (
MI.isCommutable() && OpIdx == 2 &&
780 (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(1)))) {
781 tryAddHint(MO,
MI.getOperand(0), NeedGPRC);
787 if (TwoAddrHints.
count(OrderReg))
790 return BaseImplRetVal;
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
static cl::opt< bool > DisableRegAllocHints("riscv-disable-regalloc-hints", cl::Hidden, cl::init(false), cl::desc("Disable two address hints for register " "allocation"))
static const std::pair< unsigned, int > FixedCSRFIMap[]
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Wrapper class representing physical registers. Should be passed by value.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasBP(const MachineFunction &MF) const
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool isRegisterReservedByUser(Register i) const
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
static StackOffset get(int64_t Fixed, int64_t Scalable)
Information about stack frame layout on the target.
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM=nullptr, const LiveRegMatrix *Matrix=nullptr) const
Get a list of 'hint' registers that the register allocator should try first when allocating a physica...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
static unsigned getFormat(uint64_t TSFlags)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
bool isRVVSpill(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getKillRegState(bool B)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const override
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
void lowerVRELOAD(MachineBasicBlock::iterator II) const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
RISCVRegisterInfo(unsigned HwMode)
void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const override
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
void lowerVSPILL(MachineBasicBlock::iterator II) const
Register getFrameRegister(const MachineFunction &MF) const override
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, Register SrcReg, StackOffset Offset, MachineInstr::MIFlag Flag, MaybeAlign RequiredAlign) const
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override
const uint32_t * getNoPreservedMask() const override
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg, int &FrameIdx) const override
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
unsigned getRegisterCostTableIndex(const MachineFunction &MF) const override
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override