mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-25 10:27:04 +00:00
[WinEH] Fixes for a few cppeh failures.
Differential Review: http://reviews.llvm.org/D9065 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235239 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -196,6 +196,9 @@ public:
|
||||
virtual CloningAction handleResume(ValueToValueMapTy &VMap,
|
||||
const ResumeInst *Resume,
|
||||
BasicBlock *NewBB) = 0;
|
||||
virtual CloningAction handleCompare(ValueToValueMapTy &VMap,
|
||||
const CmpInst *Compare,
|
||||
BasicBlock *NewBB) = 0;
|
||||
virtual CloningAction handleLandingPad(ValueToValueMapTy &VMap,
|
||||
const LandingPadInst *LPad,
|
||||
BasicBlock *NewBB) = 0;
|
||||
@@ -231,6 +234,8 @@ public:
|
||||
BasicBlock *NewBB) override;
|
||||
CloningAction handleResume(ValueToValueMapTy &VMap, const ResumeInst *Resume,
|
||||
BasicBlock *NewBB) override;
|
||||
CloningAction handleCompare(ValueToValueMapTy &VMap,
|
||||
const CmpInst *Compare, BasicBlock *NewBB) override;
|
||||
CloningAction handleLandingPad(ValueToValueMapTy &VMap,
|
||||
const LandingPadInst *LPad,
|
||||
BasicBlock *NewBB) override;
|
||||
@@ -267,6 +272,8 @@ public:
|
||||
BasicBlock *NewBB) override;
|
||||
CloningAction handleResume(ValueToValueMapTy &VMap, const ResumeInst *Resume,
|
||||
BasicBlock *NewBB) override;
|
||||
CloningAction handleCompare(ValueToValueMapTy &VMap,
|
||||
const CmpInst *Compare, BasicBlock *NewBB) override;
|
||||
CloningAction handleLandingPad(ValueToValueMapTy &VMap,
|
||||
const LandingPadInst *LPad,
|
||||
BasicBlock *NewBB) override;
|
||||
@@ -1053,6 +1060,9 @@ CloningDirector::CloningAction WinEHCloningDirectorBase::handleInstruction(
|
||||
if (auto *Resume = dyn_cast<ResumeInst>(Inst))
|
||||
return handleResume(VMap, Resume, NewBB);
|
||||
|
||||
if (auto *Cmp = dyn_cast<CmpInst>(Inst))
|
||||
return handleCompare(VMap, Cmp, NewBB);
|
||||
|
||||
if (match(Inst, m_Intrinsic<Intrinsic::eh_begincatch>()))
|
||||
return handleBeginCatch(VMap, Inst, NewBB);
|
||||
if (match(Inst, m_Intrinsic<Intrinsic::eh_endcatch>()))
|
||||
@@ -1173,6 +1183,30 @@ WinEHCatchDirector::handleResume(ValueToValueMapTy &VMap,
|
||||
return CloningDirector::StopCloningBB;
|
||||
}
|
||||
|
||||
CloningDirector::CloningAction
|
||||
WinEHCatchDirector::handleCompare(ValueToValueMapTy &VMap,
|
||||
const CmpInst *Compare, BasicBlock *NewBB) {
|
||||
const IntrinsicInst *IntrinCall = nullptr;
|
||||
if (match(Compare->getOperand(0), m_Intrinsic<Intrinsic::eh_typeid_for>())) {
|
||||
IntrinCall = dyn_cast<IntrinsicInst>(Compare->getOperand(0));
|
||||
} else if (match(Compare->getOperand(1), m_Intrinsic<Intrinsic::eh_typeid_for>())) {
|
||||
IntrinCall = dyn_cast<IntrinsicInst>(Compare->getOperand(1));
|
||||
}
|
||||
if (IntrinCall) {
|
||||
Value *Selector = IntrinCall->getArgOperand(0)->stripPointerCasts();
|
||||
// This causes a replacement that will collapse the landing pad CFG based
|
||||
// on the filter function we intend to match.
|
||||
if (Selector == CurrentSelector->stripPointerCasts()) {
|
||||
VMap[Compare] = ConstantInt::get(SelectorIDType, 1);
|
||||
}
|
||||
else {
|
||||
VMap[Compare] = ConstantInt::get(SelectorIDType, 0);
|
||||
}
|
||||
return CloningDirector::SkipInstruction;
|
||||
}
|
||||
return CloningDirector::CloneInstruction;
|
||||
}
|
||||
|
||||
CloningDirector::CloningAction WinEHCleanupDirector::handleLandingPad(
|
||||
ValueToValueMapTy &VMap, const LandingPadInst *LPad, BasicBlock *NewBB) {
|
||||
// The MS runtime will terminate the process if an exception occurs in a
|
||||
@@ -1189,11 +1223,11 @@ CloningDirector::CloningAction WinEHCleanupDirector::handleLandingPad(
|
||||
|
||||
CloningDirector::CloningAction WinEHCleanupDirector::handleBeginCatch(
|
||||
ValueToValueMapTy &VMap, const Instruction *Inst, BasicBlock *NewBB) {
|
||||
// Catch blocks within cleanup handlers will always be unreachable.
|
||||
// We'll insert an unreachable instruction now, but it will be pruned
|
||||
// before the cloning process is complete.
|
||||
BasicBlock::InstListType &InstList = NewBB->getInstList();
|
||||
InstList.push_back(new UnreachableInst(NewBB->getContext()));
|
||||
// Cleanup code may flow into catch blocks or the catch block may be part
|
||||
// of a branch that will be optimized away. We'll insert a return
|
||||
// instruction now, but it may be pruned before the cloning process is
|
||||
// complete.
|
||||
ReturnInst::Create(NewBB->getContext(), nullptr, NewBB);
|
||||
return CloningDirector::StopCloningBB;
|
||||
}
|
||||
|
||||
@@ -1259,6 +1293,19 @@ CloningDirector::CloningAction WinEHCleanupDirector::handleResume(
|
||||
return CloningDirector::StopCloningBB;
|
||||
}
|
||||
|
||||
CloningDirector::CloningAction
|
||||
WinEHCleanupDirector::handleCompare(ValueToValueMapTy &VMap,
|
||||
const CmpInst *Compare, BasicBlock *NewBB) {
|
||||
const IntrinsicInst *IntrinCall = nullptr;
|
||||
if (match(Compare->getOperand(0), m_Intrinsic<Intrinsic::eh_typeid_for>()) ||
|
||||
match(Compare->getOperand(1), m_Intrinsic<Intrinsic::eh_typeid_for>())) {
|
||||
VMap[Compare] = ConstantInt::get(SelectorIDType, 1);
|
||||
return CloningDirector::SkipInstruction;
|
||||
}
|
||||
return CloningDirector::CloneInstruction;
|
||||
|
||||
}
|
||||
|
||||
WinEHFrameVariableMaterializer::WinEHFrameVariableMaterializer(
|
||||
Function *OutlinedFn, FrameVarInfoMap &FrameVarInfo)
|
||||
: FrameVarInfo(FrameVarInfo), Builder(OutlinedFn->getContext()) {
|
||||
@@ -1355,10 +1402,21 @@ void WinEHPrepare::mapLandingPadBlocks(LandingPadInst *LPad,
|
||||
|
||||
// See if the clause we're looking for is a catch-all.
|
||||
// If so, the catch begins immediately.
|
||||
if (isa<ConstantPointerNull>(LPad->getClause(HandlersFound))) {
|
||||
Constant *ExpectedSelector = LPad->getClause(HandlersFound)->stripPointerCasts();
|
||||
if (isa<ConstantPointerNull>(ExpectedSelector)) {
|
||||
// The catch all must occur last.
|
||||
assert(HandlersFound == NumClauses - 1);
|
||||
|
||||
// There can be additional selector dispatches in the call chain that we
|
||||
// need to ignore.
|
||||
BasicBlock *CatchBlock = nullptr;
|
||||
Constant *Selector;
|
||||
while (BB && isSelectorDispatch(BB, CatchBlock, Selector, NextBB)) {
|
||||
DEBUG(dbgs() << " Found extra catch dispatch in block "
|
||||
<< CatchBlock->getName() << "\n");
|
||||
BB = NextBB;
|
||||
}
|
||||
|
||||
// For C++ EH, check if there is any interesting cleanup code before we
|
||||
// begin the catch. This is important because cleanups cannot rethrow
|
||||
// exceptions but code called from catches can. For SEH, it isn't
|
||||
@@ -1368,8 +1426,10 @@ void WinEHPrepare::mapLandingPadBlocks(LandingPadInst *LPad,
|
||||
findCleanupHandlers(Actions, BB, BB);
|
||||
|
||||
// Add the catch handler to the action list.
|
||||
CatchHandler *Action =
|
||||
new CatchHandler(BB, LPad->getClause(HandlersFound), nullptr);
|
||||
// Since this is a catch-all handler, the selector won't actually appear
|
||||
// in the code anywhere. ExpectedSelector here is the constant null ptr
|
||||
// that we got from the landing pad instruction.
|
||||
CatchHandler *Action = new CatchHandler(BB, ExpectedSelector, nullptr);
|
||||
CatchHandlerMap[BB] = Action;
|
||||
Actions.insertCatchHandler(Action);
|
||||
DEBUG(dbgs() << " Catch all handler at block " << BB->getName() << "\n");
|
||||
@@ -1385,12 +1445,21 @@ void WinEHPrepare::mapLandingPadBlocks(LandingPadInst *LPad,
|
||||
findCleanupHandlers(Actions, BB, CatchAction->getStartBlock());
|
||||
|
||||
assert(CatchAction);
|
||||
++HandlersFound;
|
||||
|
||||
// Add the catch handler to the action list.
|
||||
Actions.insertCatchHandler(CatchAction);
|
||||
DEBUG(dbgs() << " Found catch dispatch in block "
|
||||
<< CatchAction->getStartBlock()->getName() << "\n");
|
||||
// When the source program contains multiple nested try blocks the catch
|
||||
// handlers can get strung together in such a way that we can encounter
|
||||
// a dispatch for a selector that we've already had a handler for.
|
||||
if (CatchAction->getSelector()->stripPointerCasts() == ExpectedSelector) {
|
||||
++HandlersFound;
|
||||
|
||||
// Add the catch handler to the action list.
|
||||
DEBUG(dbgs() << " Found catch dispatch in block "
|
||||
<< CatchAction->getStartBlock()->getName() << "\n");
|
||||
Actions.insertCatchHandler(CatchAction);
|
||||
} else {
|
||||
DEBUG(dbgs() << " Found extra catch dispatch in block "
|
||||
<< CatchAction->getStartBlock()->getName() << "\n");
|
||||
}
|
||||
|
||||
// Move on to the block after the catch handler.
|
||||
BB = NextBB;
|
||||
|
||||
Reference in New Issue
Block a user