[llvm-commits] [llvm] r80530 - in /llvm/trunk/lib/CodeGen: AsmPrinter/DwarfException.cpp SjLjEHPrepare.cpp

Jim Grosbach grosbach at apple.com
Sun Aug 30 18:35:04 PDT 2009


Author: grosbach
Date: Sun Aug 30 20:35:03 2009
New Revision: 80530

URL: http://llvm.org/viewvc/llvm-project?rev=80530&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp
    llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=80530&r1=80529&r2=80530&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Sun Aug 30 20:35:03 2009
@@ -468,8 +468,9 @@
           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.

Modified: llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp?rev=80530&r1=80529&r2=80530&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp Sun Aug 30 20:35:03 2009
@@ -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 @@
 
   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 @@
 
 /// 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 @@
   // 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 @@
   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 @@
                        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 @@
       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)





More information about the llvm-commits mailing list