mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[WinEHPrepare] Turn terminatepad into a cleanuppad + call + cleanupret
The MSVC doesn't really support exception specifications so let's just turn these into cleanuppads. Later, we might use terminatepad to more efficiently encode the "noexcept"-ness of a function body. llvm-svn: 247848
This commit is contained in:
parent
ab7c728711
commit
00d8b15197
@ -144,6 +144,7 @@ private:
|
||||
Function &F);
|
||||
bool prepareExplicitEH(Function &F,
|
||||
SmallVectorImpl<BasicBlock *> &EntryBlocks);
|
||||
void replaceTerminatePadWithCleanup(Function &F);
|
||||
void colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks);
|
||||
void demotePHIsOnFunclets(Function &F);
|
||||
void demoteUsesBetweenFunclets(Function &F);
|
||||
@ -3206,6 +3207,44 @@ void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn,
|
||||
Num.processCallSite(None, ImmutableCallSite());
|
||||
}
|
||||
|
||||
void WinEHPrepare::replaceTerminatePadWithCleanup(Function &F) {
|
||||
if (Personality != EHPersonality::MSVC_CXX)
|
||||
return;
|
||||
for (BasicBlock &BB : F) {
|
||||
Instruction *First = BB.getFirstNonPHI();
|
||||
auto *TPI = dyn_cast<TerminatePadInst>(First);
|
||||
if (!TPI)
|
||||
continue;
|
||||
|
||||
if (TPI->getNumArgOperands() != 1)
|
||||
report_fatal_error(
|
||||
"Expected a unary terminatepad for MSVC C++ personalities!");
|
||||
|
||||
auto *TerminateFn = dyn_cast<Function>(TPI->getArgOperand(0));
|
||||
if (!TerminateFn)
|
||||
report_fatal_error("Function operand expected in terminatepad for MSVC "
|
||||
"C++ personalities!");
|
||||
|
||||
// Insert the cleanuppad instruction.
|
||||
auto *CPI = CleanupPadInst::Create(
|
||||
BB.getContext(), {}, Twine("terminatepad.for.", BB.getName()), &BB);
|
||||
|
||||
// Insert the call to the terminate instruction.
|
||||
auto *CallTerminate = CallInst::Create(TerminateFn, {}, &BB);
|
||||
CallTerminate->setDoesNotThrow();
|
||||
CallTerminate->setDoesNotReturn();
|
||||
CallTerminate->setCallingConv(TerminateFn->getCallingConv());
|
||||
|
||||
// Insert a new terminator for the cleanuppad using the same successor as
|
||||
// the terminatepad.
|
||||
CleanupReturnInst::Create(CPI, TPI->getUnwindDest(), &BB);
|
||||
|
||||
// Let's remove the terminatepad now that we've inserted the new
|
||||
// instructions.
|
||||
TPI->eraseFromParent();
|
||||
}
|
||||
}
|
||||
|
||||
void WinEHPrepare::colorFunclets(Function &F,
|
||||
SmallVectorImpl<BasicBlock *> &EntryBlocks) {
|
||||
SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist;
|
||||
@ -3560,6 +3599,8 @@ bool WinEHPrepare::prepareExplicitEH(
|
||||
// not.
|
||||
removeUnreachableBlocks(F);
|
||||
|
||||
replaceTerminatePadWithCleanup(F);
|
||||
|
||||
// Determine which blocks are reachable from which funclet entries.
|
||||
colorFunclets(F, EntryBlocks);
|
||||
|
||||
|
@ -85,3 +85,21 @@ inner:
|
||||
exit:
|
||||
unreachable
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @test3(
|
||||
define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
|
||||
entry:
|
||||
invoke void @f()
|
||||
to label %invoke.cont unwind label %terminate
|
||||
|
||||
invoke.cont:
|
||||
ret void
|
||||
|
||||
terminate:
|
||||
; CHECK: cleanuppad []
|
||||
; CHECK: call void @__std_terminate()
|
||||
; CHECK: unreachable
|
||||
terminatepad [void ()* @__std_terminate] unwind to caller
|
||||
}
|
||||
|
||||
declare void @__std_terminate()
|
||||
|
Loading…
x
Reference in New Issue
Block a user