[llvm] [Draft] Support save/restore point splitting in shrink-wrap (PR #119359)
dong jianqiang via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 18 05:32:31 PDT 2025
================
@@ -811,9 +975,86 @@ static bool giveUpWithRemarks(MachineOptimizationRemarkEmitter *ORE,
return false;
}
+void ShrinkWrap::setupSaveRestorePoints(MachineFunction &MF) {
+ for (unsigned Reg : getTargetCSRList(MF)) {
+ auto [Save, Restore] = SavedRegs[Reg];
+ if (SavedRegs.contains(Reg) && Save && Restore)
+ continue;
+
+ SavePoints.insertReg(Reg, &MF.front(), SaveBlocks);
+ for (MachineBasicBlock &MBB : MF) {
+ if (MBB.isEHFuncletEntry())
+ SavePoints.insertReg(Reg, &MBB, SaveBlocks);
+ if (MBB.isReturnBlock())
+ RestorePoints.insertReg(Reg, &MBB, RestoreBlocks);
+ }
+ }
+
+ for (auto [Reg, SaveRestoreBlocks] : SavedRegs) {
+ auto [Save, Restore] = SaveRestoreBlocks;
+ if (Save && Restore) {
+ SavePoints.insertReg(Reg, Save, SaveBlocks);
+ if (!Restore->succ_empty() || Restore->isReturnBlock())
+ RestorePoints.insertReg(Reg, Restore, RestoreBlocks);
+ else
+ RestorePoints.insertReg(Reg, Restore, std::nullopt);
+ }
+ }
+}
+
+bool ShrinkWrap::canSplitSaveRestorePoints(
+ const ReversePostOrderTraversal<MachineBasicBlock *> &RPOT,
+ RegScavenger *RS) {
+ for (MachineBasicBlock *MBB : RPOT) {
+ if (MBB->isEHPad() || MBB->isInlineAsmBrIndirectTarget())
+ return false;
+
+ // Check if we found any stack accesses in the predecessors. We are not
+ // doing a full dataflow analysis here to keep things simple but just
+ // rely on a reverse portorder traversal (RPOT) to guarantee predecessors
+ // are already processed except for loops (and accept the conservative
+ // result for loops).
+ bool StackAddressUsed = any_of(MBB->predecessors(), [&](auto *Pred) {
+ return StackAddressUsedBlockInfo.test(Pred->getNumber());
+ });
+
+ for (const MachineInstr &MI : *MBB) {
+ if (useOrDefFI(MI, RS, StackAddressUsed))
+ return false;
+
+ if (useOrDefCSR(MI, RS, nullptr))
+ StackAddressUsed = true;
+ }
+
+ StackAddressUsedBlockInfo[MBB->getNumber()] = StackAddressUsed;
+ }
+ return true;
+}
+
+void ShrinkWrap::performSimpleShrinkWrap(RegScavenger *RS,
+ MachineBasicBlock &SavePoint) {
+ auto MF = SavePoint.getParent();
+ auto CSRs = getTargetCSRList(*MF);
----------------
dongjianqiang2 wrote:
Whenever a basic block touches any callee-saved register (CSR), the pass updates save/restore points for all CSRs. This can make the result overly conservative: saves are moved closer to the function entry and restores closer to the exit, even for registers that are not actually used in the current block.
https://github.com/llvm/llvm-project/pull/119359
More information about the llvm-commits
mailing list