@@ -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+
416435void 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,19 +812,29 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
759812void 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 ();
819+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
765820
766821 RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
767822 MachineInstr::FrameDestroy, getStackAlign ());
823+ StackSize = 0 ;
824+
825+ unsigned CFIIndex =
826+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , CFAOffset));
827+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
828+ .addCFIIndex (CFIIndex)
829+ .setMIFlag (MachineInstr::FrameDestroy);
768830}
769831
770832void RISCVFrameLowering::emitEpilogue (MachineFunction &MF,
771833 MachineBasicBlock &MBB) const {
772834 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
773835 MachineFrameInfo &MFI = MF.getFrameInfo ();
774836 auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
837+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
775838
776839 // All calls are tail calls in GHC calling conv, and functions have no
777840 // prologue/epilogue.
@@ -814,15 +877,25 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
814877 RVFI->getVarArgsSaveSize ();
815878 uint64_t RVVStackSize = RVFI->getRVVStackSize ();
816879
817- bool RestoreFP = RI->hasStackRealignment (MF) || MFI.hasVarSizedObjects () ||
818- !hasReservedCallFrame (MF);
819-
880+ bool RestoreSPFromFP = RI->hasStackRealignment (MF) ||
881+ MFI.hasVarSizedObjects () || !hasReservedCallFrame (MF);
820882 if (RVVStackSize) {
821- // If RestoreFP the stack pointer will be restored using the frame pointer
822- // value.
823- if (!RestoreFP )
883+ // If RestoreSPFromFP the stack pointer will be restored using the frame
884+ // pointer value.
885+ if (!RestoreSPFromFP )
824886 adjustStackForRVV (MF, MBB, LastFrameDestroy, DL, RVVStackSize,
825887 MachineInstr::FrameDestroy);
888+
889+ if (!hasFP (MF)) {
890+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::cfiDefCfa (
891+ nullptr , RI->getDwarfRegNum (SPReg, true ), RealStackSize));
892+ BuildMI (MBB, LastFrameDestroy, DL,
893+ TII->get (TargetOpcode::CFI_INSTRUCTION))
894+ .addCFIIndex (CFIIndex)
895+ .setMIFlag (MachineInstr::FrameDestroy);
896+ }
897+
898+ emitCalleeSavedRVVEpilogCFI (MBB, LastFrameDestroy);
826899 }
827900
828901 if (FirstSPAdjustAmount) {
@@ -831,12 +904,21 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
831904 assert (SecondSPAdjustAmount > 0 &&
832905 " SecondSPAdjustAmount should be greater than zero" );
833906
834- // If RestoreFP the stack pointer will be restored using the frame pointer
835- // value.
836- if (!RestoreFP )
907+ // If RestoreSPFromFP the stack pointer will be restored using the frame
908+ // pointer value.
909+ if (!RestoreSPFromFP )
837910 RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, SPReg,
838911 StackOffset::getFixed (SecondSPAdjustAmount),
839912 MachineInstr::FrameDestroy, getStackAlign ());
913+
914+ if (!hasFP (MF)) {
915+ unsigned CFIIndex = MF.addFrameInst (
916+ MCCFIInstruction::cfiDefCfaOffset (nullptr , FirstSPAdjustAmount));
917+ BuildMI (MBB, LastFrameDestroy, DL,
918+ TII->get (TargetOpcode::CFI_INSTRUCTION))
919+ .addCFIIndex (CFIIndex)
920+ .setMIFlag (MachineInstr::FrameDestroy);
921+ }
840922 }
841923
842924 // Restore the stack pointer using the value of the frame pointer. Only
@@ -849,14 +931,44 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
849931 // normally it's just checking the variable sized object is present or not
850932 // is enough, but we also don't preserve that at prologue/epilogue when
851933 // have vector objects in stack.
852- if (RestoreFP ) {
934+ if (RestoreSPFromFP ) {
853935 assert (hasFP (MF) && " frame pointer should not have been eliminated" );
854-
855936 RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
856937 StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
857938 getStackAlign ());
858939 }
859940
941+ if (hasFP (MF)) {
942+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::cfiDefCfa (
943+ nullptr , RI->getDwarfRegNum (SPReg, true ), RealStackSize));
944+ BuildMI (MBB, LastFrameDestroy, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
945+ .addCFIIndex (CFIIndex)
946+ .setMIFlag (MachineInstr::FrameDestroy);
947+ }
948+
949+ if (getLibCallID (MF, CSI) != -1 ) {
950+ // tail __riscv_restore_[0-12] instruction is considered as a terminator,
951+ // therefor it is unnecessary to place any CFI instructions after it. Just
952+ // deallocate stack if needed and return.
953+ if (StackSize != 0 )
954+ deallocateStack (MF, MBB, MBBI, DL, StackSize,
955+ RVFI->getLibCallStackSize ());
956+
957+ // Emit epilogue for shadow call stack.
958+ emitSCSEpilogue (MF, MBB, MBBI, DL);
959+ return ;
960+ }
961+
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+
860972 bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
861973 MBBI->getOpcode () == RISCV::CM_POP;
862974 if (ApplyPop) {
@@ -872,12 +984,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
872984 deallocateStack (MF, MBB, MBBI, DL, StackSize,
873985 /* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
874986
875- ++MBBI;
987+ auto NextI = next_nodbg (MBBI, MBB.end ());
988+ if (NextI == MBB.end () || NextI->getOpcode () != RISCV::PseudoRET) {
989+ ++MBBI;
990+
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+ }
8761008 }
8771009
878- // Deallocate stack if we didn't already do it during cm.pop handling and
879- // StackSize isn't a zero
880- if (StackSize != 0 && !ApplyPop)
1010+ // Deallocate stack if StackSize isn't a zero yet
1011+ if (StackSize != 0 )
8811012 deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
8821013
8831014 // Emit epilogue for shadow call stack.
@@ -1564,6 +1695,23 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
15641695 return true ;
15651696}
15661697
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+
15671715void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
15681716 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
15691717 MachineFunction *MF = MBB.getParent ();
@@ -1590,15 +1738,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
15901738 // Insert the spill to the stack frame.
15911739 int FI = CS.getFrameIdx ();
15921740 if (FI >= 0 && MFI.getStackID (FI) == TargetStackID::ScalableVector) {
1593- MCRegister BaseReg = TRI.getSubReg (CS.getReg (), RISCV::sub_vrm1_0);
1594- // If it's not a grouped vector register, it doesn't have subregister, so
1595- // the base register is just itself.
1596- if (BaseReg == RISCV::NoRegister)
1597- BaseReg = CS.getReg ();
1598- unsigned NumRegs = RISCV::VRRegClass.contains (CS.getReg ()) ? 1
1599- : RISCV::VRM2RegClass.contains (CS.getReg ()) ? 2
1600- : RISCV::VRM4RegClass.contains (CS.getReg ()) ? 4
1601- : 8 ;
1741+ MCRegister BaseReg = getRVVBaseRegister (TRI, CS.getReg ());
1742+ unsigned NumRegs = getCaleeSavedRVVNumRegs (CS.getReg ());
16021743 for (unsigned i = 0 ; i < NumRegs; ++i) {
16031744 unsigned CFIIndex = MF->addFrameInst (createDefCFAOffset (
16041745 TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset (FI) / 8 + i));
@@ -1610,6 +1751,29 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16101751 }
16111752}
16121753
1754+ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI (
1755+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
1756+ MachineFunction *MF = MBB.getParent ();
1757+ const MachineFrameInfo &MFI = MF->getFrameInfo ();
1758+ const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
1759+ const TargetInstrInfo &TII = *STI.getInstrInfo ();
1760+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo ();
1761+ DebugLoc DL = MBB.findDebugLoc (MI);
1762+
1763+ const auto &RVVCSI = getRVVCalleeSavedInfo (*MF, MFI.getCalleeSavedInfo ());
1764+ for (auto &CS : RVVCSI) {
1765+ MCRegister BaseReg = getRVVBaseRegister (TRI, CS.getReg ());
1766+ unsigned NumRegs = getCaleeSavedRVVNumRegs (CS.getReg ());
1767+ for (unsigned i = 0 ; i < NumRegs; ++i) {
1768+ unsigned CFIIndex = MF->addFrameInst (MCCFIInstruction::createRestore (
1769+ nullptr , RI->getDwarfRegNum (BaseReg + i, true )));
1770+ BuildMI (MBB, MI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
1771+ .addCFIIndex (CFIIndex)
1772+ .setMIFlag (MachineInstr::FrameDestroy);
1773+ }
1774+ }
1775+ }
1776+
16131777bool RISCVFrameLowering::restoreCalleeSavedRegisters (
16141778 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
16151779 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
0 commit comments