[SEH] Implement GetExceptionCode in __except blocks
This introduces an intrinsic called llvm.eh.exceptioncode. It is lowered
by copying the EAX value live into whatever basic block it is called
from. Obviously, this only works if you insert it late during codegen,
because otherwise mid-level passes might reschedule it.
llvm-svn: 235768
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index b788232..fc5ca3e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -271,40 +271,49 @@
}
// Mark landing pad blocks.
- const LandingPadInst *LP = nullptr;
+ SmallVector<const LandingPadInst *, 4> LPads;
for (BB = Fn->begin(); BB != EB; ++BB) {
if (const auto *Invoke = dyn_cast<InvokeInst>(BB->getTerminator()))
MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
if (BB->isLandingPad())
- LP = BB->getLandingPadInst();
+ LPads.push_back(BB->getLandingPadInst());
}
- // Calculate EH numbers for MSVC C++ EH and save SEH handlers if necessary.
+ // If this is an MSVC EH personality, we need to do a bit more work.
EHPersonality Personality = EHPersonality::Unknown;
- if (LP)
- Personality = classifyEHPersonality(LP->getPersonalityFn());
+ if (!LPads.empty())
+ Personality = classifyEHPersonality(LPads.back()->getPersonalityFn());
+ if (!isMSVCEHPersonality(Personality))
+ return;
+
+ WinEHFuncInfo *EHInfo = nullptr;
if (Personality == EHPersonality::MSVC_Win64SEH) {
- addSEHHandlersForLPads();
+ addSEHHandlersForLPads(LPads);
} else if (Personality == EHPersonality::MSVC_CXX) {
const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
- WinEHFuncInfo &FI = MMI.getWinEHFuncInfo(WinEHParentFn);
- if (FI.LandingPadStateMap.empty()) {
- WinEHNumbering Num(FI);
+ EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn);
+ if (EHInfo->LandingPadStateMap.empty()) {
+ WinEHNumbering Num(*EHInfo);
Num.calculateStateNumbers(*WinEHParentFn);
// Pop everything on the handler stack.
Num.processCallSite(None, ImmutableCallSite());
}
+
+ // Copy the state numbers to LandingPadInfo for the current function, which
+ // could be a handler or the parent.
+ for (const LandingPadInst *LP : LPads) {
+ MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
+ MMI.addWinEHState(LPadMBB, EHInfo->LandingPadStateMap[LP]);
+ }
}
}
-void FunctionLoweringInfo::addSEHHandlersForLPads() {
+void FunctionLoweringInfo::addSEHHandlersForLPads(
+ ArrayRef<const LandingPadInst *> LPads) {
MachineModuleInfo &MMI = MF->getMMI();
// Iterate over all landing pads with llvm.eh.actions calls.
- for (const BasicBlock &BB : *Fn) {
- const LandingPadInst *LP = BB.getLandingPadInst();
- if (!LP)
- continue;
+ for (const LandingPadInst *LP : LPads) {
const IntrinsicInst *ActionsCall =
dyn_cast<IntrinsicInst>(LP->getNextNode());
if (!ActionsCall ||
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 01419cf..fd59d57 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4817,6 +4817,18 @@
case Intrinsic::eh_begincatch:
case Intrinsic::eh_endcatch:
llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
+ case Intrinsic::eh_exceptioncode: {
+ unsigned Reg = TLI.getExceptionPointerRegister();
+ assert(Reg && "cannot get exception code on this platform");
+ MVT PtrVT = TLI.getPointerTy();
+ const TargetRegisterClass *PtrRC = TLI.getRegClassFor(PtrVT);
+ unsigned VReg = FuncInfo.MBB->addLiveIn(Reg, PtrRC);
+ SDValue N =
+ DAG.getCopyFromReg(DAG.getEntryNode(), getCurSDLoc(), VReg, PtrVT);
+ N = DAG.getZExtOrTrunc(N, getCurSDLoc(), MVT::i32);
+ setValue(&I, N);
+ return nullptr;
+ }
}
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index f3735cb..056ba4a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -961,12 +961,6 @@
for (MachineBasicBlock *InvokeBB : InvokeBBs)
InvokeBB->removeSuccessor(MBB);
- // Transfer EH state number assigned to the IR block to the MBB.
- if (Personality == EHPersonality::MSVC_CXX) {
- WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
- MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
- }
-
// Don't select instructions for the landingpad.
return false;
}