@@ -163,6 +163,7 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
163163 .setMIFlags (MachineInstr::FrameDestroy);
164164}
165165
166+
166167// Get the ID of the libcall used for spilling and restoring callee saved
167168// registers. The ID is representative of the number of registers saved or
168169// restored by the libcall, except it is zero-indexed - ID 0 corresponds to a
@@ -408,6 +409,23 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
408409 return RVVCSI;
409410}
410411
412+ static SmallVector<CalleeSavedInfo, 8 > getPushOrLibCallsSavedInfo (const MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI) {
413+ auto *RVFI = MF.getInfo <RISCVMachineFunctionInfo>();
414+
415+ SmallVector<CalleeSavedInfo, 8 > PushPopOrLibCallsCSI;
416+ if (!RVFI->useSaveRestoreLibCalls (MF) && !RVFI->isPushable (MF))
417+ return PushPopOrLibCallsCSI;
418+
419+ for (auto &CS : CSI) {
420+ const auto *FII = llvm::find_if (
421+ FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg (); });
422+ if (FII != std::end (FixedCSRFIMap))
423+ PushPopOrLibCallsCSI.push_back (CS);
424+ }
425+
426+ return PushPopOrLibCallsCSI;
427+ }
428+
411429void RISCVFrameLowering::adjustStackForRVV (MachineFunction &MF,
412430 MachineBasicBlock &MBB,
413431 MachineBasicBlock::iterator MBBI,
@@ -581,6 +599,25 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
581599 unsigned LibCallFrameSize =
582600 alignTo ((STI.getXLen () / 8 ) * LibCallRegs, getStackAlign ());
583601 RVFI->setLibCallStackSize (LibCallFrameSize);
602+
603+ unsigned CFIIndex = MF.addFrameInst (
604+ MCCFIInstruction::cfiDefCfaOffset (nullptr , LibCallFrameSize));
605+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
606+ .addCFIIndex (CFIIndex)
607+ .setMIFlag (MachineInstr::FrameSetup);
608+
609+ const auto &CSI = MFI.getCalleeSavedInfo ();
610+ auto PushCSI = getPushOrLibCallsSavedInfo (MF, CSI);
611+ for (const auto &Entry : PushCSI) {
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+ }
584621 }
585622
586623 // FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -615,21 +652,40 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
615652 uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
616653 FirstFrameSetup->getOperand (1 ).setImm (Spimm);
617654 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+ const auto &CSI = MFI.getCalleeSavedInfo ();
663+ auto PushCSI = getPushOrLibCallsSavedInfo (MF, CSI);
664+ for (const auto &Entry : PushCSI) {
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+ }
618674 }
619675
620676 if (StackSize != 0 ) {
621677 // Allocate space on the stack if necessary.
622678 RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
623679 StackOffset::getFixed (-StackSize), MachineInstr::FrameSetup,
624680 getStackAlign ());
625- }
626681
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);
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+ }
633689
634690 const auto &CSI = MFI.getCalleeSavedInfo ();
635691
@@ -643,11 +699,11 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
643699
644700 // Iterate over list of callee-saved registers and emit .cfi_offset
645701 // directives.
646- for (const auto &Entry : CSI) {
702+ for (const auto &Entry : getUnmanagedCSI (MF, CSI) ) {
647703 int FrameIdx = Entry.getFrameIdx ();
648- if (FrameIdx >= 0 &&
704+ /* if (FrameIdx >= 0 &&
649705 MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector)
650- continue ;
706+ continue;*/
651707
652708 int64_t Offset = MFI.getObjectOffset (FrameIdx);
653709 Register Reg = Entry.getReg ();
@@ -758,7 +814,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
758814void RISCVFrameLowering::deallocateStack (MachineFunction &MF,
759815 MachineBasicBlock &MBB,
760816 MachineBasicBlock::iterator MBBI,
761- const DebugLoc &DL, uint64_t StackSize,
817+ const DebugLoc &DL, uint64_t & StackSize,
762818 int64_t CFAOffset) const {
763819 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
764820 const RISCVInstrInfo *TII = STI.getInstrInfo ();
@@ -767,6 +823,7 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
767823
768824 RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
769825 MachineInstr::FrameDestroy, getStackAlign ());
826+ StackSize = 0 ;
770827
771828 unsigned CFIIndex =
772829 MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , CFAOffset));
@@ -807,12 +864,12 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
807864 --MBBI;
808865 }
809866
810- const auto &CSI = MFI.getCalleeSavedInfo ();
867+ const auto &UnmanagedCSI = getUnmanagedCSI (MF, MFI.getCalleeSavedInfo () );
811868
812869 // Skip to before the restores of scalar callee-saved registers
813870 // FIXME: assumes exactly one instruction is used to restore each
814871 // callee-saved register.
815- auto LastFrameDestroy = std::prev (MBBI, getUnmanagedCSI (MF, CSI) .size ());
872+ auto LastFrameDestroy = std::prev (MBBI, UnmanagedCSI .size ());
816873
817874 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount (MF);
818875 uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
@@ -881,7 +938,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
881938 // have vector objects in stack.
882939 if (RestoreSPFromFP) {
883940 assert (hasFP (MF) && " frame pointer should not have been eliminated" );
884-
885941 RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
886942 StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
887943 getStackAlign ());
@@ -895,7 +951,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
895951 .setMIFlag (MachineInstr::FrameDestroy);
896952 }
897953
898- if (getLibCallID (MF, CSI ) + 1 ) {
954+ if (getLibCallID (MF, MFI. getCalleeSavedInfo () ) + 1 ) {
899955 // tail __riscv_restore_[0-12] instruction is considered as a terminator,
900956 // therefor it is unnecessary to place any CFI instructions after it. Just
901957 // deallocate stack if needed and return.
@@ -908,6 +964,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
908964 return ;
909965 }
910966
967+ // Recover callee-saved registers.
968+ for (const auto &Entry : UnmanagedCSI) {
969+ Register Reg = Entry.getReg ();
970+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createRestore (
971+ nullptr , RI->getDwarfRegNum (Reg, true )));
972+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
973+ .addCFIIndex (CFIIndex)
974+ .setMIFlag (MachineInstr::FrameDestroy);
975+ }
976+
911977 bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
912978 MBBI->getOpcode () == RISCV::CM_POP;
913979 if (ApplyPop) {
@@ -921,31 +987,44 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
921987
922988 if (StackSize != 0 )
923989 deallocateStack (MF, MBB, MBBI, DL, StackSize,
924- /* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
990+ /* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
991+
992+ auto NextI = next_nodbg (MBBI, MBB.end ());
993+ if (NextI != MBB.end () && NextI->getOpcode () != RISCV::PseudoRET) {
994+ ++MBBI;
995+
996+ unsigned PushedRegNum = RVFI->getRVPushRegs ();
997+ for (unsigned i = 0 ; i < PushedRegNum; i++) {
998+ Register Reg = FixedCSRFIMap[i].first ;
999+ unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createRestore (
1000+ nullptr , RI->getDwarfRegNum (Reg, true )));
1001+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
1002+ .addCFIIndex (CFIIndex)
1003+ .setMIFlag (MachineInstr::FrameDestroy);
1004+ }
9251005
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);
1006+ // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA offset
1007+ // should be a zero.
1008+ unsigned CFIIndex =
1009+ MF. addFrameInst ( MCCFIInstruction::cfiDefCfaOffset ( nullptr , 0 ));
1010+ BuildMI (MBB, MBBI, DL, TII-> get (TargetOpcode::CFI_INSTRUCTION))
1011+ . addCFIIndex (CFIIndex )
1012+ . setMIFlag (MachineInstr::FrameDestroy);
1013+ }
9341014 }
935-
1015+ /*
9361016 // Recover callee-saved registers.
937- for (const auto &Entry : CSI ) {
1017+ for (const auto &Entry : UnmanagedCSI ) {
9381018 Register Reg = Entry.getReg();
9391019 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
9401020 nullptr, RI->getDwarfRegNum(Reg, true)));
9411021 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
9421022 .addCFIIndex(CFIIndex)
9431023 .setMIFlag(MachineInstr::FrameDestroy);
9441024 }
945-
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)
1025+ */
1026+ // Deallocate stack if StackSize isn't a zero yet
1027+ if (StackSize != 0 )
9491028 deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
9501029
9511030 // Emit epilogue for shadow call stack.
@@ -1633,6 +1712,39 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
16331712 return true ;
16341713}
16351714
1715+ /* void RISCVFrameLowering::emitPopCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool HasFP) const {
1716+ MachineFunction *MF = MBB.getParent();
1717+ RISCVMachineFunctionInfo *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
1718+
1719+ unsigned PushedRegNum = RVFI->getRVPushRegs();
1720+ for (unsigned idx = 0; idx < PushedRegNum; ++idx) {
1721+ Register Reg = MCOperand::createReg(FixedCSRFIMap[idx].first) ;
1722+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
1723+ nullptr, RI->getDwarfRegNum(Reg, true)));
1724+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
1725+ .addCFIIndex(CFIIndex)
1726+ .setMIFlag(MachineInstr::FrameDestroy);
1727+ }
1728+ */
1729+
1730+
1731+ static unsigned getCaleeSavedRVVNumRegs (const Register &BaseReg) {
1732+ return RISCV::VRRegClass.contains (BaseReg) ? 1
1733+ : RISCV::VRM2RegClass.contains (BaseReg) ? 2
1734+ : RISCV::VRM4RegClass.contains (BaseReg) ? 4
1735+ : 8 ;
1736+ }
1737+
1738+ static MCRegister getRVVBaseRegister (const RISCVRegisterInfo &TRI, const Register &Reg) {
1739+ MCRegister BaseReg = TRI.getSubReg (Reg, RISCV::sub_vrm1_0);
1740+ // If it's not a grouped vector register, it doesn't have subregister, so
1741+ // the base register is just itself.
1742+ if (BaseReg == RISCV::NoRegister)
1743+ BaseReg = Reg;
1744+ return BaseReg;
1745+ }
1746+
1747+
16361748void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
16371749 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
16381750 MachineFunction *MF = MBB.getParent ();
@@ -1659,15 +1771,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16591771 // Insert the spill to the stack frame.
16601772 int FI = CS.getFrameIdx ();
16611773 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 ;
1774+ MCRegister BaseReg = getRVVBaseRegister (TRI, CS.getReg ());
1775+ unsigned NumRegs = getCaleeSavedRVVNumRegs (CS.getReg ());
16711776 for (unsigned i = 0 ; i < NumRegs; ++i) {
16721777 unsigned CFIIndex = MF->addFrameInst (createDefCFAOffset (
16731778 TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset (FI) / 8 + i));
@@ -1685,15 +1790,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
16851790 const MachineFrameInfo &MFI = MF->getFrameInfo ();
16861791 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
16871792 const TargetInstrInfo &TII = *STI.getInstrInfo ();
1793+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo ();
16881794 DebugLoc DL = MBB.findDebugLoc (MI);
16891795
16901796 const auto &RVVCSI = getRVVCalleeSavedInfo (*MF, MFI.getCalleeSavedInfo ());
16911797 for (auto &CS : RVVCSI) {
1692- int FI = CS.getFrameIdx ( );
1693- if (FI >= 0 && MFI. getStackID (FI) == TargetStackID::ScalableVector) {
1694- Register Reg = CS. getReg ();
1798+ MCRegister BaseReg = getRVVBaseRegister (TRI, CS.getReg () );
1799+ unsigned NumRegs = getCaleeSavedRVVNumRegs (CS. getReg ());
1800+ for ( unsigned i = 0 ; i < NumRegs; ++i) {
16951801 unsigned CFIIndex = MF->addFrameInst (MCCFIInstruction::createRestore (
1696- nullptr , RI->getDwarfRegNum (Reg , true )));
1802+ nullptr , RI->getDwarfRegNum (BaseReg + i , true )));
16971803 BuildMI (MBB, MI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
16981804 .addCFIIndex (CFIIndex)
16991805 .setMIFlag (MachineInstr::FrameDestroy);
0 commit comments