summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SjLjEHPrepare.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2009-08-20 01:03:48 +0000
committerJim Grosbach <grosbach@apple.com>2009-08-20 01:03:48 +0000
commit8fc3b6903ac555e21d6c64c34f9815781e68c88b (patch)
treeb51fbe7ab0d51de5e80f3ee305af67b8ad2bcf34 /lib/CodeGen/SjLjEHPrepare.cpp
parentf636b9698c61cf346a11b778391c53326b52d3be (diff)
downloadllvm-8fc3b6903ac555e21d6c64c34f9815781e68c88b.tar.gz
llvm-8fc3b6903ac555e21d6c64c34f9815781e68c88b.tar.bz2
llvm-8fc3b6903ac555e21d6c64c34f9815781e68c88b.tar.xz
Check for shared landing pads when assigning call site values. Invokes which
share a landing pad should also use the same call site value. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79501 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SjLjEHPrepare.cpp')
-rw-r--r--lib/CodeGen/SjLjEHPrepare.cpp54
1 files changed, 34 insertions, 20 deletions
diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp
index 58b5213a0e..91a85c0719 100644
--- a/lib/CodeGen/SjLjEHPrepare.cpp
+++ b/lib/CodeGen/SjLjEHPrepare.cpp
@@ -24,6 +24,7 @@
#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"
@@ -69,8 +70,7 @@ namespace {
private:
void markInvokeCallSite(InvokeInst *II, unsigned InvokeNo,
- Value *CallSite,
- SwitchInst *CatchSwitch);
+ Value *CallSite);
void splitLiveRangesLiveAcrossInvokes(SmallVector<InvokeInst*,16> &Invokes);
bool insertSjLjEHSupport(Function &F);
};
@@ -125,14 +125,9 @@ 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,
- SwitchInst *CatchSwitch) {
+ Value *CallSite) {
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())) {
@@ -149,8 +144,6 @@ 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?
@@ -294,13 +287,6 @@ 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
@@ -472,11 +458,32 @@ 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.
- for (unsigned i = 0, e = Invokes.size(); i != e; ++i)
- markInvokeCallSite(Invokes[i], i+1, CallSite, DispatchSwitch);
+ 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);
+ }
// 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.
@@ -504,6 +511,13 @@ 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)