[llvm-commits] CVS: llvm/lib/Transforms/IPO/LowerSetJmp.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Oct 12 19:58:01 PDT 2003


Changes in directory llvm/lib/Transforms/IPO:

LowerSetJmp.cpp updated: 1.4 -> 1.5

---
Log message:

Checkin an improvement contributed by Bill:

Only transform call sites in a setjmp'ing function which are reachable from 
the setjmp.  If the call dominates the setjmp (for example), the called 
function cannot longjmp to the setjmp.

This dramatically reduces the number of invoke instructions created in some
large testcases.



---
Diffs of the changes:  (+30 -6)

Index: llvm/lib/Transforms/IPO/LowerSetJmp.cpp
diff -u llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.4 llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.5
--- llvm/lib/Transforms/IPO/LowerSetJmp.cpp:1.4	Mon Sep 22 16:57:15 2003
+++ llvm/lib/Transforms/IPO/LowerSetJmp.cpp	Sun Oct 12 19:57:16 2003
@@ -32,14 +32,13 @@
 #include "llvm/Intrinsics.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
-#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/CFG.h"
 #include "llvm/Support/InstVisitor.h"
+#include "Support/DepthFirstIterator.h"
 #include "Support/Statistic.h"
 #include "Support/StringExtras.h"
 #include "Support/VectorExtras.h"
 
-#include <set>
-
 namespace {
   Statistic<> LongJmpsTransformed("lowersetjmp",
                                   "Number of longjmps transformed");
@@ -64,6 +63,11 @@
 
     typedef std::pair<SwitchInst*, CallInst*> SwitchValuePair;
 
+    // Keep track of those basic blocks reachable via a depth-first search of
+    // the CFG from a setjmp call. We only need to transform those "call" and
+    // "invoke" instructions that are reachable from the setjmp call site.
+    std::set<BasicBlock*> DFSBlocks;
+
     // The setjmp map is going to hold information about which setjmps
     // were called (each setjmp gets its own number) and with which
     // buffer it was called.
@@ -127,13 +131,24 @@
   // setjmp/longjmp functions.
   doInitialization(M);
 
-  if (SetJmp)
+  if (SetJmp) {
+    std::set<BasicBlock*> BBSet;
+    
+    for (Value::use_iterator B = SetJmp->use_begin(), E = SetJmp->use_end();
+         B != E; ++B) {
+      Instruction* I = cast<Instruction>(*B);
+      BasicBlock* BB = I->getParent();
+      Function* Func = BB->getParent();
+      DFSBlocks.insert(df_begin(BB), df_end(BB));
+    }
+
     while (!SetJmp->use_empty()) {
       assert(isa<CallInst>(SetJmp->use_back()) &&
              "User of setjmp intrinsic not a call?");
       TransformSetJmpCall(cast<CallInst>(SetJmp->use_back()));
       Changed = true;
     }
+  }
 
   if (LongJmp)
     while (!LongJmp->use_empty()) {
@@ -156,6 +171,7 @@
       }
   }
 
+  DFSBlocks.clear();
   SJMap.clear();
   RethrowBBMap.clear();
   PrelimBBMap.clear();
@@ -398,12 +414,16 @@
         CI.getCalledFunction()->isIntrinsic()) return;
 
   BasicBlock* OldBB = CI.getParent();
+  Function* Func = OldBB->getParent();
+
+  // If not reachable from a setjmp call, don't transform.
+  if (!DFSBlocks.count(OldBB)) return;
+
   BasicBlock* NewBB = OldBB->splitBasicBlock(CI);
   assert(NewBB && "Couldn't split BB of \"call\" instruction!!");
   NewBB->setName("Call2Invoke");
 
   // Reposition the split BB in the BB list to make things tidier.
-  Function* Func = OldBB->getParent();
   Func->getBasicBlockList().remove(NewBB);
   Func->getBasicBlockList().insert(++Function::iterator(OldBB), NewBB);
 
@@ -432,7 +452,11 @@
     if (!IsTransformableFunction(II.getCalledFunction()->getName()) ||
         II.getCalledFunction()->isIntrinsic()) return;
 
-  Function* Func = II.getParent()->getParent();
+  BasicBlock* BB = II.getParent();
+  Function* Func = BB->getParent();
+
+  // If not reachable from a setjmp call, don't transform.
+  if (!DFSBlocks.count(BB)) return;
 
   BasicBlock* NormalBB = II.getNormalDest();
   BasicBlock* ExceptBB = II.getExceptionalDest();





More information about the llvm-commits mailing list