@@ -408,6 +408,23 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
408
408
return RVVCSI;
409
409
}
410
410
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
+
411
428
void RISCVFrameLowering::adjustStackForRVV (MachineFunction &MF,
412
429
MachineBasicBlock &MBB,
413
430
MachineBasicBlock::iterator MBBI,
@@ -556,6 +573,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
556
573
// Determine the correct frame layout
557
574
determineFrameLayout (MF);
558
575
576
+ const auto &CSI = MFI.getCalleeSavedInfo ();
577
+
559
578
// If libcalls are used to spill and restore callee-saved registers, the frame
560
579
// has two sections; the opaque section managed by the libcalls, and the
561
580
// section managed by MachineFrameInfo which can also hold callee saved
@@ -581,6 +600,23 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
581
600
unsigned LibCallFrameSize =
582
601
alignTo ((STI.getXLen () / 8 ) * LibCallRegs, getStackAlign ());
583
602
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
+ }
584
620
}
585
621
586
622
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -615,23 +651,38 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
615
651
uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
616
652
FirstFrameSetup->getOperand (1 ).setImm (Spimm);
617
653
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
+ }
618
671
}
619
672
620
673
if (StackSize != 0 ) {
621
674
// Allocate space on the stack if necessary.
622
675
RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
623
676
StackOffset::getFixed (-StackSize), MachineInstr::FrameSetup,
624
677
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);
633
678
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
+ }
635
686
636
687
// The frame pointer is callee-saved, and code has been generated for us to
637
688
// save it to the stack. We need to skip over the storing of callee-saved
@@ -643,7 +694,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
643
694
644
695
// Iterate over list of callee-saved registers and emit .cfi_offset
645
696
// directives.
646
- for (const auto &Entry : CSI) {
697
+ for (const auto &Entry : getUnmanagedCSI (MF, CSI) ) {
647
698
int FrameIdx = Entry.getFrameIdx ();
648
699
if (FrameIdx >= 0 &&
649
700
MFI.getStackID (FrameIdx) == TargetStackID::ScalableVector)
@@ -758,7 +809,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
758
809
void RISCVFrameLowering::deallocateStack (MachineFunction &MF,
759
810
MachineBasicBlock &MBB,
760
811
MachineBasicBlock::iterator MBBI,
761
- const DebugLoc &DL, uint64_t StackSize,
812
+ const DebugLoc &DL, uint64_t & StackSize,
762
813
int64_t CFAOffset) const {
763
814
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
764
815
const RISCVInstrInfo *TII = STI.getInstrInfo ();
@@ -767,6 +818,7 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
767
818
768
819
RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
769
820
MachineInstr::FrameDestroy, getStackAlign ());
821
+ StackSize = 0 ;
770
822
771
823
unsigned CFIIndex =
772
824
MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , CFAOffset));
@@ -881,7 +933,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
881
933
// have vector objects in stack.
882
934
if (RestoreSPFromFP) {
883
935
assert (hasFP (MF) && " frame pointer should not have been eliminated" );
884
-
885
936
RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
886
937
StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
887
938
getStackAlign ());
@@ -908,6 +959,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
908
959
return ;
909
960
}
910
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
+
911
972
bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
912
973
MBBI->getOpcode () == RISCV::CM_POP;
913
974
if (ApplyPop) {
@@ -923,29 +984,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
923
984
deallocateStack (MF, MBB, MBBI, DL, StackSize,
924
985
/* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
925
986
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;
935
990
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
+ }
945
999
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 )
949
1012
deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
950
1013
951
1014
// Emit epilogue for shadow call stack.
@@ -1633,6 +1696,22 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
1633
1696
return true ;
1634
1697
}
1635
1698
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
+
1636
1715
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
1637
1716
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
1638
1717
MachineFunction *MF = MBB.getParent ();
@@ -1659,15 +1738,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1659
1738
// Insert the spill to the stack frame.
1660
1739
int FI = CS.getFrameIdx ();
1661
1740
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 ());
1671
1743
for (unsigned i = 0 ; i < NumRegs; ++i) {
1672
1744
unsigned CFIIndex = MF->addFrameInst (createDefCFAOffset (
1673
1745
TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset (FI) / 8 + i));
@@ -1685,15 +1757,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
1685
1757
const MachineFrameInfo &MFI = MF->getFrameInfo ();
1686
1758
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
1687
1759
const TargetInstrInfo &TII = *STI.getInstrInfo ();
1760
+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo ();
1688
1761
DebugLoc DL = MBB.findDebugLoc (MI);
1689
1762
1690
1763
const auto &RVVCSI = getRVVCalleeSavedInfo (*MF, MFI.getCalleeSavedInfo ());
1691
1764
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) {
1695
1768
unsigned CFIIndex = MF->addFrameInst (MCCFIInstruction::createRestore (
1696
- nullptr , RI->getDwarfRegNum (Reg , true )));
1769
+ nullptr , RI->getDwarfRegNum (BaseReg + i , true )));
1697
1770
BuildMI (MBB, MI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
1698
1771
.addCFIIndex (CFIIndex)
1699
1772
.setMIFlag (MachineInstr::FrameDestroy);
0 commit comments