diff options
author | Reid Kleckner <rnk@google.com> | 2015-11-06 01:49:05 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-11-06 01:49:05 +0000 |
commit | 51460c139eb95d1ee2daf62ebed082f735016392 (patch) | |
tree | b80ea144ab445ec34be42fcb0f920d19cc36a1fb /llvm/lib/Target/X86/X86FrameLowering.cpp | |
parent | 8d372b9761e73455873069660491e10c289009ab (diff) | |
download | bcm5719-llvm-51460c139eb95d1ee2daf62ebed082f735016392.tar.gz bcm5719-llvm-51460c139eb95d1ee2daf62ebed082f735016392.zip |
[WinEH] Split EH_RESTORE out of CATCHRET for 32-bit EH
This adds the EH_RESTORE x86 pseudo instr, which is responsible for
restoring the stack pointers: EBP and ESP, and ESI if stack realignment
is involved. We only need this on 32-bit x86, because on x64 the runtime
restores CSRs for us.
Previously we had to keep the CATCHRET instruction around during SEH so
that we could convince X86FrameLowering to restore our frame pointers.
Now we can split these instructions earlier.
This was confusing, because we had a return instruction which wasn't
really a return and was ultimately going to be removed by
X86FrameLowering. This change also simplifies X86FrameLowering, which
really shouldn't be building new MBBs.
No observable functional change currently, but with the new register
mask stuff in D14407, CATCHRET will become a register allocator barrier,
and our existing tests rely on us having reasonable register allocation
around SEH.
llvm-svn: 252266
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 54 |
1 files changed, 14 insertions, 40 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index ad83344b327..b69a001a0b5 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1091,7 +1091,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, bool NeedsWinCFI = IsWin64Prologue && MF.getFunction()->needsUnwindTableEntry(); bool IsFunclet = isFuncletReturnInstr(MBBI); - MachineBasicBlock *RestoreMBB = nullptr; + MachineBasicBlock *TargetMBB = nullptr; // Get the number of bytes to allocate from the FrameInfo. uint64_t StackSize = MFI->getStackSize(); @@ -1100,45 +1100,19 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, uint64_t NumBytes = 0; if (MBBI->getOpcode() == X86::CATCHRET) { + // SEH shouldn't use catchret. + assert(!isAsynchronousEHPersonality( + classifyEHPersonality(MF.getFunction()->getPersonalityFn())) && + "SEH should not use CATCHRET"); + NumBytes = getWinEHFuncletFrameSize(MF); assert(hasFP(MF) && "EH funclets without FP not yet implemented"); - MachineBasicBlock *TargetMBB = MBBI->getOperand(0).getMBB(); - - // If this is SEH, this isn't really a funclet return. - bool IsSEH = isAsynchronousEHPersonality( - classifyEHPersonality(MF.getFunction()->getPersonalityFn())); - if (IsSEH) { - if (STI.is32Bit()) - restoreWin32EHStackPointers(MBB, MBBI, DL, /*RestoreSP=*/true); - BuildMI(MBB, MBBI, DL, TII.get(X86::JMP_4)).addMBB(TargetMBB); - MBBI->eraseFromParent(); - return; - } - - // For 32-bit, create a new block for the restore code. - RestoreMBB = TargetMBB; - if (STI.is32Bit()) { - RestoreMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock()); - MF.insert(TargetMBB->getIterator(), RestoreMBB); - MBB.removeSuccessor(TargetMBB); - MBB.addSuccessor(RestoreMBB); - RestoreMBB->addSuccessor(TargetMBB); - MBBI->getOperand(0).setMBB(RestoreMBB); - } + TargetMBB = MBBI->getOperand(0).getMBB(); // Pop EBP. BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), MachineFramePtr) .setMIFlag(MachineInstr::FrameDestroy); - - // Insert frame restoration code in a new block. - if (STI.is32Bit()) { - auto RestoreMBBI = RestoreMBB->begin(); - restoreWin32EHStackPointers(*RestoreMBB, RestoreMBBI, DL, - /*RestoreSP=*/true); - BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::JMP_4)) - .addMBB(TargetMBB); - } } else if (MBBI->getOpcode() == X86::CLEANUPRET) { NumBytes = getWinEHFuncletFrameSize(MF); assert(hasFP(MF) && "EH funclets without FP not yet implemented"); @@ -1178,26 +1152,26 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, } MachineBasicBlock::iterator FirstCSPop = MBBI; - if (RestoreMBB) { + if (TargetMBB) { // Fill EAX/RAX with the address of the target block. unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX; if (STI.is64Bit()) { - // LEA64r RestoreMBB(%rip), %rax + // LEA64r TargetMBB(%rip), %rax BuildMI(MBB, FirstCSPop, DL, TII.get(X86::LEA64r), ReturnReg) .addReg(X86::RIP) .addImm(0) .addReg(0) - .addMBB(RestoreMBB) + .addMBB(TargetMBB) .addReg(0); } else { - // MOV32ri $RestoreMBB, %eax + // MOV32ri $TargetMBB, %eax BuildMI(MBB, FirstCSPop, DL, TII.get(X86::MOV32ri)) .addReg(ReturnReg) - .addMBB(RestoreMBB); + .addMBB(TargetMBB); } - // Record that we've taken the address of RestoreMBB and no longer just + // Record that we've taken the address of TargetMBB and no longer just // reference it in a terminator. - RestoreMBB->setHasAddressTaken(); + TargetMBB->setHasAddressTaken(); } if (MBBI != MBB.end()) |