@@ -413,6 +413,25 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
413
413
return RVVCSI;
414
414
}
415
415
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
+
416
435
void RISCVFrameLowering::adjustStackForRVV (MachineFunction &MF,
417
436
MachineBasicBlock &MBB,
418
437
MachineBasicBlock::iterator MBBI,
@@ -557,6 +576,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
557
576
// Determine the correct frame layout
558
577
determineFrameLayout (MF);
559
578
579
+ const auto &CSI = MFI.getCalleeSavedInfo ();
580
+
560
581
// If libcalls are used to spill and restore callee-saved registers, the frame
561
582
// has two sections; the opaque section managed by the libcalls, and the
562
583
// section managed by MachineFrameInfo which can also hold callee saved
@@ -582,6 +603,23 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
582
603
unsigned LibCallFrameSize =
583
604
alignTo ((STI.getXLen () / 8 ) * LibCallRegs, getStackAlign ());
584
605
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
+ }
585
623
}
586
624
587
625
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -616,23 +654,38 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
616
654
uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
617
655
FirstFrameSetup->getOperand (1 ).setImm (Spimm);
618
656
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
+ }
619
674
}
620
675
621
676
if (StackSize != 0 ) {
622
677
// Allocate space on the stack if necessary.
623
678
RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
624
679
StackOffset::getFixed (-StackSize), MachineInstr::FrameSetup,
625
680
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);
634
681
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
+ }
636
689
637
690
// The frame pointer is callee-saved, and code has been generated for us to
638
691
// save it to the stack. We need to skip over the storing of callee-saved
@@ -644,7 +697,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
644
697
645
698
// Iterate over list of callee-saved registers and emit .cfi_offset
646
699
// directives.
647
- for (const auto &Entry : CSI) {
700
+ for (const auto &Entry : getUnmanagedCSI (MF, CSI) ) {
648
701
int FrameIdx = Entry.getFrameIdx ();
649
702
if (FrameIdx >= 0 &&
650
703
MFI.getStackID (FrameIdx) == TargetStackID::ScalableVector)
@@ -759,19 +812,29 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
759
812
void RISCVFrameLowering::deallocateStack (MachineFunction &MF,
760
813
MachineBasicBlock &MBB,
761
814
MachineBasicBlock::iterator MBBI,
762
- const DebugLoc &DL, uint64_t StackSize,
815
+ const DebugLoc &DL,
816
+ uint64_t &StackSize,
763
817
int64_t CFAOffset) const {
764
818
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
819
+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
765
820
766
821
RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
767
822
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);
768
830
}
769
831
770
832
void RISCVFrameLowering::emitEpilogue (MachineFunction &MF,
771
833
MachineBasicBlock &MBB) const {
772
834
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
773
835
MachineFrameInfo &MFI = MF.getFrameInfo ();
774
836
auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
837
+ const RISCVInstrInfo *TII = STI.getInstrInfo ();
775
838
776
839
// All calls are tail calls in GHC calling conv, and functions have no
777
840
// prologue/epilogue.
@@ -814,15 +877,25 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
814
877
RVFI->getVarArgsSaveSize ();
815
878
uint64_t RVVStackSize = RVFI->getRVVStackSize ();
816
879
817
- bool RestoreFP = RI->hasStackRealignment (MF) || MFI.hasVarSizedObjects () ||
818
- !hasReservedCallFrame (MF);
819
-
880
+ bool RestoreSPFromFP = RI->hasStackRealignment (MF) ||
881
+ MFI.hasVarSizedObjects () || !hasReservedCallFrame (MF);
820
882
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 )
824
886
adjustStackForRVV (MF, MBB, LastFrameDestroy, DL, RVVStackSize,
825
887
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);
826
899
}
827
900
828
901
if (FirstSPAdjustAmount) {
@@ -831,12 +904,21 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
831
904
assert (SecondSPAdjustAmount > 0 &&
832
905
" SecondSPAdjustAmount should be greater than zero" );
833
906
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 )
837
910
RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, SPReg,
838
911
StackOffset::getFixed (SecondSPAdjustAmount),
839
912
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
+ }
840
922
}
841
923
842
924
// Restore the stack pointer using the value of the frame pointer. Only
@@ -849,14 +931,44 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
849
931
// normally it's just checking the variable sized object is present or not
850
932
// is enough, but we also don't preserve that at prologue/epilogue when
851
933
// have vector objects in stack.
852
- if (RestoreFP ) {
934
+ if (RestoreSPFromFP ) {
853
935
assert (hasFP (MF) && " frame pointer should not have been eliminated" );
854
-
855
936
RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
856
937
StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
857
938
getStackAlign ());
858
939
}
859
940
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
+
860
972
bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
861
973
MBBI->getOpcode () == RISCV::CM_POP;
862
974
if (ApplyPop) {
@@ -872,12 +984,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
872
984
deallocateStack (MF, MBB, MBBI, DL, StackSize,
873
985
/* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
874
986
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
+ }
876
1008
}
877
1009
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 )
881
1012
deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
882
1013
883
1014
// Emit epilogue for shadow call stack.
@@ -1564,6 +1695,23 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
1564
1695
return true ;
1565
1696
}
1566
1697
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
+
1567
1715
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
1568
1716
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
1569
1717
MachineFunction *MF = MBB.getParent ();
@@ -1590,15 +1738,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1590
1738
// Insert the spill to the stack frame.
1591
1739
int FI = CS.getFrameIdx ();
1592
1740
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 ());
1602
1743
for (unsigned i = 0 ; i < NumRegs; ++i) {
1603
1744
unsigned CFIIndex = MF->addFrameInst (createDefCFAOffset (
1604
1745
TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset (FI) / 8 + i));
@@ -1610,6 +1751,29 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1610
1751
}
1611
1752
}
1612
1753
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
+
1613
1777
bool RISCVFrameLowering::restoreCalleeSavedRegisters (
1614
1778
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
1615
1779
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
0 commit comments