27#define GET_REGINFO_TARGET_DESC
28#include "RISCVGenRegisterInfo.inc"
35 cl::desc(
"Disable two address hints for register "
38static_assert(RISCV::X1 == RISCV::X0 + 1,
"Register list not consecutive");
39static_assert(RISCV::X31 == RISCV::X0 + 31,
"Register list not consecutive");
40static_assert(RISCV::F1_H == RISCV::F0_H + 1,
"Register list not consecutive");
41static_assert(RISCV::F31_H == RISCV::F0_H + 31,
42 "Register list not consecutive");
43static_assert(RISCV::F1_F == RISCV::F0_F + 1,
"Register list not consecutive");
44static_assert(RISCV::F31_F == RISCV::F0_F + 31,
45 "Register list not consecutive");
46static_assert(RISCV::F1_D == RISCV::F0_D + 1,
"Register list not consecutive");
47static_assert(RISCV::F31_D == RISCV::F0_D + 31,
48 "Register list not consecutive");
49static_assert(RISCV::V1 == RISCV::V0 + 1,
"Register list not consecutive");
50static_assert(RISCV::V31 == RISCV::V0 + 31,
"Register list not consecutive");
60 return CSR_NoRegs_SaveList;
62 if (Subtarget.hasStdExtD())
63 return CSR_XLEN_F64_Interrupt_SaveList;
64 if (Subtarget.hasStdExtF())
65 return CSR_XLEN_F32_Interrupt_SaveList;
66 return CSR_Interrupt_SaveList;
69 switch (Subtarget.getTargetABI()) {
74 return CSR_ILP32_LP64_SaveList;
77 return CSR_ILP32F_LP64F_SaveList;
80 return CSR_ILP32D_LP64D_SaveList;
89 for (
size_t Reg = 0; Reg < getNumRegs(); Reg++) {
108 markSuperRegs(
Reserved, RISCV::VTYPE);
109 markSuperRegs(
Reserved, RISCV::VXSAT);
110 markSuperRegs(
Reserved, RISCV::VXRM);
111 markSuperRegs(
Reserved, RISCV::VLENB);
114 markSuperRegs(
Reserved, RISCV::FRM);
115 markSuperRegs(
Reserved, RISCV::FFLAGS);
127 return CSR_NoRegs_RegMask;
150 int &FrameIdx)
const {
152 if (!RVFI->useSaveRestoreLibCalls(MF))
160 FrameIdx = FII->second;
171 if (DestReg == SrcReg && !
Offset.getFixed() && !
Offset.getScalable())
179 bool KillSrcReg =
false;
181 if (
Offset.getScalable()) {
182 unsigned ScalableAdjOpc = RISCV::ADD;
183 int64_t ScalableValue =
Offset.getScalable();
184 if (ScalableValue < 0) {
185 ScalableValue = -ScalableValue;
186 ScalableAdjOpc = RISCV::SUB;
190 if (DestReg == SrcReg)
191 ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
192 TII->getVLENFactoredAmount(MF,
MBB, II,
DL, ScratchReg, ScalableValue, Flag);
200 int64_t Val =
Offset.getFixed();
201 if (DestReg == SrcReg && Val == 0)
206 if (isInt<12>(Val)) {
220 assert(
Align < 2048 &&
"Required alignment too large");
221 int64_t MaxPosAdjStep = 2048 -
Align;
222 if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) {
223 int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep;
236 unsigned Opc = RISCV::ADD;
242 Register ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
243 TII->movImm(
MBB, II,
DL, ScratchReg, Val, Flag);
261 unsigned NF = ZvlssegInfo->first;
262 unsigned LMUL = ZvlssegInfo->second;
263 assert(NF * LMUL <= 8 &&
"Invalid NF/LMUL combinations.");
264 unsigned Opcode, SubRegIdx;
269 Opcode = RISCV::VS1R_V;
270 SubRegIdx = RISCV::sub_vrm1_0;
273 Opcode = RISCV::VS2R_V;
274 SubRegIdx = RISCV::sub_vrm2_0;
277 Opcode = RISCV::VS4R_V;
278 SubRegIdx = RISCV::sub_vrm4_0;
281 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
282 "Unexpected subreg numbering");
283 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
284 "Unexpected subreg numbering");
285 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
286 "Unexpected subreg numbering");
288 Register VL =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
291 if (ShiftAmount != 0)
296 Register SrcReg = II->getOperand(0).getReg();
298 bool IsBaseKill = II->getOperand(1).isKill();
299 Register NewBase =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
300 for (
unsigned I = 0;
I < NF; ++
I) {
306 .
addReg(
TRI->getSubReg(SrcReg, SubRegIdx +
I))
316 II->eraseFromParent();
330 unsigned NF = ZvlssegInfo->first;
331 unsigned LMUL = ZvlssegInfo->second;
332 assert(NF * LMUL <= 8 &&
"Invalid NF/LMUL combinations.");
333 unsigned Opcode, SubRegIdx;
338 Opcode = RISCV::VL1RE8_V;
339 SubRegIdx = RISCV::sub_vrm1_0;
342 Opcode = RISCV::VL2RE8_V;
343 SubRegIdx = RISCV::sub_vrm2_0;
346 Opcode = RISCV::VL4RE8_V;
347 SubRegIdx = RISCV::sub_vrm4_0;
350 static_assert(RISCV::sub_vrm1_7 == RISCV::sub_vrm1_0 + 7,
351 "Unexpected subreg numbering");
352 static_assert(RISCV::sub_vrm2_3 == RISCV::sub_vrm2_0 + 3,
353 "Unexpected subreg numbering");
354 static_assert(RISCV::sub_vrm4_1 == RISCV::sub_vrm4_0 + 1,
355 "Unexpected subreg numbering");
357 Register VL =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
360 if (ShiftAmount != 0)
365 Register DestReg = II->getOperand(0).getReg();
367 bool IsBaseKill = II->getOperand(1).isKill();
368 Register NewBase =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
369 for (
unsigned I = 0;
I < NF; ++
I) {
371 TRI->getSubReg(DestReg, SubRegIdx +
I))
380 II->eraseFromParent();
384 int SPAdj,
unsigned FIOperandNum,
386 assert(SPAdj == 0 &&
"Unexpected non-zero SPAdj value");
394 int FrameIndex =
MI.getOperand(FIOperandNum).getIndex();
397 getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
402 if (
Offset.getScalable() &&
403 ST.getRealMinVLen() == ST.getRealMaxVLen()) {
406 int64_t FixedValue =
Offset.getFixed();
407 int64_t ScalableValue =
Offset.getScalable();
408 assert(ScalableValue % 8 == 0 &&
409 "Scalable offset is not a multiple of a single vector size.");
410 int64_t NumOfVReg = ScalableValue / 8;
411 int64_t VLENB = ST.getRealMinVLen() / 8;
415 if (!isInt<32>(
Offset.getFixed())) {
417 "Frame offsets outside of the signed 32-bit range not supported");
421 if (
MI.getOpcode() == RISCV::ADDI && !isInt<12>(
Offset.getFixed())) {
427 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);
432 int64_t Val =
Offset.getFixed();
433 int64_t Lo12 = SignExtend64<12>(Val);
434 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Lo12);
442 if (
MI.getOpcode() == RISCV::ADDI)
443 DestReg =
MI.getOperand(0).getReg();
445 DestReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
448 MI.getOperand(FIOperandNum).ChangeToRegister(DestReg,
false,
452 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg,
false,
458 if (
MI.getOpcode() == RISCV::ADDI &&
459 MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg() &&
460 MI.getOperand(2).getImm() == 0) {
461 MI.eraseFromParent();
469 switch (
MI.getOpcode()) {
470 case RISCV::PseudoVSPILL2_M1:
471 case RISCV::PseudoVSPILL2_M2:
472 case RISCV::PseudoVSPILL2_M4:
473 case RISCV::PseudoVSPILL3_M1:
474 case RISCV::PseudoVSPILL3_M2:
475 case RISCV::PseudoVSPILL4_M1:
476 case RISCV::PseudoVSPILL4_M2:
477 case RISCV::PseudoVSPILL5_M1:
478 case RISCV::PseudoVSPILL6_M1:
479 case RISCV::PseudoVSPILL7_M1:
480 case RISCV::PseudoVSPILL8_M1:
483 case RISCV::PseudoVRELOAD2_M1:
484 case RISCV::PseudoVRELOAD2_M2:
485 case RISCV::PseudoVRELOAD2_M4:
486 case RISCV::PseudoVRELOAD3_M1:
487 case RISCV::PseudoVRELOAD3_M2:
488 case RISCV::PseudoVRELOAD4_M1:
489 case RISCV::PseudoVRELOAD4_M2:
490 case RISCV::PseudoVRELOAD5_M1:
491 case RISCV::PseudoVRELOAD6_M1:
492 case RISCV::PseudoVRELOAD7_M1:
493 case RISCV::PseudoVRELOAD8_M1:
512 unsigned FIOperandNum = 0;
513 for (; !
MI->getOperand(FIOperandNum).isFI(); FIOperandNum++)
514 assert(FIOperandNum < MI->getNumOperands() &&
515 "Instr doesn't have FrameIndex operand");
524 if (!
MI->mayLoad() && !
MI->mayStore())
531 unsigned CalleeSavedSize = 0;
538 if (!ReservedRegs.
test(Reg))
539 CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg));
542 int64_t MaxFPOffset =
Offset - CalleeSavedSize;
543 if (TFI->
hasFP(MF) && !shouldRealignStack(MF))
550 int64_t MaxSPOffset =
Offset + 128;
560 unsigned FIOperandNum = 0;
561 while (!
MI->getOperand(FIOperandNum).isFI()) {
563 assert(FIOperandNum < MI->getNumOperands() &&
564 "Instr does not have a FrameIndex operand!");
596 unsigned FIOperandNum = 0;
597 while (!
MI.getOperand(FIOperandNum).isFI()) {
599 assert(FIOperandNum <
MI.getNumOperands() &&
600 "Instr does not have a FrameIndex operand!");
606 MI.getOperand(FIOperandNum).ChangeToRegister(BaseReg,
false);
607 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(
Offset);
616 "The MI must be I or S format.");
617 assert(
MI->getOperand(
Idx).isFI() &&
"The Idx'th operand of MI is not a "
618 "FrameIndex operand");
619 return MI->getOperand(
Idx + 1).getImm();
624 return TFI->
hasFP(MF) ? RISCV::X8 : RISCV::X2;
633 return CSR_NoRegs_RegMask;
634 switch (Subtarget.getTargetABI()) {
639 return CSR_ILP32_LP64_RegMask;
642 return CSR_ILP32F_LP64F_RegMask;
645 return CSR_ILP32D_LP64D_RegMask;
652 if (RC == &RISCV::VMV0RegClass)
653 return &RISCV::VRRegClass;
662 assert(
Offset.getScalable() % 8 == 0 &&
"Invalid frame offset");
668 int64_t VLENBSized =
Offset.getScalable() / 8;
669 if (VLENBSized > 0) {
672 Ops.
append({dwarf::DW_OP_bregx, VLENB, 0ULL});
675 }
else if (VLENBSized < 0) {
678 Ops.
append({dwarf::DW_OP_bregx, VLENB, 0ULL});
698 VirtReg, Order, Hints, MF, VRM,
Matrix);
701 return BaseImplRetVal;
707 bool NeedGPRC) ->
void {
710 if (PhysReg && (!NeedGPRC || RISCV::GPRCRegClass.
contains(PhysReg))) {
711 assert(!MO.getSubReg() && !VRRegMO.
getSubReg() &&
"Unexpected subreg!");
713 TwoAddrHints.
insert(PhysReg);
719 auto isCompressible = [](
const MachineInstr &
MI,
bool &NeedGPRC) {
721 switch (
MI.getOpcode()) {
734 return MI.getOperand(2).isImm() && isInt<6>(
MI.getOperand(2).getImm());
744 return MI.getOperand(2).isImm() && isInt<6>(
MI.getOperand(2).getImm());
757 return PhysReg && RISCV::GPRCRegClass.contains(PhysReg);
760 for (
auto &MO :
MRI->reg_nodbg_operands(VirtReg)) {
762 unsigned OpIdx = MO.getOperandNo();
764 if (isCompressible(
MI, NeedGPRC)) {
765 if (OpIdx == 0 &&
MI.getOperand(1).isReg()) {
766 if (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(2)))
767 tryAddHint(MO,
MI.getOperand(1), NeedGPRC);
768 if (
MI.isCommutable() &&
MI.getOperand(2).isReg() &&
769 (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(1))))
770 tryAddHint(MO,
MI.getOperand(2), NeedGPRC);
771 }
else if (OpIdx == 1 &&
772 (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(2)))) {
773 tryAddHint(MO,
MI.getOperand(0), NeedGPRC);
774 }
else if (
MI.isCommutable() && OpIdx == 2 &&
775 (!NeedGPRC || isCompressibleOpnd(
MI.getOperand(1)))) {
776 tryAddHint(MO,
MI.getOperand(0), NeedGPRC);
782 if (TwoAddrHints.
count(OrderReg))
785 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())
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