[llvm] [llvm] Support multiple save/restore points in mir (PR #119357)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 18 03:53:16 PDT 2025
================
@@ -478,12 +478,65 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineRegisterInfo &MRI = MF.getRegInfo();
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
DebugLoc DL = MI.getDebugLoc();
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
Register FrameReg;
StackOffset Offset =
getFrameLowering(MF)->getFrameIndexReference(MF, FrameIndex, FrameReg);
+
+ const auto &CSI =
+ getFrameLowering(MF)->getUnmanagedCSI(MF, MFI.getCalleeSavedInfo());
+
+ if (!CSI.empty()) {
+ int MinCSFI = CSI.front().getFrameIdx();
+ int MaxCSFI = CSI.back().getFrameIdx();
+
+ // If our FrameIndex is CSI FrameIndex we in some cases need additional
+ // adjustment
+ if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) {
+ MachineBasicBlock *SpilledIn = nullptr;
+ MachineBasicBlock *RestoredIn = nullptr;
+ auto It = std::find_if(CSI.begin(), CSI.end(), [FrameIndex](auto &CS) {
+ return CS.getFrameIdx() == FrameIndex;
+ });
+
+ assert(It != CSI.end() &&
+ "Did't find CalleeSavedInfo for CalleeSaved FrameIndex");
+
+ assert(!(MI.mayLoad() && MI.mayStore()) &&
+ "Instruction with frame index operand may load and store "
+ "simultaneously!");
+
+ if (MI.mayStore())
+ SpilledIn = MFI.findSpilledIn(*It);
+ else if (MI.mayLoad())
+ RestoredIn = MFI.findRestoredIn(*It);
+ else
+ llvm_unreachable(
+ "Instruction with frame index operand neither loads nor stores!");
+
+ bool SpilledRestoredInPrologEpilog = true;
+ // If we didn't managed to find NCD (NCPD) for the list of Save (Restore)
+ // blocks, spill (restore) will be unconditionally in Prolog (Epilog)
+ if (MI.mayStore() && MFI.getProlog())
+ SpilledRestoredInPrologEpilog = SpilledIn == MFI.getProlog();
+ else if (MI.mayLoad() && MFI.getEpilog())
+ SpilledRestoredInPrologEpilog = RestoredIn == MFI.getEpilog();
+
+ // For spills/restores performed not in Prolog/Epilog we need to add full
+ // SP offset, despite SPAdjusment optimization, because at the end of
+ // Prolog or at the start of Epilog SP has maximum offset
+ uint64_t FirstSPAdjustAmount =
+ getFrameLowering(MF)->getFirstSPAdjustAmount(MF);
+ if (FirstSPAdjustAmount && !SpilledRestoredInPrologEpilog)
----------------
arsenm wrote:
Braces
https://github.com/llvm/llvm-project/pull/119357
More information about the llvm-commits
mailing list