Skip to content

Commit 7b01cba

Browse files
committed
[RISCV][CFI] update prolog
1 parent 8e92906 commit 7b01cba

File tree

2 files changed

+120
-47
lines changed

2 files changed

+120
-47
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 119 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,23 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
408408
return RVVCSI;
409409
}
410410

411+
static SmallVector<CalleeSavedInfo, 8> getPushOrLibCallsSavedInfo(const MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI) {
412+
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
413+
414+
SmallVector<CalleeSavedInfo, 8> PushPopOrLibCallsCSI;
415+
if (!RVFI->useSaveRestoreLibCalls(MF) && !RVFI->isPushable(MF))
416+
return PushPopOrLibCallsCSI;
417+
418+
for (auto &CS : CSI) {
419+
const auto *FII = llvm::find_if(
420+
FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); });
421+
if (FII != std::end(FixedCSRFIMap))
422+
PushPopOrLibCallsCSI.push_back(CS);
423+
}
424+
425+
return PushPopOrLibCallsCSI;
426+
}
427+
411428
void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF,
412429
MachineBasicBlock &MBB,
413430
MachineBasicBlock::iterator MBBI,
@@ -556,6 +573,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
556573
// Determine the correct frame layout
557574
determineFrameLayout(MF);
558575

576+
const auto &CSI = MFI.getCalleeSavedInfo();
577+
559578
// If libcalls are used to spill and restore callee-saved registers, the frame
560579
// has two sections; the opaque section managed by the libcalls, and the
561580
// section managed by MachineFrameInfo which can also hold callee saved
@@ -581,6 +600,23 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
581600
unsigned LibCallFrameSize =
582601
alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
583602
RVFI->setLibCallStackSize(LibCallFrameSize);
603+
604+
unsigned CFIIndex = MF.addFrameInst(
605+
MCCFIInstruction::cfiDefCfaOffset(nullptr, LibCallFrameSize));
606+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
607+
.addCFIIndex(CFIIndex)
608+
.setMIFlag(MachineInstr::FrameSetup);
609+
610+
for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) {
611+
int FrameIdx = Entry.getFrameIdx();
612+
int64_t Offset = MFI.getObjectOffset(FrameIdx);
613+
Register Reg = Entry.getReg();
614+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
615+
nullptr, RI->getDwarfRegNum(Reg, true), Offset));
616+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
617+
.addCFIIndex(CFIIndex)
618+
.setMIFlag(MachineInstr::FrameSetup);
619+
}
584620
}
585621

586622
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -615,23 +651,38 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
615651
uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48);
616652
FirstFrameSetup->getOperand(1).setImm(Spimm);
617653
StackSize -= Spimm;
654+
655+
unsigned CFIIndex = MF.addFrameInst(
656+
MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize - StackSize));
657+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
658+
.addCFIIndex(CFIIndex)
659+
.setMIFlag(MachineInstr::FrameSetup);
660+
661+
for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) {
662+
int FrameIdx = Entry.getFrameIdx();
663+
int64_t Offset = MFI.getObjectOffset(FrameIdx);
664+
Register Reg = Entry.getReg();
665+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
666+
nullptr, RI->getDwarfRegNum(Reg, true), Offset));
667+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
668+
.addCFIIndex(CFIIndex)
669+
.setMIFlag(MachineInstr::FrameSetup);
670+
}
618671
}
619672

620673
if (StackSize != 0) {
621674
// Allocate space on the stack if necessary.
622675
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
623676
StackOffset::getFixed(-StackSize), MachineInstr::FrameSetup,
624677
getStackAlign());
625-
}
626-
627-
// Emit ".cfi_def_cfa_offset RealStackSize"
628-
unsigned CFIIndex = MF.addFrameInst(
629-
MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize));
630-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
631-
.addCFIIndex(CFIIndex)
632-
.setMIFlag(MachineInstr::FrameSetup);
633678

634-
const auto &CSI = MFI.getCalleeSavedInfo();
679+
// Emit ".cfi_def_cfa_offset RealStackSize"
680+
unsigned CFIIndex = MF.addFrameInst(
681+
MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize));
682+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
683+
.addCFIIndex(CFIIndex)
684+
.setMIFlag(MachineInstr::FrameSetup);
685+
}
635686

636687
// The frame pointer is callee-saved, and code has been generated for us to
637688
// save it to the stack. We need to skip over the storing of callee-saved
@@ -643,7 +694,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
643694

644695
// Iterate over list of callee-saved registers and emit .cfi_offset
645696
// directives.
646-
for (const auto &Entry : CSI) {
697+
for (const auto &Entry : getUnmanagedCSI(MF, CSI)) {
647698
int FrameIdx = Entry.getFrameIdx();
648699
if (FrameIdx >= 0 &&
649700
MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector)
@@ -758,7 +809,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
758809
void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
759810
MachineBasicBlock &MBB,
760811
MachineBasicBlock::iterator MBBI,
761-
const DebugLoc &DL, uint64_t StackSize,
812+
const DebugLoc &DL, uint64_t &StackSize,
762813
int64_t CFAOffset) const {
763814
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
764815
const RISCVInstrInfo *TII = STI.getInstrInfo();
@@ -767,6 +818,7 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
767818

768819
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
769820
MachineInstr::FrameDestroy, getStackAlign());
821+
StackSize = 0;
770822

771823
unsigned CFIIndex =
772824
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
@@ -881,7 +933,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
881933
// have vector objects in stack.
882934
if (RestoreSPFromFP) {
883935
assert(hasFP(MF) && "frame pointer should not have been eliminated");
884-
885936
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
886937
StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
887938
getStackAlign());
@@ -908,6 +959,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
908959
return;
909960
}
910961

962+
// Recover callee-saved registers.
963+
for (const auto &Entry : getUnmanagedCSI(MF, CSI)) {
964+
Register Reg = Entry.getReg();
965+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
966+
nullptr, RI->getDwarfRegNum(Reg, true)));
967+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
968+
.addCFIIndex(CFIIndex)
969+
.setMIFlag(MachineInstr::FrameDestroy);
970+
}
971+
911972
bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
912973
MBBI->getOpcode() == RISCV::CM_POP;
913974
if (ApplyPop) {
@@ -923,29 +984,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
923984
deallocateStack(MF, MBB, MBBI, DL, StackSize,
924985
/*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
925986

926-
++MBBI;
927-
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
928-
// should be a zero.
929-
unsigned CFIIndex =
930-
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
931-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
932-
.addCFIIndex(CFIIndex)
933-
.setMIFlag(MachineInstr::FrameDestroy);
934-
}
987+
auto NextI = next_nodbg(MBBI, MBB.end());
988+
if (NextI == MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) {
989+
++MBBI;
935990

936-
// Recover callee-saved registers.
937-
for (const auto &Entry : CSI) {
938-
Register Reg = Entry.getReg();
939-
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
940-
nullptr, RI->getDwarfRegNum(Reg, true)));
941-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
942-
.addCFIIndex(CFIIndex)
943-
.setMIFlag(MachineInstr::FrameDestroy);
944-
}
991+
for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) {
992+
Register Reg = Entry.getReg();
993+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
994+
nullptr, RI->getDwarfRegNum(Reg, true)));
995+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
996+
.addCFIIndex(CFIIndex)
997+
.setMIFlag(MachineInstr::FrameDestroy);
998+
}
945999

946-
// Deallocate stack if we didn't already do it during cm.pop handling and
947-
// StackSize isn't a zero
948-
if (StackSize != 0 && !ApplyPop)
1000+
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
1001+
// should be a zero.
1002+
unsigned CFIIndex =
1003+
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
1004+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1005+
.addCFIIndex(CFIIndex)
1006+
.setMIFlag(MachineInstr::FrameDestroy);
1007+
}
1008+
}
1009+
1010+
// Deallocate stack if StackSize isn't a zero yet
1011+
if (StackSize != 0)
9491012
deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
9501013

9511014
// Emit epilogue for shadow call stack.
@@ -1633,6 +1696,22 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
16331696
return true;
16341697
}
16351698

1699+
static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) {
1700+
return RISCV::VRRegClass.contains(BaseReg) ? 1
1701+
: RISCV::VRM2RegClass.contains(BaseReg) ? 2
1702+
: RISCV::VRM4RegClass.contains(BaseReg) ? 4
1703+
: 8;
1704+
}
1705+
1706+
static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, const Register &Reg) {
1707+
MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0);
1708+
// If it's not a grouped vector register, it doesn't have subregister, so
1709+
// the base register is just itself.
1710+
if (BaseReg == RISCV::NoRegister)
1711+
BaseReg = Reg;
1712+
return BaseReg;
1713+
}
1714+
16361715
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16371716
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
16381717
MachineFunction *MF = MBB.getParent();
@@ -1659,15 +1738,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16591738
// Insert the spill to the stack frame.
16601739
int FI = CS.getFrameIdx();
16611740
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1662-
MCRegister BaseReg = TRI.getSubReg(CS.getReg(), RISCV::sub_vrm1_0);
1663-
// If it's not a grouped vector register, it doesn't have subregister, so
1664-
// the base register is just itself.
1665-
if (BaseReg == RISCV::NoRegister)
1666-
BaseReg = CS.getReg();
1667-
unsigned NumRegs = RISCV::VRRegClass.contains(CS.getReg()) ? 1
1668-
: RISCV::VRM2RegClass.contains(CS.getReg()) ? 2
1669-
: RISCV::VRM4RegClass.contains(CS.getReg()) ? 4
1670-
: 8;
1741+
MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1742+
unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg());
16711743
for (unsigned i = 0; i < NumRegs; ++i) {
16721744
unsigned CFIIndex = MF->addFrameInst(createDefCFAOffset(
16731745
TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset(FI) / 8 + i));
@@ -1685,15 +1757,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
16851757
const MachineFrameInfo &MFI = MF->getFrameInfo();
16861758
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
16871759
const TargetInstrInfo &TII = *STI.getInstrInfo();
1760+
const RISCVRegisterInfo &TRI = *STI.getRegisterInfo();
16881761
DebugLoc DL = MBB.findDebugLoc(MI);
16891762

16901763
const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
16911764
for (auto &CS : RVVCSI) {
1692-
int FI = CS.getFrameIdx();
1693-
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1694-
Register Reg = CS.getReg();
1765+
MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1766+
unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg());
1767+
for (unsigned i = 0; i < NumRegs; ++i) {
16951768
unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore(
1696-
nullptr, RI->getDwarfRegNum(Reg, true)));
1769+
nullptr, RI->getDwarfRegNum(BaseReg + i, true)));
16971770
BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
16981771
.addCFIIndex(CFIIndex)
16991772
.setMIFlag(MachineInstr::FrameDestroy);

llvm/lib/Target/RISCV/RISCVFrameLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class RISCVFrameLowering : public TargetFrameLowering {
9595
MachineBasicBlock::iterator MI) const;
9696
void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB,
9797
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
98-
uint64_t StackSize, int64_t CFAOffset) const;
98+
uint64_t &StackSize, int64_t CFAOffset) const;
9999

100100
std::pair<int64_t, Align>
101101
assignRVVStackObjectOffsets(MachineFunction &MF) const;

0 commit comments

Comments
 (0)