[llvm] [AArch64] Use a frame record for non-leaf outlined functions on MachO (PR #213711)
Jon Roelofs via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 08:53:27 PDT 2026
================
@@ -11213,32 +11235,80 @@ void AArch64InstrInfo::buildOutlinedFrame(
OF.FrameConstructionID == MachineOutlinerThunk)
Et = std::prev(MBB.end());
- // Insert a save before the outlined region
- MachineInstr *STRXpre = BuildMI(MF, DebugLoc(), get(AArch64::STRXpre))
- .addReg(AArch64::SP, RegState::Define)
- .addReg(AArch64::LR)
+ // There is a call in the range, so we must save LR. On MachO, saving only
+ // LR cannot be described by compact unwind. Saving FP and LR as a frame
+ // record lets the compact-unwind encoder use the FRAME encoding, at the
+ // cost of one extra mov.
+ bool NeedsDwarf =
+ MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo(MF);
+ bool UseFrameRecord = shouldUseCompactUnwindFrameRecordForOutlinedFunction(
+ MF, NeedsDwarf, isFPAvailableInsideOutlinedSeq(MBB, getRegisterInfo()));
+
+ if (UseFrameRecord) {
+ // FP is saved here, so it must be live-in.
+ if (!MBB.isLiveIn(AArch64::FP))
+ MBB.addLiveIn(AArch64::FP);
+
+ // stp x29, x30, [sp, #-16]! (STP pre-index imm is scaled by 8: -2 * 8)
+ MachineInstr *STPXpre = BuildMI(MF, DebugLoc(), get(AArch64::STPXpre))
+ .addReg(AArch64::SP, RegState::Define)
+ .addReg(AArch64::FP)
+ .addReg(AArch64::LR)
+ .addReg(AArch64::SP)
+ .addImm(-2);
+ It = MBB.insert(It, STPXpre);
+
+ // mov x29, sp (add x29, sp, #0) so x29 points at the saved frame record.
+ MachineInstr *SetFP = BuildMI(MF, DebugLoc(), get(AArch64::ADDXri))
+ .addReg(AArch64::FP, RegState::Define)
.addReg(AArch64::SP)
- .addImm(-16);
- It = MBB.insert(It, STRXpre);
-
- if (MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo(MF)) {
- CFIInstBuilder CFIBuilder(MBB, It, MachineInstr::FrameSetup);
-
- // Add a CFI saying the stack was moved 16 B down.
- CFIBuilder.buildDefCFAOffset(16);
+ .addImm(0)
+ .addImm(0);
+ MBB.insertAfter(It, SetFP);
+
+ // Standard frame-record CFI (FP is the CFA) so the encoder emits FRAME.
+ CFIInstBuilder CFIBuilder(MBB, std::next(SetFP->getIterator()),
+ MachineInstr::FrameSetup);
+ CFIBuilder.buildDefCFA(AArch64::FP, 16);
+ CFIBuilder.buildOffset(AArch64::LR, -8);
+ CFIBuilder.buildOffset(AArch64::FP, -16);
----------------
jroelofs wrote:
oh, never mind, we don't need the "needs dwarf" check here, since that's subsumed by the `shouldUseCompactUnwindFrameRecordForOutlinedFunction` check.
https://github.com/llvm/llvm-project/pull/213711
More information about the llvm-commits
mailing list