diff --git a/llvm/lib/CodeGen/CFIFixup.cpp b/llvm/lib/CodeGen/CFIFixup.cpp index 61888a4266652..e881a62522f0c 100644 --- a/llvm/lib/CodeGen/CFIFixup.cpp +++ b/llvm/lib/CodeGen/CFIFixup.cpp @@ -116,6 +116,32 @@ findPrologueEnd(MachineFunction &MF, MachineBasicBlock::iterator &PrologueEnd) { return nullptr; } +// Inserts a `.cfi_remember_state` instruction before PrologueEnd and a +// `.cfi_restore_state` instruction before DstInsertPt. Returns an iterator +// to the first instruction after the inserted `.cfi_restore_state` instruction. +static MachineBasicBlock::iterator +insertRememberRestorePair(MachineBasicBlock::iterator RememberInsertPt, + MachineBasicBlock::iterator RestoreInsertPt) { + MachineBasicBlock *RememberMBB = RememberInsertPt->getParent(); + MachineBasicBlock *RestoreMBB = RestoreInsertPt->getParent(); + MachineFunction &MF = *RememberMBB->getParent(); + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); + + // Insert the `.cfi_remember_state` instruction. + unsigned CFIIndex = + MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr)); + BuildMI(*RememberMBB, RememberInsertPt, DebugLoc(), + TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + + // Insert the `.cfi_restore_state` instruction. + CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr)); + BuildMI(*RestoreMBB, RestoreInsertPt, DebugLoc(), + TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + return RestoreInsertPt; +} + bool CFIFixup::runOnMachineFunction(MachineFunction &MF) { const TargetFrameLowering &TFL = *MF.getSubtarget().getFrameLowering(); if (!TFL.enableCFIFixup(MF)) @@ -174,12 +200,10 @@ bool CFIFixup::runOnMachineFunction(MachineFunction &MF) { // Every block inherits the frame state (as recorded in the unwind tables) // of the previous block. If the intended frame state is different, insert // compensating CFI instructions. - const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); bool Change = false; // `InsertPt` always points to the point in a preceding block where we have to // insert a `.cfi_remember_state`, in the case that the current block needs a // `.cfi_restore_state`. - MachineBasicBlock *InsertMBB = PrologueBlock; MachineBasicBlock::iterator InsertPt = PrologueEnd; assert(InsertPt != PrologueBlock->begin() && @@ -210,20 +234,10 @@ bool CFIFixup::runOnMachineFunction(MachineFunction &MF) { if (!Info.StrongNoFrameOnEntry && Info.HasFrameOnEntry && !HasFrame) { // Reset to the "after prologue" state. - // Insert a `.cfi_remember_state` into the last block known to have a - // stack frame. - unsigned CFIIndex = - MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr)); - BuildMI(*InsertMBB, InsertPt, DebugLoc(), - TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); - // Insert a `.cfi_restore_state` at the beginning of the current block. - CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr)); - InsertPt = BuildMI(*CurrBB, CurrBB->begin(), DebugLoc(), - TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); - ++InsertPt; - InsertMBB = &*CurrBB; + // There's an earlier block known to have a stack frame. Insert a + // `.cfi_remember_state` instruction into that block and a + // `.cfi_restore_state` instruction at the beginning of the current block. + InsertPt = insertRememberRestorePair(InsertPt, CurrBB->begin()); Change = true; } else if ((Info.StrongNoFrameOnEntry || !Info.HasFrameOnEntry) && HasFrame) {