Skip to content

Commit b0227fb

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

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
@@ -413,6 +413,23 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
413413
return RVVCSI;
414414
}
415415

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

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

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

621674
if (StackSize != 0) {
622675
// Allocate space on the stack if necessary.
623676
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
624677
StackOffset::getFixed(-StackSize), MachineInstr::FrameSetup,
625678
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);
634679

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

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

645696
// Iterate over list of callee-saved registers and emit .cfi_offset
646697
// directives.
647-
for (const auto &Entry : CSI) {
698+
for (const auto &Entry : getUnmanagedCSI(MF, CSI)) {
648699
int FrameIdx = Entry.getFrameIdx();
649700
if (FrameIdx >= 0 &&
650701
MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector)
@@ -759,13 +810,14 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
759810
void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
760811
MachineBasicBlock &MBB,
761812
MachineBasicBlock::iterator MBBI,
762-
const DebugLoc &DL, uint64_t StackSize,
813+
const DebugLoc &DL, uint64_t &StackSize,
763814
int64_t CFAOffset) const {
764815
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
765816
const RISCVInstrInfo *TII = STI.getInstrInfo();
766817

767818
RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
768819
MachineInstr::FrameDestroy, getStackAlign());
820+
StackSize = 0;
769821

770822
unsigned CFIIndex =
771823
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
@@ -878,7 +930,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
878930
// have vector objects in stack.
879931
if (RestoreSPFromFP) {
880932
assert(hasFP(MF) && "frame pointer should not have been eliminated");
881-
882933
RI->adjustReg(MBB, LastFrameDestroy, DL, SPReg, FPReg,
883934
StackOffset::getFixed(-FPOffset), MachineInstr::FrameDestroy,
884935
getStackAlign());
@@ -905,6 +956,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
905956
return;
906957
}
907958

959+
// Recover callee-saved registers.
960+
for (const auto &Entry : getUnmanagedCSI(MF, CSI)) {
961+
Register Reg = Entry.getReg();
962+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
963+
nullptr, RI->getDwarfRegNum(Reg, true)));
964+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
965+
.addCFIIndex(CFIIndex)
966+
.setMIFlag(MachineInstr::FrameDestroy);
967+
}
968+
908969
bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() &&
909970
MBBI->getOpcode() == RISCV::CM_POP;
910971
if (ApplyPop) {
@@ -920,29 +981,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
920981
deallocateStack(MF, MBB, MBBI, DL, StackSize,
921982
/*stack_adj of cm.pop instr*/ RealStackSize - StackSize);
922983

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-
}
984+
auto NextI = next_nodbg(MBBI, MBB.end());
985+
if (NextI == MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) {
986+
++MBBI;
932987

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);
941-
}
988+
for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) {
989+
Register Reg = Entry.getReg();
990+
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
991+
nullptr, RI->getDwarfRegNum(Reg, true)));
992+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
993+
.addCFIIndex(CFIIndex)
994+
.setMIFlag(MachineInstr::FrameDestroy);
995+
}
942996

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)
997+
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
998+
// should be a zero.
999+
unsigned CFIIndex =
1000+
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
1001+
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1002+
.addCFIIndex(CFIIndex)
1003+
.setMIFlag(MachineInstr::FrameDestroy);
1004+
}
1005+
}
1006+
1007+
// Deallocate stack if StackSize isn't a zero yet
1008+
if (StackSize != 0)
9461009
deallocateStack(MF, MBB, MBBI, DL, StackSize, 0);
9471010

9481011
// Emit epilogue for shadow call stack.
@@ -1629,6 +1692,22 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
16291692
return true;
16301693
}
16311694

1695+
static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) {
1696+
return RISCV::VRRegClass.contains(BaseReg) ? 1
1697+
: RISCV::VRM2RegClass.contains(BaseReg) ? 2
1698+
: RISCV::VRM4RegClass.contains(BaseReg) ? 4
1699+
: 8;
1700+
}
1701+
1702+
static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, const Register &Reg) {
1703+
MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0);
1704+
// If it's not a grouped vector register, it doesn't have subregister, so
1705+
// the base register is just itself.
1706+
if (BaseReg == RISCV::NoRegister)
1707+
BaseReg = Reg;
1708+
return BaseReg;
1709+
}
1710+
16321711
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16331712
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
16341713
MachineFunction *MF = MBB.getParent();
@@ -1655,15 +1734,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16551734
// Insert the spill to the stack frame.
16561735
int FI = CS.getFrameIdx();
16571736
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;
1737+
MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1738+
unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg());
16671739
for (unsigned i = 0; i < NumRegs; ++i) {
16681740
unsigned CFIIndex = MF->addFrameInst(createDefCFAOffset(
16691741
TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset(FI) / 8 + i));
@@ -1681,15 +1753,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
16811753
const MachineFrameInfo &MFI = MF->getFrameInfo();
16821754
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
16831755
const TargetInstrInfo &TII = *STI.getInstrInfo();
1756+
const RISCVRegisterInfo &TRI = *STI.getRegisterInfo();
16841757
DebugLoc DL = MBB.findDebugLoc(MI);
16851758

16861759
const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo());
16871760
for (auto &CS : RVVCSI) {
1688-
int FI = CS.getFrameIdx();
1689-
if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) {
1690-
Register Reg = CS.getReg();
1761+
MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg());
1762+
unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg());
1763+
for (unsigned i = 0; i < NumRegs; ++i) {
16911764
unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore(
1692-
nullptr, RI->getDwarfRegNum(Reg, true)));
1765+
nullptr, RI->getDwarfRegNum(BaseReg + i, true)));
16931766
BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
16941767
.addCFIIndex(CFIIndex)
16951768
.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)