@@ -755,11 +755,32 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
755755 }
756756}
757757
758+ void RISCVFrameLowering::deallocateStack (MachineFunction &MF,
759+ MachineBasicBlock &MBB,
760+ MachineBasicBlock::iterator MBBI,
761+ const DebugLoc &DL, uint64_t StackSize,
762+ int64_t CFAOffset) const {
763+ const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
764+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
765+
766+ Register SPReg = getSPReg (STI);
767+
768+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
769+ MachineInstr::FrameDestroy, getStackAlign ());
770+
771+ unsigned CFIIndex =
772+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , CFAOffset));
773+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
774+ .addCFIIndex (CFIIndex)
775+ .setMIFlag (MachineInstr::FrameDestroy);
776+ }
777+
758778void RISCVFrameLowering::emitEpilogue (MachineFunction &MF,
759779 MachineBasicBlock &MBB) const {
760780 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
761781 MachineFrameInfo &MFI = MF.getFrameInfo ();
762782 auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
783+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
763784 Register FPReg = getFPReg (STI);
764785 Register SPReg = getSPReg (STI);
765786
@@ -786,20 +807,67 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
786807 --MBBI;
787808 }
788809
789- const auto &CSI = getUnmanagedCSI (MF, MFI.getCalleeSavedInfo () );
810+ const auto &CSI = MFI.getCalleeSavedInfo ();
790811
791812 // Skip to before the restores of scalar callee-saved registers
792813 // FIXME: assumes exactly one instruction is used to restore each
793814 // callee-saved register.
794- auto LastFrameDestroy = MBBI;
795- if (!CSI.empty ())
796- LastFrameDestroy = std::prev (MBBI, CSI.size ());
815+ auto LastFrameDestroy = std::prev (MBBI, getUnmanagedCSI (MF, CSI).size ());
797816
798- uint64_t RealStackSize = getStackSizeWithRVVPadding (MF);
799- uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize ();
800- uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize ();
817+ uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount (MF);
818+ uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
819+ : getStackSizeWithRVVPadding (MF);
820+ uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
821+ : getStackSizeWithRVVPadding (MF) -
822+ RVFI->getReservedSpillsSize ();
823+ uint64_t FPOffset = FirstSPAdjustAmount ? FirstSPAdjustAmount
824+ : getStackSizeWithRVVPadding (MF) -
825+ RVFI->getVarArgsSaveSize ();
801826 uint64_t RVVStackSize = RVFI->getRVVStackSize ();
802827
828+ bool restoreFP = RI->hasStackRealignment (MF) || MFI.hasVarSizedObjects () ||
829+ !hasReservedCallFrame (MF);
830+
831+ if (RVVStackSize) {
832+ // If restoreFP the stack pointer will be restored using the frame pointer
833+ // value.
834+ if (!restoreFP) {
835+ adjustStackForRVV (MF, MBB, LastFrameDestroy, DL, RVVStackSize,
836+ MachineInstr::FrameDestroy);
837+
838+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::cfiDefCfa (
839+ nullptr , RI->getDwarfRegNum (SPReg, true ), RealStackSize));
840+ BuildMI (MBB, LastFrameDestroy, DL,
841+ TII->get (TargetOpcode::CFI_INSTRUCTION))
842+ .addCFIIndex (CFIIndex)
843+ .setMIFlag (MachineInstr::FrameDestroy);
844+ }
845+
846+ emitCalleeSavedRVVEpilogCFI (MBB, LastFrameDestroy);
847+ }
848+
849+ if (FirstSPAdjustAmount) {
850+ uint64_t SecondSPAdjustAmount =
851+ getStackSizeWithRVVPadding (MF) - FirstSPAdjustAmount;
852+ assert (SecondSPAdjustAmount > 0 &&
853+ " SecondSPAdjustAmount should be greater than zero" );
854+
855+ // If restoreFP the stack pointer will be restored using the frame pointer
856+ // value.
857+ if (!restoreFP) {
858+ RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, SPReg,
859+ StackOffset::getFixed (SecondSPAdjustAmount),
860+ MachineInstr::FrameDestroy, getStackAlign ());
861+
862+ unsigned CFIIndex = MF.addFrameInst (
863+ MCCFIInstruction::cfiDefCfaOffset (nullptr , FirstSPAdjustAmount));
864+ BuildMI (MBB, LastFrameDestroy, DL,
865+ TII->get (TargetOpcode::CFI_INSTRUCTION))
866+ .addCFIIndex (CFIIndex)
867+ .setMIFlag (MachineInstr::FrameDestroy);
868+ }
869+ }
870+
803871 // Restore the stack pointer using the value of the frame pointer. Only
804872 // necessary if the stack pointer was modified, meaning the stack size is
805873 // unknown.
@@ -810,50 +878,58 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
810878 // normally it's just checking the variable sized object is present or not
811879 // is enough, but we also don't preserve that at prologue/epilogue when
812880 // have vector objects in stack.
813- if (RI->hasStackRealignment (MF) || MFI.hasVarSizedObjects () ||
814- !hasReservedCallFrame (MF)) {
815- assert (hasFP (MF) && " frame pointer should not have been eliminated" );
881+ if (restoreFP) {
816882 RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
817- StackOffset::getFixed (-FPOffset),
818- MachineInstr::FrameDestroy, getStackAlign ());
819- } else {
820- if (RVVStackSize)
821- adjustStackForRVV (MF, MBB, LastFrameDestroy, DL, RVVStackSize,
822- MachineInstr::FrameDestroy);
823- }
824-
825- uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount (MF);
826- if (FirstSPAdjustAmount) {
827- uint64_t SecondSPAdjustAmount =
828- getStackSizeWithRVVPadding (MF) - FirstSPAdjustAmount;
829- assert (SecondSPAdjustAmount > 0 &&
830- " SecondSPAdjustAmount should be greater than zero" );
883+ StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
884+ getStackAlign ());
831885
832- RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, SPReg,
833- StackOffset::getFixed (SecondSPAdjustAmount),
834- MachineInstr::FrameDestroy, getStackAlign ());
886+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::cfiDefCfa (
887+ nullptr , RI->getDwarfRegNum (SPReg, true ), RealStackSize));
888+ BuildMI (MBB, LastFrameDestroy, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
889+ .addCFIIndex (CFIIndex)
890+ .setMIFlag (MachineInstr::FrameDestroy);
835891 }
836892
837- if (FirstSPAdjustAmount)
838- StackSize = FirstSPAdjustAmount;
839-
840- if (RVFI->isPushable (MF) && MBBI != MBB.end () &&
841- MBBI->getOpcode () == RISCV::CM_POP) {
893+ bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
894+ MBBI->getOpcode () == RISCV::CM_POP;
895+ if (ApplyPop) {
842896 // Use available stack adjustment in pop instruction to deallocate stack
843897 // space. Align the stack size down to a multiple of 16. This is needed for
844898 // RVE.
845899 // FIXME: Can we increase the stack size to a multiple of 16 instead?
846900 uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
847901 MBBI->getOperand (1 ).setImm (Spimm);
848902 StackSize -= Spimm;
903+
904+ if (StackSize != 0 )
905+ deallocateStack (MF, MBB, MBBI, DL, StackSize,
906+ /* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
907+
908+ // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
909+ // is zero.
910+ MBBI = std::next (MBBI);
911+ unsigned CFIIndex =
912+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , 0 ));
913+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
914+ .addCFIIndex (CFIIndex)
915+ .setMIFlag (MachineInstr::FrameDestroy);
849916 }
850917
851- // Deallocate stack
852- if (StackSize != 0 ) {
853- RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
854- MachineInstr::FrameDestroy, getStackAlign ());
918+ // Recover callee-saved registers.
919+ for (const auto &Entry : CSI) {
920+ Register Reg = Entry.getReg ();
921+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createRestore (
922+ nullptr , RI->getDwarfRegNum (Reg, true )));
923+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
924+ .addCFIIndex (CFIIndex)
925+ .setMIFlag (MachineInstr::FrameDestroy);
855926 }
856927
928+ // Deallocate stack if StackSize isn't a zero and if we didn't already do it
929+ // during cm.pop handling.
930+ if (StackSize != 0 && !ApplyPop)
931+ deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
932+
857933 // Emit epilogue for shadow call stack.
858934 emitSCSEpilogue (MF, MBB, MBBI, DL);
859935}
@@ -1557,6 +1633,7 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
15571633 int FI = CS.getFrameIdx ();
15581634 if (FI >= 0 && MFI.getStackID (FI) == TargetStackID::ScalableVector) {
15591635 MCRegister BaseReg = TRI.getSubReg (CS.getReg (), RISCV::sub_vrm1_0);
1636+
15601637 // If it's not a grouped vector register, it doesn't have subregister, so
15611638 // the base register is just itself.
15621639 if (BaseReg == RISCV::NoRegister)
@@ -1576,6 +1653,31 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
15761653 }
15771654}
15781655
1656+ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI (
1657+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
1658+ MachineFunction *MF = MBB.getParent ();
1659+ const MachineFrameInfo &MFI = MF->getFrameInfo ();
1660+ const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
1661+ const TargetInstrInfo &TII = *STI.getInstrInfo ();
1662+ DebugLoc DL = MBB.findDebugLoc (MI);
1663+
1664+ const auto &RVVCSI = getRVVCalleeSavedInfo (*MF, MFI.getCalleeSavedInfo ());
1665+ if (RVVCSI.empty ())
1666+ return ;
1667+
1668+ for (auto &CS : RVVCSI) {
1669+ int FI = CS.getFrameIdx ();
1670+ if (FI >= 0 && MFI.getStackID (FI) == TargetStackID::ScalableVector) {
1671+ Register Reg = CS.getReg ();
1672+ unsigned CFIIndex = MF->addFrameInst (MCCFIInstruction::createRestore (
1673+ nullptr , RI->getDwarfRegNum (Reg, true )));
1674+ BuildMI (MBB, MI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
1675+ .addCFIIndex (CFIIndex)
1676+ .setMIFlag (MachineInstr::FrameDestroy);
1677+ }
1678+ }
1679+ }
1680+
15791681bool RISCVFrameLowering::restoreCalleeSavedRegisters (
15801682 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
15811683 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
0 commit comments