[llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Oct 31 22:54:12 PST 2004



Changes in directory llvm/lib/Transforms/Utils:

SimplifyCFG.cpp updated: 1.56 -> 1.57
---
Log message:

Do not compute the predecessor list for a block unless we need it.
This speeds up simplifycfg on this program, from 44.87s to 0.29s (with
a profiled build):

 #define CL0(a) case a: goto c;
 #define CL1(a) CL0(a##0) CL0(a##1) CL0(a##2) CL0(a##3) CL0(a##4) CL0(a##5) \
 CL0(a##6) CL0(a##7) CL0(a##8) CL0(a##9)
 #define CL2(a) CL1(a##0) CL1(a##1) CL1(a##2) CL1(a##3) CL1(a##4) CL1(a##5) \
 CL1(a##6) CL1(a##7) CL1(a##8) CL1(a##9)
 #define CL3(a) CL2(a##0) CL2(a##1) CL2(a##2) CL2(a##3) CL2(a##4) CL2(a##5) \
 CL2(a##6) CL2(a##7) CL2(a##8) CL2(a##9)
 #define CL4(a) CL3(a##0) CL3(a##1) CL3(a##2) CL3(a##3) CL3(a##4) CL3(a##5) \
 CL3(a##6) CL3(a##7) CL3(a##8) CL3(a##9)

 void f();

 void a() {
     int b;
  c: switch (b) {
         CL4(1)
     }
 }

This testcase is contrived to expose N^2 behavior, but this patch should speedup
simplifycfg on any programs that use large switch statements.  This testcase 
comes from GCC PR17895: http://llvm.cs.uiuc.edu/PR17895 .



---
Diffs of the changes:  (+24 -27)

Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.56 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.57
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.56	Fri Oct 22 11:10:39 2004
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp	Mon Nov  1 00:53:58 2004
@@ -608,31 +608,29 @@
   // to the successor.
   succ_iterator SI(succ_begin(BB));
   if (SI != succ_end(BB) && ++SI == succ_end(BB)) {  // One succ?
-
     BasicBlock::iterator BBI = BB->begin();  // Skip over phi nodes...
     while (isa<PHINode>(*BBI)) ++BBI;
 
-    if (BBI->isTerminator()) {   // Terminator is the only non-phi instruction!
-      BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor
-     
-      if (Succ != BB) {   // Arg, don't hurt infinite loops!
-        // If our successor has PHI nodes, then we need to update them to
-        // include entries for BB's predecessors, not for BB itself.
-        // Be careful though, if this transformation fails (returns true) then
-        // we cannot do this transformation!
-        //
-	if (!PropagatePredecessorsForPHIs(BB, Succ)) {
-          DEBUG(std::cerr << "Killing Trivial BB: \n" << *BB);
-          std::string OldName = BB->getName();
-
+    BasicBlock *Succ = *succ_begin(BB); // There is exactly one successor.
+    if (BBI->isTerminator() &&  // Terminator is the only non-phi instruction!
+        Succ != BB) {           // Don't hurt infinite loops!
+      // If our successor has PHI nodes, then we need to update them to include
+      // entries for BB's predecessors, not for BB itself.  Be careful though,
+      // if this transformation fails (returns true) then we cannot do this
+      // transformation!
+      //
+      if (!PropagatePredecessorsForPHIs(BB, Succ)) {
+        DEBUG(std::cerr << "Killing Trivial BB: \n" << *BB);
+        
+        if (isa<PHINode>(&BB->front())) {
           std::vector<BasicBlock*>
             OldSuccPreds(pred_begin(Succ), pred_end(Succ));
-
+        
           // Move all PHI nodes in BB to Succ if they are alive, otherwise
           // delete them.
           while (PHINode *PN = dyn_cast<PHINode>(&BB->front()))
             if (PN->use_empty())
-              BB->getInstList().erase(BB->begin());  // Nuke instruction...
+              BB->getInstList().erase(BB->begin());  // Nuke instruction.
             else {
               // The instruction is alive, so this means that Succ must have
               // *ONLY* had BB as a predecessor, and the PHI node is still valid
@@ -640,7 +638,7 @@
               // strictly dominated Succ.
               BB->getInstList().remove(BB->begin());
               Succ->getInstList().push_front(PN);
-
+              
               // We need to add new entries for the PHI node to account for
               // predecessors of Succ that the PHI node does not take into
               // account.  At this point, since we know that BB dominated succ,
@@ -651,17 +649,16 @@
                 if (OldSuccPreds[i] != BB)
                   PN->addIncoming(PN, OldSuccPreds[i]);
             }
+        }
+        
+        // Everything that jumped to BB now goes to Succ.
+        std::string OldName = BB->getName();
+        BB->replaceAllUsesWith(Succ);
+        BB->eraseFromParent();              // Delete the old basic block.
 
-          // Everything that jumped to BB now goes to Succ...
-          BB->replaceAllUsesWith(Succ);
-
-          // Delete the old basic block...
-          M->getBasicBlockList().erase(BB);
-	
-          if (!OldName.empty() && !Succ->hasName())  // Transfer name if we can
-            Succ->setName(OldName);
-          return true;
-	}
+        if (!OldName.empty() && !Succ->hasName())  // Transfer name if we can
+          Succ->setName(OldName);
+        return true;
       }
     }
   }






More information about the llvm-commits mailing list