diff options
author | Joseph Tremoulet <jotrem@microsoft.com> | 2015-09-27 01:47:46 +0000 |
---|---|---|
committer | Joseph Tremoulet <jotrem@microsoft.com> | 2015-09-27 01:47:46 +0000 |
commit | 09af67aba54e6d2a05e3071c0c7ba43bde678df9 (patch) | |
tree | ff8dfefbf81e9a6ae3f2f3ded3ade5b8a54b8ed7 /llvm/lib/Transforms/Utils/Local.cpp | |
parent | d47346d0f8f0012c556e4ce656c4222eec8d08d6 (diff) | |
download | bcm5719-llvm-09af67aba54e6d2a05e3071c0c7ba43bde678df9.tar.gz bcm5719-llvm-09af67aba54e6d2a05e3071c0c7ba43bde678df9.zip |
[EH] Create removeUnwindEdge utility
Summary:
Factor the code that rewrites invokes to calls and rewrites WinEH
terminators to their "unwind to caller" equivalents into a helper in
Utils/Local, and use it in the three places I'm aware of that need to do
this.
Reviewers: andrew.w.kaylor, majnemer, rnk
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D13152
llvm-svn: 248677
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 235973c4fbc..fec7176e9a2 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1258,6 +1258,43 @@ static bool markAliveBlocks(Function &F, return Changed; } +void llvm::removeUnwindEdge(BasicBlock *BB) { + TerminatorInst *TI = BB->getTerminator(); + + if (auto *II = dyn_cast<InvokeInst>(TI)) { + changeToCall(II); + return; + } + + TerminatorInst *NewTI; + BasicBlock *UnwindDest; + + if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) { + NewTI = CleanupReturnInst::Create(CRI->getCleanupPad(), nullptr, CRI); + UnwindDest = CRI->getUnwindDest(); + } else if (auto *CEP = dyn_cast<CleanupEndPadInst>(TI)) { + NewTI = CleanupEndPadInst::Create(CEP->getCleanupPad(), nullptr, CEP); + UnwindDest = CEP->getUnwindDest(); + } else if (auto *CEP = dyn_cast<CatchEndPadInst>(TI)) { + NewTI = CatchEndPadInst::Create(CEP->getContext(), nullptr, CEP); + UnwindDest = CEP->getUnwindDest(); + } else if (auto *TPI = dyn_cast<TerminatePadInst>(TI)) { + SmallVector<Value *, 3> TerminatePadArgs; + for (Value *Operand : TPI->arg_operands()) + TerminatePadArgs.push_back(Operand); + NewTI = TerminatePadInst::Create(TPI->getContext(), nullptr, + TerminatePadArgs, TPI); + UnwindDest = TPI->getUnwindDest(); + } else { + llvm_unreachable("Could not find unwind successor"); + } + + NewTI->takeName(TI); + NewTI->setDebugLoc(TI->getDebugLoc()); + UnwindDest->removePredecessor(BB); + TI->eraseFromParent(); +} + /// removeUnreachableBlocksFromFn - Remove blocks that are not reachable, even /// if they are in a dead cycle. Return true if a change was made, false /// otherwise. |