[llvm-commits] [llvm] r79501 - /llvm/trunk/lib/CodeGen/SjLjEHPrepare.cpp

Jim Grosbach grosbach at apple.com
Wed Aug 19 18:03:49 PDT 2009


Author: grosbach
Date: Wed Aug 19 20:03:48 2009
New Revision: 79501

URL: http://llvm.org/viewvc/llvm-project?rev=79501&view=rev
Log:
Check for shared landing pads when assigning call site values. Invokes which
share a landing pad should also use the same call site value.

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

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

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