Go to the documentation of this file.
27 #define GET_REGINFO_TARGET_DESC
28 #include "RISCVGenRegisterInfo.inc"
35 cl::desc(
"Disable two address hints for register "
38 static_assert(RISCV::X1 == RISCV::X0 + 1,
"Register list not consecutive");
39 static_assert(RISCV::X31 == RISCV::X0 + 31,
"Register list not consecutive");
40 static_assert(RISCV::F1_H == RISCV::F0_H + 1,
"Register list not consecutive");
41 static_assert(RISCV::F31_H == RISCV::F0_H + 31,
42 "Register list not consecutive");
43 static_assert(RISCV::F1_F == RISCV::F0_F + 1,
"Register list not consecutive");
44 static_assert(RISCV::F31_F == RISCV::F0_F + 31,
45 "Register list not consecutive");
46 static_assert(RISCV::F1_D == RISCV::F0_D + 1,
"Register list not consecutive");
47 static_assert(RISCV::F31_D == RISCV::F0_D + 31,
48 "Register list not consecutive");
49 static_assert(RISCV::V1 == RISCV::V0 + 1,
"Register list not consecutive");
50 static_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()) {
183 int64_t ScalableValue =
Offset.getScalable();
184 if (ScalableValue < 0) {
185 ScalableValue = -ScalableValue;
190 if (DestReg == SrcReg)
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;
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");
291 if (ShiftAmount != 0)
296 Register SrcReg = II->getOperand(0).getReg();
298 bool IsBaseKill = II->getOperand(1).isKill();
300 for (
unsigned I = 0;
I < NF; ++
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");
360 if (ShiftAmount != 0)
365 Register DestReg = II->getOperand(0).getReg();
367 bool IsBaseKill = II->getOperand(1).isKill();
369 for (
unsigned I = 0;
I < NF; ++
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();
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;
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) {
670 Ops.push_back(dwarf::DW_OP_constu);
671 Ops.push_back(VLENBSized);
672 Ops.
append({dwarf::DW_OP_bregx, VLENB, 0ULL});
673 Ops.push_back(dwarf::DW_OP_mul);
674 Ops.push_back(dwarf::DW_OP_plus);
675 }
else if (VLENBSized < 0) {
676 Ops.push_back(dwarf::DW_OP_constu);
677 Ops.push_back(-VLENBSized);
678 Ops.
append({dwarf::DW_OP_bregx, VLENB, 0ULL});
679 Ops.push_back(dwarf::DW_OP_mul);
680 Ops.push_back(dwarf::DW_OP_minus);
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);
762 unsigned OpIdx =
MI.getOperandNo(&MO);
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))
783 Hints.push_back(OrderReg);
785 return BaseImplRetVal;
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override
unsigned getRegisterCostTableIndex(const MachineFunction &MF) const override
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
Register getFrameRegister(const MachineFunction &MF) const override
Information about stack frame layout on the target.
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static StackOffset get(int64_t Fixed, int64_t Scalable)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const override
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
virtual const TargetInstrInfo * getInstrInfo() const
RISCVRegisterInfo(unsigned HwMode)
return AArch64::GPR64RegClass contains(Reg)
bool isRegisterReservedByUser(Register i) const
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
Reg
All possible values of the reg field in the ModR/M byte.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
const_iterator end(StringRef path)
Get end iterator over path.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, Register SrcReg, StackOffset Offset, MachineInstr::MIFlag Flag, MaybeAlign RequiredAlign) const
unsigned const TargetRegisterInfo * TRI
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
bool getRegAllocationHints(Register VirtReg, ArrayRef< MCPhysReg > Order, SmallVectorImpl< MCPhysReg > &Hints, const MachineFunction &MF, const VirtRegMap *VRM, const LiveRegMatrix *Matrix) const override
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const override
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(Register Reg) const
const HexagonInstrInfo * TII
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MachineOperand class - Representation of each machine instruction operand.
void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const override
BitVector getReservedRegs(const MachineFunction &MF) const override
Flag
These should be considered private to the implementation of the MCInstrDesc class.
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ AND
Bitwise operators - logical and, logical or, logical xor.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void lowerVRELOAD(MachineBasicBlock::iterator II) const
This struct is a compact representation of a valid (non-zero power of two) alignment.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static unsigned getFormat(uint64_t TSFlags)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
Representation of each machine instruction.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const override
bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const override
@ Implicit
Not emitted register (e.g. carry, or temporary result).
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
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...
initializer< Ty > init(const Ty &Val)
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StackOffset holds a fixed and a scalable offset in bytes.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
void lowerVSPILL(MachineBasicBlock::iterator II) const
unsigned const MachineRegisterInfo * MRI
bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg, int &FrameIdx) const override
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
bool test(unsigned Idx) const
Function & getFunction()
Return the LLVM function that this machine code represents.
uint64_t value() const
This is a hole in the type system and should not be abused.
bool isRVVSpill(const MachineInstr &MI)
static const std::pair< unsigned, int > FixedCSRFIMap[]
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
@ ADD
Simple integer binary arithmetic operators.
static cl::opt< bool > DisableRegAllocHints("riscv-disable-regalloc-hints", cl::Hidden, cl::init(false), cl::desc("Disable two address hints for register " "allocation"))
@ Kill
The last use of a register.
unsigned getKillRegState(bool B)
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
const uint32_t * getNoPreservedMask() const override
bool hasBP(const MachineFunction &MF) const
int64_t getFixed() const
Returns the fixed component of the stack.
Wrapper class representing physical registers. Should be passed by value.
bool isAsmClobberable(const MachineFunction &MF, MCRegister PhysReg) const override