@@ -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+
411428void 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,
758809void 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+
16361715void 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);
0 commit comments