diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-10-06 23:31:59 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-10-06 23:31:59 +0000 |
commit | 7735a6d07ac83620379273aa19566de172cf06c3 (patch) | |
tree | cf1df5815568680069913c9083aeb2e1d34c2620 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | |
parent | 083ca9bb3233fb4df575bfb8c4198e3f9d6e3acd (diff) | |
download | bcm5719-llvm-7735a6d07ac83620379273aa19566de172cf06c3.tar.gz bcm5719-llvm-7735a6d07ac83620379273aa19566de172cf06c3.zip |
[WinEH] Create a separate MBB for funclet prologues
Our current emission strategy is to emit the funclet prologue in the
CatchPad's normal destination. This is problematic because
intra-funclet control flow to the normal destination is not erroneous
and results in us reevaluating the prologue if said control flow is
taken.
Instead, use the CatchPad's location for the funclet prologue. This
correctly models our desire to have unwind edges evaluate the prologue
but edges to the normal destination result in typical control flow.
Differential Revision: http://reviews.llvm.org/D13424
llvm-svn: 249483
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index fc140f65571..22809aa0b3e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1160,7 +1160,35 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { } void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) { - llvm_unreachable("should never codegen catchpads"); + auto Pers = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()); + bool IsMSVCCXX = Pers == EHPersonality::MSVC_CXX; + bool IsSEH = isAsynchronousEHPersonality(Pers); + MachineBasicBlock *CatchPadMBB = FuncInfo.MBB; + // In MSVC C++, catchblocks are funclets and need prologues. + if (IsMSVCCXX) + CatchPadMBB->setIsEHFuncletEntry(); + + MachineBasicBlock *NormalDestMBB = FuncInfo.MBBMap[I.getNormalDest()]; + + // 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->begin()))); + return; + } + + // 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))); } void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) { @@ -1168,6 +1196,18 @@ void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) { MachineBasicBlock *TargetMBB = FuncInfo.MBBMap[I.getSuccessor()]; FuncInfo.MBB->addSuccessor(TargetMBB); + auto Pers = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()); + bool IsSEH = isAsynchronousEHPersonality(Pers); + if (IsSEH) { + // If this is not a fall-through branch or optimizations are switched off, + // emit the branch. + if (TargetMBB != NextBlock(FuncInfo.MBB) || + TM.getOptLevel() == CodeGenOpt::None) + DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, + getControlRoot(), DAG.getBasicBlock(TargetMBB))); + return; + } + // Figure out the funclet membership for the catchret's successor. // This will be used by the FuncletLayout pass to determine how to order the // BB's. @@ -1225,8 +1265,8 @@ findUnwindDestinations(FunctionLoweringInfo &FuncInfo, break; } else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) { // Add the catchpad handler to the possible destinations. - UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]); - // In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues. + UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]); + // In MSVC C++, catchblocks are funclets and need prologues. if (IsMSVCCXX || IsCoreCLR) UnwindDests.back()->setIsEHFuncletEntry(); EHPadBB = CPI->getUnwindDest(); |