@@ -413,6 +413,23 @@ getRVVCalleeSavedInfo(const MachineFunction &MF,
413413 return RVVCSI;
414414}
415415
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+
416433void RISCVFrameLowering::adjustStackForRVV (MachineFunction &MF,
417434 MachineBasicBlock &MBB,
418435 MachineBasicBlock::iterator MBBI,
@@ -557,6 +574,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
557574 // Determine the correct frame layout
558575 determineFrameLayout (MF);
559576
577+ const auto &CSI = MFI.getCalleeSavedInfo ();
578+
560579 // If libcalls are used to spill and restore callee-saved registers, the frame
561580 // has two sections; the opaque section managed by the libcalls, and the
562581 // section managed by MachineFrameInfo which can also hold callee saved
@@ -582,6 +601,23 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
582601 unsigned LibCallFrameSize =
583602 alignTo ((STI.getXLen () / 8 ) * LibCallRegs, getStackAlign ());
584603 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+ }
585621 }
586622
587623 // FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -616,23 +652,38 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
616652 uint64_t Spimm = std::min (alignDown (StackSize, 16 ), (uint64_t )48 );
617653 FirstFrameSetup->getOperand (1 ).setImm (Spimm);
618654 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+ }
619672 }
620673
621674 if (StackSize != 0 ) {
622675 // Allocate space on the stack if necessary.
623676 RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
624677 StackOffset::getFixed (-StackSize), MachineInstr::FrameSetup,
625678 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);
634679
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+ }
636687
637688 // The frame pointer is callee-saved, and code has been generated for us to
638689 // save it to the stack. We need to skip over the storing of callee-saved
@@ -644,7 +695,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
644695
645696 // Iterate over list of callee-saved registers and emit .cfi_offset
646697 // directives.
647- for (const auto &Entry : CSI) {
698+ for (const auto &Entry : getUnmanagedCSI (MF, CSI) ) {
648699 int FrameIdx = Entry.getFrameIdx ();
649700 if (FrameIdx >= 0 &&
650701 MFI.getStackID (FrameIdx) == TargetStackID::ScalableVector)
@@ -759,13 +810,14 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
759810void RISCVFrameLowering::deallocateStack (MachineFunction &MF,
760811 MachineBasicBlock &MBB,
761812 MachineBasicBlock::iterator MBBI,
762- const DebugLoc &DL, uint64_t StackSize,
813+ const DebugLoc &DL, uint64_t & StackSize,
763814 int64_t CFAOffset) const {
764815 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
765816 const RISCVInstrInfo *TII = STI.getInstrInfo ();
766817
767818 RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (StackSize),
768819 MachineInstr::FrameDestroy, getStackAlign ());
820+ StackSize = 0 ;
769821
770822 unsigned CFIIndex =
771823 MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , CFAOffset));
@@ -878,7 +930,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
878930 // have vector objects in stack.
879931 if (RestoreSPFromFP) {
880932 assert (hasFP (MF) && " frame pointer should not have been eliminated" );
881-
882933 RI->adjustReg (MBB, LastFrameDestroy, DL, SPReg, FPReg,
883934 StackOffset::getFixed (-FPOffset), MachineInstr::FrameDestroy,
884935 getStackAlign ());
@@ -905,6 +956,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
905956 return ;
906957 }
907958
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+
908969 bool ApplyPop = RVFI->isPushable (MF) && MBBI != MBB.end () &&
909970 MBBI->getOpcode () == RISCV::CM_POP;
910971 if (ApplyPop) {
@@ -920,29 +981,31 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
920981 deallocateStack (MF, MBB, MBBI, DL, StackSize,
921982 /* stack_adj of cm.pop instr*/ RealStackSize - StackSize);
922983
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;
932987
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+ }
942996
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 )
9461009 deallocateStack (MF, MBB, MBBI, DL, StackSize, 0 );
9471010
9481011 // Emit epilogue for shadow call stack.
@@ -1629,6 +1692,22 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
16291692 return true ;
16301693}
16311694
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+
16321711void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI (
16331712 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, bool HasFP) const {
16341713 MachineFunction *MF = MBB.getParent ();
@@ -1655,15 +1734,8 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
16551734 // Insert the spill to the stack frame.
16561735 int FI = CS.getFrameIdx ();
16571736 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 ());
16671739 for (unsigned i = 0 ; i < NumRegs; ++i) {
16681740 unsigned CFIIndex = MF->addFrameInst (createDefCFAOffset (
16691741 TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset (FI) / 8 + i));
@@ -1681,15 +1753,16 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
16811753 const MachineFrameInfo &MFI = MF->getFrameInfo ();
16821754 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
16831755 const TargetInstrInfo &TII = *STI.getInstrInfo ();
1756+ const RISCVRegisterInfo &TRI = *STI.getRegisterInfo ();
16841757 DebugLoc DL = MBB.findDebugLoc (MI);
16851758
16861759 const auto &RVVCSI = getRVVCalleeSavedInfo (*MF, MFI.getCalleeSavedInfo ());
16871760 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) {
16911764 unsigned CFIIndex = MF->addFrameInst (MCCFIInstruction::createRestore (
1692- nullptr , RI->getDwarfRegNum (Reg , true )));
1765+ nullptr , RI->getDwarfRegNum (BaseReg + i , true )));
16931766 BuildMI (MBB, MI, DL, TII.get (TargetOpcode::CFI_INSTRUCTION))
16941767 .addCFIIndex (CFIIndex)
16951768 .setMIFlag (MachineInstr::FrameDestroy);
0 commit comments