Skip to content

Commit 1654ef9

Browse files
committed
[RISCV][CFI] update prolog
1 parent 4f4ff18 commit 1654ef9

File tree

2 files changed

+123
-46
lines changed

2 files changed

+123
-46
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 122 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,25 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
413413
return RVVCSI;
414414
}
415415

416+
static SmallVector<CalleeSavedInfo, 8>
417+
getPushOrLibCallsSavedInfo(const MachineFunction &MF,
418+
const std::vector<CalleeSavedInfo> &CSI) {
419+
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
420+
421+
SmallVector<CalleeSavedInfo, 8> PushPopOrLibCallsCSI;
422+
if (!RVFI->useSaveRestoreLibCalls(MF) && !RVFI->isPushable(MF))
423+
return PushPopOrLibCallsCSI;
424+
425+
for (auto &CS : CSI) {
426+
const auto *FII = llvm::find_if(
427+
FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); });
428+
if (FII != std::end(FixedCSRFIMap))
429+
PushPopOrLibCallsCSI.push_back(CS);
430+
}
431+
432+
return PushPopOrLibCallsCSI;
433+
}
434+
416435
void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF,
417436
MachineBasicBlock &MBB,
418437
MachineBasicBlock::iterator MBBI,
@@ -557,6 +576,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
557576
// Determine the correct frame layout
558577
determineFrameLayout(MF);
559578

579+
const auto &CSI = MFI.getCalleeSavedInfo();
580+
560581
// If libcalls are used to spill and restore callee-saved registers, the frame
561582
// has two sections; the opaque section managed by the libcalls, and the
562583
// section managed by MachineFrameInfo which can also hold callee saved
@@ -582,6 +603,23 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
582603
unsigned LibCallFrameSize =
583604
alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
584605
RVFI->setLibCallStackSize(LibCallFrameSize);
606+
607+
unsigned CFIIndex = MF.addFrameInst(
608+
MCCFIInstruction::cfiDefCfaOffset(nullptr, LibCallFrameSize));
609+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
610+
.addCFIIndex(CFIIndex)
611+
.setMIFlag(MachineInstr::FrameSetup);
612+
613+
for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) {
614+
int FrameIdx = Entry.getFrameIdx();
615+
int64_t Offset = MFI.getObjectOffset(FrameIdx);
616+
Register Reg = Entry.getReg();
617+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
618+
nullptr, RI->getDwarfRegNum(Reg, true), Offset));
619+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
620+
.addCFIIndex(CFIIndex)
621+
.setMIFlag(MachineInstr::FrameSetup);
622+
}
585623
}
586624

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

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

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

637690
// The frame pointer is callee-saved, and code has been generated for us to
638691
// save it to the stack. We need to skip over the storing of callee-saved
@@ -644,7 +697,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
644697

645698
// Iterate over list of callee-saved registers and emit .cfi_offset
646699
// directives.
647-
for (const auto &Entry : CSI) {
700+
for (const auto &Entry : getUnmanagedCSI(MF, CSI)) {
648701
int FrameIdx = Entry.getFrameIdx();
649702
if (FrameIdx >= 0 &&
650703
MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector)
@@ -759,13 +812,15 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
759812
void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
760813
MachineBasicBlock &MBB,
761814
MachineBasicBlock::iterator MBBI,
762-
const DebugLoc &DL, uint64_t StackSize,
815+
const DebugLoc &DL,
816+
uint64_t &StackSize,
763817
int64_t CFAOffset) const {
764818
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
765819
const RISCVInstrInfo *TII = STI.getInstrInfo();
766820

767821
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
768822
MachineInstr::FrameDestroy, getStackAlign());
823+
StackSize = 0;
769824

770825
unsigned CFIIndex =
771826
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
@@ -878,7 +933,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
878933
// have vector objects in stack.
879934
if (RestoreSPFromFP) {
880935
assert(hasFP(MF) && "frame pointer should not have been eliminated");
881-
882936
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
883937
StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
884938
getStackAlign());
@@ -905,6 +959,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
905959
return;
906960
}
907961

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+
908972
bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
909973
MBBI->getOpcode() == RISCV::CM_POP;
910974
if (ApplyPop) {
@@ -920,29 +984,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
920984
deallocateStack(MF, MBB, MBBI, DL, StackSize,
921985
/*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
922986

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

933-
// Recover callee-saved registers.
934-
for (const auto &Entry : CSI) {
935-
Register Reg = Entry.getReg();
936-
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
937-
nullptr, RI->getDwarfRegNum(Reg, true)));
938-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
939-
.addCFIIndex(CFIIndex)
940-
.setMIFlag(MachineInstr::FrameDestroy);
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+
}
999+
1000+
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA
1001+
// offset 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+
}
9411008
}
9421009

943-
// Deallocate stack if we didn't already do it during cm.pop handling and
944-
// StackSize isn't a zero
945-
if (StackSize != 0 && !ApplyPop)
1010+
// Deallocate stack if StackSize isn't a zero yet
1011+
if (StackSize != 0)
9461012
deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
9471013

9481014
// Emit epilogue for shadow call stack.
@@ -1629,6 +1695,23 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
16291695
return true;
16301696
}
16311697

1698+
static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) {
1699+
return RISCV::VRRegClass.contains(BaseReg) ? 1
1700+
: RISCV::VRM2RegClass.contains(BaseReg) ? 2
1701+
: RISCV::VRM4RegClass.contains(BaseReg) ? 4
1702+
: 8;
1703+
}
1704+
1705+
static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI,
1706+
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+
16321715
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16331716
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
16341717
MachineFunction *MF = MBB.getParent();
@@ -1655,15 +1738,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16551738
// Insert the spill to the stack frame.
16561739
int FI = CS.getFrameIdx();
16571740
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1658-
MCRegister BaseReg = TRI.getSubReg(CS.getReg(), RISCV::sub_vrm1_0);
1659-
// If it's not a grouped vector register, it doesn't have subregister, so
1660-
// the base register is just itself.
1661-
if (BaseReg == RISCV::NoRegister)
1662-
BaseReg = CS.getReg();
1663-
unsigned NumRegs = RISCV::VRRegClass.contains(CS.getReg()) ? 1
1664-
: RISCV::VRM2RegClass.contains(CS.getReg()) ? 2
1665-
: RISCV::VRM4RegClass.contains(CS.getReg()) ? 4
1666-
: 8;
1741+
MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1742+
unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg());
16671743
for (unsigned i = 0; i < NumRegs; ++i) {
16681744
unsigned CFIIndex = MF->addFrameInst(createDefCFAOffset(
16691745
TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset(FI) / 8 + i));
@@ -1681,15 +1757,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
16811757
const MachineFrameInfo &MFI = MF->getFrameInfo();
16821758
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
16831759
const TargetInstrInfo &TII = *STI.getInstrInfo();
1760+
const RISCVRegisterInfo &TRI = *STI.getRegisterInfo();
16841761
DebugLoc DL = MBB.findDebugLoc(MI);
16851762

16861763
const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
16871764
for (auto &CS : RVVCSI) {
1688-
int FI = CS.getFrameIdx();
1689-
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1690-
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) {
16911768
unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore(
1692-
nullptr, RI->getDwarfRegNum(Reg, true)));
1769+
nullptr, RI->getDwarfRegNum(BaseReg + i, true)));
16931770
BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
16941771
.addCFIIndex(CFIIndex)
16951772
.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)