PR4747
authorJim Grosbach <grosbach@apple.com>
Mon, 31 Aug 2009 01:35:03 +0000 (01:35 +0000)
committerJim Grosbach <grosbach@apple.com>
Mon, 31 Aug 2009 01:35:03 +0000 (01:35 +0000)
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

lib/CodeGen/AsmPrinter/DwarfException.cpp
lib/CodeGen/SjLjEHPrepare.cpp

index e32447392f45a61c3192c7e62c85511613303e11..0371d64e91d589f2aad72449ff03a36d5047ed62 100644 (file)
@@ -468,8 +468,9 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
           FirstActions[P.PadIndex]
         };
 
-        // Try to merge with the previous call-site.
-        if (PreviousIsInvoke) {
+        // Try to merge with the previous call-site. SJLJ doesn't do this
+        if (PreviousIsInvoke &&
+          MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
           CallSiteEntry &Prev = CallSites.back();
           if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
             // Extend the range of the previous entry.
index 61f13abcdaf017bd5cd025cee77ea79bd9e99b1f..38996ff6cda4eadae5c59b1e032f10e505f685de 100644 (file)
@@ -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)