@@ -413,6 +413,23 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
413
413
return RVVCSI;
414
414
}
415
415
416
+ static SmallVector<CalleeSavedInfo, 8 > getPushOrLibCallsSavedInfo (const MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI) {
417
+ auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
418
+
419
+ SmallVector<CalleeSavedInfo, 8 > PushPopOrLibCallsCSI;
420
+ if (!RVFI->useSaveRestoreLibCalls (MF) && !RVFI->isPushable (MF))
421
+ return PushPopOrLibCallsCSI;
422
+
423
+ for (auto &CS : CSI) {
424
+ const auto *FII = llvm::find_if (
425
+ FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg (); });
426
+ if (FII != std::end (FixedCSRFIMap))
427
+ PushPopOrLibCallsCSI.push_back (CS);
428
+ }
429
+
430
+ return PushPopOrLibCallsCSI;
431
+ }
432
+
416
433
void RISCVFrameLowering::adjustStackForRVV (MachineFunction &MF,
417
434
MachineBasicBlock &MBB,
418
435
MachineBasicBlock::iterator MBBI,
@@ -557,6 +574,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
557
574
// Determine the correct frame layout
558
575
determineFrameLayout (MF);
559
576
577
+ const auto &CSI = MFI.getCalleeSavedInfo ();
578
+
560
579
// If libcalls are used to spill and restore callee-saved registers, the frame
561
580
// has two sections; the opaque section managed by the libcalls, and the
562
581
// section managed by MachineFrameInfo which can also hold callee saved
@@ -582,6 +601,23 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
582
601
unsigned LibCallFrameSize =
583
602
alignTo ((STI.getXLen () / 8 ) * LibCallRegs, getStackAlign ());
584
603
RVFI->setLibCallStackSize (LibCallFrameSize);
604
+
605
+ unsigned CFIIndex = MF.addFrameInst (
606
+ MCCFIInstruction::cfiDefCfaOffset (nullptr , LibCallFrameSize));
607
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
608
+ .addCFIIndex (CFIIndex)
609
+ .setMIFlag (MachineInstr::FrameSetup);
610
+
611
+ for (const auto &Entry : getPushOrLibCallsSavedInfo (MF, CSI)) {
612
+ int FrameIdx = Entry.getFrameIdx ();
613
+ int64_t Offset = MFI.getObjectOffset (FrameIdx);
614
+ Register Reg = Entry.getReg ();
615
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
616
+ nullptr , RI->getDwarfRegNum (Reg, true ), Offset));
617
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
618
+ .addCFIIndex (CFIIndex)
619
+ .setMIFlag (MachineInstr::FrameSetup);
620
+ }
585
621
}
586
622
587
623
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -616,23 +652,38 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
616
652
uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
617
653
FirstFrameSetup->getOperand (1 ).setImm (Spimm);
618
654
StackSize -= Spimm;
655
+
656
+ unsigned CFIIndex = MF.addFrameInst (
657
+ MCCFIInstruction::cfiDefCfaOffset (nullptr , RealStackSize - StackSize));
658
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
659
+ .addCFIIndex (CFIIndex)
660
+ .setMIFlag (MachineInstr::FrameSetup);
661
+
662
+ for (const auto &Entry : getPushOrLibCallsSavedInfo (MF, CSI)) {
663
+ int FrameIdx = Entry.getFrameIdx ();
664
+ int64_t Offset = MFI.getObjectOffset (FrameIdx);
665
+ Register Reg = Entry.getReg ();
666
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
667
+ nullptr , RI->getDwarfRegNum (Reg, true ), Offset));
668
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
669
+ .addCFIIndex (CFIIndex)
670
+ .setMIFlag (MachineInstr::FrameSetup);
671
+ }
619
672
}
620
673
621
674
if (StackSize != 0 ) {
622
675
// Allocate space on the stack if necessary.
623
676
RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
624
677
StackOffset::getFixed (-StackSize), MachineInstr::FrameSetup,
625
678
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
679
635
- const auto &CSI = MFI.getCalleeSavedInfo ();
680
+ // Emit ".cfi_def_cfa_offset RealStackSize"
681
+ unsigned CFIIndex = MF.addFrameInst (
682
+ MCCFIInstruction::cfiDefCfaOffset (nullptr , RealStackSize));
683
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
684
+ .addCFIIndex (CFIIndex)
685
+ .setMIFlag (MachineInstr::FrameSetup);
686
+ }
636
687
637
688
// The frame pointer is callee-saved, and code has been generated for us to
638
689
// save it to the stack. We need to skip over the storing of callee-saved
@@ -644,7 +695,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
644
695
645
696
// Iterate over list of callee-saved registers and emit .cfi_offset
646
697
// directives.
647
- for (const auto &Entry : CSI) {
698
+ for (const auto &Entry : getUnmanagedCSI (MF, CSI) ) {
648
699
int FrameIdx = Entry.getFrameIdx ();
649
700
if (FrameIdx >= 0 &&
650
701
MFI.getStackID (FrameIdx) == TargetStackID::ScalableVector)
@@ -759,13 +810,14 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
759
810
void RISCVFrameLowering::deallocateStack (MachineFunction &MF,
760
811
MachineBasicBlock &MBB,
761
812
MachineBasicBlock::iterator MBBI,
762
- const DebugLoc &DL, uint64_t StackSize,
813
+ const DebugLoc &DL, uint64_t & StackSize,
763
814
int64_t CFAOffset) const {
764
815
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
765
816
const RISCVInstrInfo *TII = STI.getInstrInfo ();
766
817
767
818
RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
768
819
MachineInstr::FrameDestroy, getStackAlign ());
820
+ StackSize = 0 ;
769
821
770
822
unsigned CFIIndex =
771
823
MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , CFAOffset));
@@ -878,7 +930,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
878
930
// have vector objects in stack.
879
931
if (RestoreSPFromFP) {
880
932
assert (hasFP (MF) && " frame pointer should not have been eliminated" );
881
-
882
933
RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
883
934
StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
884
935
getStackAlign ());
@@ -905,6 +956,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
905
956
return ;
906
957
}
907
958
959
+ // Recover callee-saved registers.
960
+ for (const auto &Entry : getUnmanagedCSI (MF, CSI)) {
961
+ Register Reg = Entry.getReg ();
962
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createRestore (
963
+ nullptr , RI->getDwarfRegNum (Reg, true )));
964
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
965
+ .addCFIIndex (CFIIndex)
966
+ .setMIFlag (MachineInstr::FrameDestroy);
967
+ }
968
+
908
969
bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
909
970
MBBI->getOpcode () == RISCV::CM_POP;
910
971
if (ApplyPop) {
@@ -920,29 +981,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
920
981
deallocateStack (MF, MBB, MBBI, DL, StackSize,
921
982
/* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
922
983
923
- ++MBBI;
924
- // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
925
- // should be a zero.
926
- unsigned CFIIndex =
927
- MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , 0 ));
928
- BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
929
- .addCFIIndex (CFIIndex)
930
- .setMIFlag (MachineInstr::FrameDestroy);
931
- }
984
+ auto NextI = next_nodbg (MBBI, MBB.end ());
985
+ if (NextI == MBB.end () || NextI->getOpcode () != RISCV::PseudoRET) {
986
+ ++MBBI;
932
987
933
- // Recover callee-saved registers.
934
- for (const auto &Entry : CSI) {
935
- Register Reg = Entry.getReg ();
936
- unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createRestore (
937
- nullptr , RI->getDwarfRegNum (Reg, true )));
938
- BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
939
- .addCFIIndex (CFIIndex)
940
- .setMIFlag (MachineInstr::FrameDestroy);
941
- }
988
+ for (const auto &Entry : getPushOrLibCallsSavedInfo (MF, CSI)) {
989
+ Register Reg = Entry.getReg ();
990
+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createRestore (
991
+ nullptr , RI->getDwarfRegNum (Reg, true )));
992
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
993
+ .addCFIIndex (CFIIndex)
994
+ .setMIFlag (MachineInstr::FrameDestroy);
995
+ }
942
996
943
- // Deallocate stack if we didn't already do it during cm.pop handling and
944
- // StackSize isn't a zero
945
- if (StackSize != 0 && !ApplyPop)
997
+ // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
998
+ // should be a zero.
999
+ unsigned CFIIndex =
1000
+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , 0 ));
1001
+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
1002
+ .addCFIIndex (CFIIndex)
1003
+ .setMIFlag (MachineInstr::FrameDestroy);
1004
+ }
1005
+ }
1006
+
1007
+ // Deallocate stack if StackSize isn't a zero yet
1008
+ if (StackSize != 0 )
946
1009
deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
947
1010
948
1011
// Emit epilogue for shadow call stack.
@@ -1629,6 +1692,22 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
1629
1692
return true ;
1630
1693
}
1631
1694
1695
+ static unsigned getCaleeSavedRVVNumRegs (const Register &BaseReg) {
1696
+ return RISCV::VRRegClass.contains (BaseReg) ? 1
1697
+ : RISCV::VRM2RegClass.contains (BaseReg) ? 2
1698
+ : RISCV::VRM4RegClass.contains (BaseReg) ? 4
1699
+ : 8 ;
1700
+ }
1701
+
1702
+ static MCRegister getRVVBaseRegister (const RISCVRegisterInfo &TRI, const Register &Reg) {
1703
+ MCRegister BaseReg = TRI.getSubReg (Reg, RISCV::sub_vrm1_0);
1704
+ // If it's not a grouped vector register, it doesn't have subregister, so
1705
+ // the base register is just itself.
1706
+ if (BaseReg == RISCV::NoRegister)
1707
+ BaseReg = Reg;
1708
+ return BaseReg;
1709
+ }
1710
+
1632
1711
void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
1633
1712
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
1634
1713
MachineFunction *MF = MBB.getParent ();
@@ -1655,15 +1734,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
1655
1734
// Insert the spill to the stack frame.
1656
1735
int FI = CS.getFrameIdx ();
1657
1736
if (FI >= 0 && MFI.getStackID (FI) == TargetStackID::ScalableVector) {
1658
- MCRegister BaseReg = TRI.getSubReg (CS.getReg (), RISCV::sub_vrm1_0);
1659
- // If it's not a grouped vector register, it doesn't have subregister, so
1660
- // the base register is just itself.
1661
- if (BaseReg == RISCV::NoRegister)
1662
- BaseReg = CS.getReg ();
1663
- unsigned NumRegs = RISCV::VRRegClass.contains (CS.getReg ()) ? 1
1664
- : RISCV::VRM2RegClass.contains (CS.getReg ()) ? 2
1665
- : RISCV::VRM4RegClass.contains (CS.getReg ()) ? 4
1666
- : 8 ;
1737
+ MCRegister BaseReg = getRVVBaseRegister (TRI, CS.getReg ());
1738
+ unsigned NumRegs = getCaleeSavedRVVNumRegs (CS.getReg ());
1667
1739
for (unsigned i = 0 ; i < NumRegs; ++i) {
1668
1740
unsigned CFIIndex = MF->addFrameInst (createDefCFAOffset (
1669
1741
TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset (FI) / 8 + i));
@@ -1681,15 +1753,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
1681
1753
const MachineFrameInfo &MFI = MF->getFrameInfo ();
1682
1754
const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
1683
1755
const TargetInstrInfo &TII = *STI.getInstrInfo ();
1756
+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo ();
1684
1757
DebugLoc DL = MBB.findDebugLoc (MI);
1685
1758
1686
1759
const auto &RVVCSI = getRVVCalleeSavedInfo (*MF, MFI.getCalleeSavedInfo ());
1687
1760
for (auto &CS : RVVCSI) {
1688
- int FI = CS.getFrameIdx ( );
1689
- if (FI >= 0 && MFI. getStackID (FI) == TargetStackID::ScalableVector) {
1690
- Register Reg = CS. getReg ();
1761
+ MCRegister BaseReg = getRVVBaseRegister (TRI, CS.getReg () );
1762
+ unsigned NumRegs = getCaleeSavedRVVNumRegs (CS. getReg ());
1763
+ for ( unsigned i = 0 ; i < NumRegs; ++i) {
1691
1764
unsigned CFIIndex = MF->addFrameInst (MCCFIInstruction::createRestore (
1692
- nullptr , RI->getDwarfRegNum (Reg , true )));
1765
+ nullptr , RI->getDwarfRegNum (BaseReg + i , true )));
1693
1766
BuildMI (MBB, MI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
1694
1767
.addCFIIndex (CFIIndex)
1695
1768
.setMIFlag (MachineInstr::FrameDestroy);
0 commit comments