@@ -755,11 +755,32 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
755
755
}
756
756
}
757
757
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
+
758
778
void RISCVFrameLowering::emitEpilogue (MachineFunction &MF,
759
779
MachineBasicBlock &MBB) const {
760
780
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
761
781
MachineFrameInfo &MFI = MF.getFrameInfo ();
762
782
auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
783
+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
763
784
Register FPReg = getFPReg (STI);
764
785
Register SPReg = getSPReg (STI);
765
786
@@ -786,20 +807,67 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
786
807
--MBBI;
787
808
}
788
809
789
- const auto &CSI = getUnmanagedCSI (MF, MFI.getCalleeSavedInfo () );
810
+ const auto &CSI = MFI.getCalleeSavedInfo ();
790
811
791
812
// Skip to before the restores of scalar callee-saved registers
792
813
// FIXME: assumes exactly one instruction is used to restore each
793
814
// 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 ());
797
816
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 ();
801
826
uint64_t RVVStackSize = RVFI->getRVVStackSize ();
802
827
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
+
803
871
// Restore the stack pointer using the value of the frame pointer. Only
804
872
// necessary if the stack pointer was modified, meaning the stack size is
805
873
// unknown.
@@ -810,50 +878,58 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
810
878
// normally it's just checking the variable sized object is present or not
811
879
// is enough, but we also don't preserve that at prologue/epilogue when
812
880
// 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) {
816
882
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 ());
831
885
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);
835
891
}
836
892
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) {
842
896
// Use available stack adjustment in pop instruction to deallocate stack
843
897
// space. Align the stack size down to a multiple of 16. This is needed for
844
898
// RVE.
845
899
// FIXME: Can we increase the stack size to a multiple of 16 instead?
846
900
uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
847
901
MBBI->getOperand (1 ).setImm (Spimm);
848
902
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);
849
916
}
850
917
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);
855
926
}
856
927
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
+
857
933
// Emit epilogue for shadow call stack.
858
934
emitSCSEpilogue (MF, MBB, MBBI, DL);
859
935
}
@@ -1557,6 +1633,7 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1557
1633
int FI = CS.getFrameIdx ();
1558
1634
if (FI >= 0 && MFI.getStackID (FI) == TargetStackID::ScalableVector) {
1559
1635
MCRegister BaseReg = TRI.getSubReg (CS.getReg (), RISCV::sub_vrm1_0);
1636
+
1560
1637
// If it's not a grouped vector register, it doesn't have subregister, so
1561
1638
// the base register is just itself.
1562
1639
if (BaseReg == RISCV::NoRegister)
@@ -1576,6 +1653,31 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1576
1653
}
1577
1654
}
1578
1655
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
+
1579
1681
bool RISCVFrameLowering::restoreCalleeSavedRegisters (
1580
1682
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
1581
1683
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
0 commit comments