summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SjLjEHPrepare.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2009-08-31 01:35:03 +0000
committerJim Grosbach <grosbach@apple.com>2009-08-31 01:35:03 +0000
commit0bb61c56bcad7a738d50f705b5966be446ef06c1 (patch)
tree60a257049a2b00eaa38d7c414ecc4f2486173b4a /lib/CodeGen/SjLjEHPrepare.cpp
parent5e794d40b8fc112ca55dfb66fc2249c6bfaa75a9 (diff)
downloadllvm-0bb61c56bcad7a738d50f705b5966be446ef06c1.tar.gz
llvm-0bb61c56bcad7a738d50f705b5966be446ef06c1.tar.bz2
llvm-0bb61c56bcad7a738d50f705b5966be446ef06c1.tar.xz
PR4747
Shared landing pads run into trouble with SJLJ, as the dispatch table is mapped to call sites, and merging the pads will throw that off. There needs to be a one-to-one mapping of landing pad exception table entries to invoke call points. Detecting the shared pad during lowering of SJLJ info insn't sufficient, as the dispatch function may still need separate destinations to properly handle phi-nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80530 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SjLjEHPrepare.cpp')
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp54
1 files changed, 20 insertions, 34 deletions
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index 61f13abcda..38996ff6cd 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -24,7 +24,6 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
@@ -70,7 +69,8 @@ namespace {
private:
void markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
- Value *CallSite);
+ Value *CallSite,
+ SwitchInst *CatchSwitch);
void splitLiveRangesLiveAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes);
bool insertSjLjEHSupport(Function &F);
};
@@ -126,9 +126,14 @@ bool SjLjEHPass::doInitialization(Module &M) {
/// markInvokeCallSite - Insert code to mark the call_site for this invoke
void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
- Value *CallSite) {
+ Value *CallSite,
+ SwitchInst *CatchSwitch) {
ConstantInt *CallSiteNoC= ConstantInt::get(Type::getInt32Ty(II->getContext()),
InvokeNo);
+ // The runtime comes back to the dispatcher with the call_site - 1 in
+ // the context. Odd, but there it is.
+ ConstantInt *SwitchValC = ConstantInt::get(Type::getInt32Ty(II->getContext()),
+ InvokeNo - 1);
// If the unwind edge has phi nodes, split the edge.
if (isa<PHINode>(II->getUnwindDest()->begin())) {
@@ -145,6 +150,8 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
// location afterward.
new StoreInst(CallSiteNoC, CallSite, true, II); // volatile
+ // Add a switch case to our unwind block.
+ CatchSwitch->addCase(SwitchValC, II->getUnwindDest());
// We still want this to look like an invoke so we emit the LSDA properly
// FIXME: ??? Or will this cause strangeness with mis-matched IDs like
// when it was in the front end?
@@ -311,6 +318,13 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
if (!Invokes.empty()) {
// We have invokes, so we need to add register/unregister calls to get
// this function onto the global unwind stack.
+ //
+ // First thing we need to do is scan the whole function for values that are
+ // live across unwind edges. Each value that is live across an unwind edge
+ // we spill into a stack location, guaranteeing that there is nothing live
+ // across the unwind edge. This process also splits all critical edges
+ // coming out of invoke's.
+ splitLiveRangesLiveAcrossInvokes(Invokes);
BasicBlock *EntryBB = F.begin();
// Create an alloca for the incoming jump buffer ptr and the new jump buffer
@@ -462,32 +476,11 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
ContBlock->getTerminator());
Register->setDoesNotThrow();
- // At this point, we are all set up. Update the invoke instructions
+ // At this point, we are all set up, update the invoke instructions
// to mark their call_site values, and fill in the dispatch switch
// accordingly.
- DenseMap<BasicBlock*,unsigned> PadSites;
- unsigned NextCallSiteValue = 1;
- for (SmallVector<InvokeInst*,16>::iterator I = Invokes.begin(),
- E = Invokes.end(); I < E; ++I) {
- unsigned CallSiteValue;
- BasicBlock *LandingPad = (*I)->getSuccessor(1);
- // landing pads can be shared. If we see a landing pad again, we
- // want to make sure to use the same call site index so the dispatch
- // will go to the right place.
- CallSiteValue = PadSites[LandingPad];
- if (!CallSiteValue) {
- CallSiteValue = NextCallSiteValue++;
- PadSites[LandingPad] = CallSiteValue;
- // Add a switch case to our unwind block. The runtime comes back
- // to the dispatcher with the call_site - 1 in the context. Odd,
- // but there it is.
- ConstantInt *SwitchValC =
- ConstantInt::get(Type::getInt32Ty((*I)->getContext()),
- CallSiteValue - 1);
- DispatchSwitch->addCase(SwitchValC, (*I)->getUnwindDest());
- }
- markInvokeCallSite(*I, CallSiteValue, CallSite);
- }
+ for (unsigned i = 0, e = Invokes.size(); i != e; ++i)
+ markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch);
// The front end has likely added calls to _Unwind_Resume. We need
// to find those calls and mark the call_site as -1 immediately prior.
@@ -515,13 +508,6 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) {
Unwinds[i]->eraseFromParent();
}
- // Scan the whole function for values that are live across unwind edges.
- // Each value that is live across an unwind edge we spill into a stack
- // location, guaranteeing that there is nothing live across the unwind
- // edge. This process also splits all critical edges coming out of
- // invoke's.
- splitLiveRangesLiveAcrossInvokes(Invokes);
-
// Finally, for any returns from this function, if this function contains an
// invoke, add a call to unregister the function context.
for (unsigned i = 0, e = Returns.size(); i != e; ++i)