mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
[WinEH] Don't emit CATCHRET from visitCatchPad
Instead, emit a CATCHPAD node which will get selected to a target specific sequence. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252528 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5d89904858
commit
c30d240fb8
@ -591,6 +591,9 @@ namespace ISD {
|
||||
/// take a chain as input and return a chain.
|
||||
EH_LABEL,
|
||||
|
||||
/// CATCHPAD - Represents a catchpad instruction.
|
||||
CATCHPAD,
|
||||
|
||||
/// CATCHRET - Represents a return from a catch block funclet. Used for
|
||||
/// MSVC compatible exception handling. Takes a chain operand and a
|
||||
/// destination basic block operand.
|
||||
|
@ -455,8 +455,11 @@ def brcc : SDNode<"ISD::BR_CC" , SDTBrCC, [SDNPHasChain]>;
|
||||
def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>;
|
||||
def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
|
||||
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
|
||||
def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret, [SDNPHasChain]>;
|
||||
def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone, [SDNPHasChain]>;
|
||||
def catchpad : SDNode<"ISD::CATCHPAD" , SDTNone,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
def trap : SDNode<"ISD::TRAP" , SDTNone,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
@ -1178,7 +1178,6 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
|
||||
void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
|
||||
auto Pers = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn());
|
||||
bool IsMSVCCXX = Pers == EHPersonality::MSVC_CXX;
|
||||
bool IsSEH = isAsynchronousEHPersonality(Pers);
|
||||
bool IsCoreCLR = Pers == EHPersonality::CoreCLR;
|
||||
MachineBasicBlock *CatchPadMBB = FuncInfo.MBB;
|
||||
// In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues.
|
||||
@ -1190,22 +1189,16 @@ void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
|
||||
// Update machine-CFG edge.
|
||||
FuncInfo.MBB->addSuccessor(NormalDestMBB);
|
||||
|
||||
// CatchPads in SEH are not funclets, they are merely markers which indicate
|
||||
// where to insert register restoration code.
|
||||
if (IsSEH) {
|
||||
DAG.setRoot(DAG.getNode(ISD::CATCHRET, getCurSDLoc(), MVT::Other,
|
||||
getControlRoot(), DAG.getBasicBlock(NormalDestMBB),
|
||||
DAG.getBasicBlock(&FuncInfo.MF->front())));
|
||||
return;
|
||||
}
|
||||
SDValue Chain =
|
||||
DAG.getNode(ISD::CATCHPAD, getCurSDLoc(), MVT::Other, getControlRoot());
|
||||
|
||||
// If this is not a fall-through branch or optimizations are switched off,
|
||||
// emit the branch.
|
||||
if (NormalDestMBB != NextBlock(CatchPadMBB) ||
|
||||
TM.getOptLevel() == CodeGenOpt::None)
|
||||
DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other,
|
||||
getControlRoot(),
|
||||
DAG.getBasicBlock(NormalDestMBB)));
|
||||
Chain = DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, Chain,
|
||||
DAG.getBasicBlock(NormalDestMBB));
|
||||
DAG.setRoot(Chain);
|
||||
}
|
||||
|
||||
void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
|
||||
|
@ -21401,15 +21401,7 @@ X86TargetLowering::EmitLoweredCatchRet(MachineInstr *MI,
|
||||
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;
|
||||
}
|
||||
assert(!IsSEH && "SEH does not use catchret!");
|
||||
|
||||
// Only 32-bit EH needs to worry about manually restoring stack pointers.
|
||||
if (!Subtarget->is32Bit())
|
||||
@ -21431,6 +21423,22 @@ X86TargetLowering::EmitLoweredCatchRet(MachineInstr *MI,
|
||||
return BB;
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
X86TargetLowering::EmitLoweredCatchPad(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const {
|
||||
MachineFunction *MF = BB->getParent();
|
||||
const Constant *PerFn = MF->getFunction()->getPersonalityFn();
|
||||
bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(PerFn));
|
||||
// Only 32-bit SEH requires special handling for catchpad.
|
||||
if (IsSEH && Subtarget->is32Bit()) {
|
||||
const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
BuildMI(*BB, MI, DL, TII.get(X86::EH_RESTORE));
|
||||
}
|
||||
MI->eraseFromParent();
|
||||
return BB;
|
||||
}
|
||||
|
||||
MachineBasicBlock *
|
||||
X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const {
|
||||
@ -21813,6 +21821,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
return EmitLoweredWinAlloca(MI, BB);
|
||||
case X86::CATCHRET:
|
||||
return EmitLoweredCatchRet(MI, BB);
|
||||
case X86::CATCHPAD:
|
||||
return EmitLoweredCatchPad(MI, BB);
|
||||
case X86::SEG_ALLOCA_32:
|
||||
case X86::SEG_ALLOCA_64:
|
||||
return EmitLoweredSegAlloca(MI, BB);
|
||||
|
@ -1101,6 +1101,9 @@ namespace llvm {
|
||||
MachineBasicBlock *EmitLoweredCatchRet(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
|
||||
MachineBasicBlock *EmitLoweredCatchPad(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
|
||||
MachineBasicBlock *EmitLoweredSegAlloca(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
|
||||
|
@ -156,13 +156,17 @@ let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
|
||||
isCodeGenOnly = 1, isReturn = 1 in {
|
||||
def CLEANUPRET : I<0, Pseudo, (outs), (ins), "# CLEANUPRET", [(cleanupret)]>;
|
||||
|
||||
// CATCHRET needs a custom inserter for SEH nonsense.
|
||||
// CATCHRET needs a custom inserter for SEH.
|
||||
let usesCustomInserter = 1 in
|
||||
def CATCHRET : I<0, Pseudo, (outs), (ins brtarget32:$dst, brtarget32:$from),
|
||||
"# CATCHRET",
|
||||
[(catchret bb:$dst, bb:$from)]>;
|
||||
}
|
||||
|
||||
let hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1, isCodeGenOnly = 1,
|
||||
usesCustomInserter = 1 in
|
||||
def CATCHPAD : I<0, Pseudo, (outs), (ins), "# CATCHPAD", [(catchpad)]>;
|
||||
|
||||
// This instruction is responsible for re-establishing stack pointers after an
|
||||
// exception has been caught and we are rejoining normal control flow in the
|
||||
// parent function or funclet. It generally sets ESP and EBP, and optionally
|
||||
|
@ -34,7 +34,6 @@ endpad:
|
||||
; CHECK: callq crash
|
||||
; CHECK: retq
|
||||
; CHECK: .LBB0_2: # %lpad
|
||||
; CHECK: # %catchall
|
||||
; CHECK: leaq str(%rip), %rcx
|
||||
; CHECK: movl %eax, %edx
|
||||
; CHECK: callq printf
|
||||
|
@ -121,8 +121,6 @@ ehcleanup.end: ; preds = %ehcleanup
|
||||
; CHECK: callq "?fin$0@0@main@@"
|
||||
; CHECK: jmp .LBB1_[[epilogue]]
|
||||
; CHECK: .LBB1_[[except2bb:[0-9]+]]: # %catch.dispatch.7
|
||||
; CHECK: jmp .LBB1_7
|
||||
; CHECK: # %__except.9
|
||||
; CHECK: leaq "??_C@_06IBDBCMGJ@caught?$AA@"(%rip), %rcx
|
||||
; CHECK: callq puts
|
||||
; CHECK: jmp .LBB1_[[epilogue]]
|
||||
@ -145,18 +143,18 @@ ehcleanup.end: ; preds = %ehcleanup
|
||||
; CHECK-NEXT: .long .Ltmp2@IMGREL+1
|
||||
; CHECK-NEXT: .long .Ltmp3@IMGREL+1
|
||||
; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL
|
||||
; CHECK-NEXT: .long .LBB1_6@IMGREL
|
||||
; CHECK-NEXT: .long .LBB1_5@IMGREL
|
||||
; CHECK-NEXT: .long .Ltmp6@IMGREL+1
|
||||
; CHECK-NEXT: .long .Ltmp7@IMGREL+1
|
||||
; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL
|
||||
; CHECK-NEXT: .long .LBB1_6@IMGREL
|
||||
; CHECK-NEXT: .long .LBB1_5@IMGREL
|
||||
; CHECK-NEXT: .Llsda_end0:
|
||||
|
||||
; CHECK: .text
|
||||
; CHECK: .seh_endproc
|
||||
|
||||
; CHECK: "?dtor$4@?0?main@4HA":
|
||||
; CHECK: .seh_proc "?dtor$4@?0?main@4HA"
|
||||
; CHECK: "?dtor$3@?0?main@4HA":
|
||||
; CHECK: .seh_proc "?dtor$3@?0?main@4HA"
|
||||
; CHECK: .seh_handler __C_specific_handler, @unwind, @except
|
||||
; CHECK: .LBB1_[[finbb]]: # %ehcleanup
|
||||
; CHECK: movq %rdx, 16(%rsp)
|
||||
|
@ -36,6 +36,6 @@ catchendblock: ; preds = %catch.dispatch
|
||||
; CHECK: xorl %ecx, %ecx
|
||||
; CHECK: callq f
|
||||
|
||||
; CHECK: # %__except
|
||||
; CHECK: # %catch.dispatch
|
||||
; CHECK: movl %eax, %ecx
|
||||
; CHECK-NEXT: callq f
|
||||
|
@ -61,7 +61,7 @@ declare i32 @_except_handler3(...)
|
||||
; CHECK: calll _useit
|
||||
;
|
||||
; Epilogue
|
||||
; CHECK: LBB0_1: # %__try.cont
|
||||
; CHECK: LBB0_2: # %__try.cont
|
||||
; CHECK: leal -12(%ebp), %esp
|
||||
; CHECK: popl %esi
|
||||
; CHECK: popl %edi
|
||||
@ -69,7 +69,7 @@ declare i32 @_except_handler3(...)
|
||||
; CHECK: popl %ebp
|
||||
; CHECK: retl
|
||||
;
|
||||
; CHECK: LBB0_2: # %catch.dispatch
|
||||
; CHECK: LBB0_1: # %catch.dispatch
|
||||
; Restore ESP
|
||||
; CHECK: movl -24(%ebp), %esp
|
||||
; Recompute ESI by subtracting 60 from the end of the registration node.
|
||||
@ -77,4 +77,4 @@ declare i32 @_except_handler3(...)
|
||||
; Restore EBP
|
||||
; CHECK: movl 12(%esi), %ebp
|
||||
; Rejoin normal control flow
|
||||
; CHECK: jmp LBB0_1
|
||||
; CHECK: jmp LBB0_2
|
||||
|
@ -220,7 +220,6 @@ catchendblock: ; preds = %catch.dispatch
|
||||
; CHECK: # %catch.dispatch
|
||||
; CHECK-NEXT: movl -24(%ebp), %esp
|
||||
; CHECK-NEXT: addl $12, %ebp
|
||||
; CHECK: # %__except.ret
|
||||
; CHECK-NEXT: movl $-1, -16(%ebp)
|
||||
; CHECK-NEXT: movl $2, (%esp)
|
||||
; CHECK-NEXT: calll _f
|
||||
|
Loading…
Reference in New Issue
Block a user