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/X86ISelLowering.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/X86ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d13d0510a0c..c9218a17a0b 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -21338,6 +21338,46 @@ X86TargetLowering::EmitLoweredWinAlloca(MachineInstr *MI, } MachineBasicBlock * +X86TargetLowering::EmitLoweredCatchRet(MachineInstr *MI, + MachineBasicBlock *BB) const { + MachineFunction *MF = BB->getParent(); + const Constant *PerFn = MF->getFunction()->getPersonalityFn(); + bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(PerFn)); + const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); + MachineBasicBlock *TargetMBB = MI->getOperand(0).getMBB(); + DebugLoc DL = MI->getDebugLoc(); + + // SEH does not outline catch bodies into funclets. Turn CATCHRETs into + // JMP_4s, possibly with some extra restoration code for 32-bit EH. + if (IsSEH) { + if (Subtarget->is32Bit()) + BuildMI(*BB, MI, DL, TII.get(X86::EH_RESTORE)); + BuildMI(*BB, MI, DL, TII.get(X86::JMP_4)).addMBB(TargetMBB); + MI->eraseFromParent(); + return BB; + } + + // Only 32-bit EH needs to worry about manually restoring stack pointers. + if (!Subtarget->is32Bit()) + return BB; + + // C++ EH creates a new target block to hold the restore code, and wires up + // the new block to the return destination with a normal JMP_4. + MachineBasicBlock *RestoreMBB = + MF->CreateMachineBasicBlock(BB->getBasicBlock()); + MF->insert(TargetMBB->getIterator(), RestoreMBB); + BB->removeSuccessor(TargetMBB); + BB->addSuccessor(RestoreMBB); + RestoreMBB->addSuccessor(TargetMBB); + MI->getOperand(0).setMBB(RestoreMBB); + + auto RestoreMBBI = RestoreMBB->begin(); + BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::EH_RESTORE)); + BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::JMP_4)).addMBB(TargetMBB); + return BB; +} + +MachineBasicBlock * X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI, MachineBasicBlock *BB) const { // This is pretty easy. We're taking the value that we received from @@ -21717,6 +21757,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; case X86::WIN_ALLOCA: return EmitLoweredWinAlloca(MI, BB); + case X86::CATCHRET: + return EmitLoweredCatchRet(MI, BB); case X86::SEG_ALLOCA_32: case X86::SEG_ALLOCA_64: return EmitLoweredSegAlloca(MI, BB); |