[llvm-commits] [llvm] r61100 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll

Eli Friedman eli.friedman at gmail.com
Tue Dec 16 12:54:33 PST 2008


Author: efriedma
Date: Tue Dec 16 14:54:32 2008
New Revision: 61100

URL: http://llvm.org/viewvc/llvm-project?rev=61100&view=rev
Log:
Add a helper to remove a branch and DCE the condition, and use it 
consistently for deleting branches.  In addition to being slightly 
more readable, this makes SimplifyCFG a bit better 
about cleaning up after itself when it makes conditions unused.


Added:
    llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=61100&r1=61099&r2=61100&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Tue Dec 16 14:54:32 2008
@@ -386,6 +386,7 @@
         // We can hoist loads that are non-volatile and obviously cannot trap.
         if (cast<LoadInst>(I)->isVolatile())
           return false;
+        // FIXME: A computation of a constant can trap!
         if (!isa<AllocaInst>(I->getOperand(0)) &&
             !isa<Constant>(I->getOperand(0)))
           return false;
@@ -494,6 +495,19 @@
   return false;
 }
 
+static void EraseTerminatorInstAndDCECond(TerminatorInst *TI) {
+  Instruction* Cond = 0;
+  if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
+    Cond = dyn_cast<Instruction>(SI->getCondition());
+  } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
+    if (BI->isConditional())
+      Cond = dyn_cast<Instruction>(BI->getCondition());
+  }
+
+  TI->eraseFromParent();
+  if (Cond) RecursivelyDeleteTriviallyDeadInstructions(Cond);
+}
+
 /// isValueEqualityComparison - Return true if the specified terminator checks
 /// to see if a value is equal to constant integer value.
 static Value *isValueEqualityComparison(TerminatorInst *TI) {
@@ -617,11 +631,10 @@
     // PredCases.  If there are any cases in ThisCases that are in PredCases, we
     // can simplify TI.
     if (ValuesOverlap(PredCases, ThisCases)) {
-      if (BranchInst *BTI = dyn_cast<BranchInst>(TI)) {
+      if (isa<BranchInst>(TI)) {
         // Okay, one of the successors of this condbr is dead.  Convert it to a
         // uncond br.
         assert(ThisCases.size() == 1 && "Branch can only have one case!");
-        Value *Cond = BTI->getCondition();
         // Insert the new branch.
         Instruction *NI = BranchInst::Create(ThisDef, TI);
 
@@ -631,10 +644,7 @@
         DOUT << "Threading pred instr: " << *Pred->getTerminator()
              << "Through successor TI: " << *TI << "Leaving: " << *NI << "\n";
 
-        TI->eraseFromParent();   // Nuke the old one.
-        // If condition is now dead, nuke it.
-        if (Instruction *CondI = dyn_cast<Instruction>(Cond))
-          RecursivelyDeleteTriviallyDeadInstructions(CondI);
+        EraseTerminatorInstAndDCECond(TI);
         return true;
 
       } else {
@@ -697,12 +707,8 @@
 
     DOUT << "Threading pred instr: " << *Pred->getTerminator()
          << "Through successor TI: " << *TI << "Leaving: " << *NI << "\n";
-    Instruction *Cond = 0;
-    if (BranchInst *BI = dyn_cast<BranchInst>(TI))
-      Cond = dyn_cast<Instruction>(BI->getCondition());
-    TI->eraseFromParent();   // Nuke the old one.
 
-    if (Cond) RecursivelyDeleteTriviallyDeadInstructions(Cond);
+    EraseTerminatorInstAndDCECond(TI);
     return true;
   }
   return false;
@@ -811,14 +817,7 @@
       for (unsigned i = 0, e = PredCases.size(); i != e; ++i)
         NewSI->addCase(PredCases[i].first, PredCases[i].second);
 
-      Instruction *DeadCond = 0;
-      if (BranchInst *BI = dyn_cast<BranchInst>(PTI))
-        // If PTI is a branch, remember the condition.
-        DeadCond = dyn_cast<Instruction>(BI->getCondition());
-      Pred->getInstList().erase(PTI);
-
-      // If the condition is dead now, remove the instruction tree.
-      if (DeadCond) RecursivelyDeleteTriviallyDeadInstructions(DeadCond);
+      EraseTerminatorInstAndDCECond(PTI);
 
       // Okay, last check.  If BB is still a successor of PSI, then we must
       // have an infinite loop case.  If so, add an infinitely looping block
@@ -921,7 +920,7 @@
   for (succ_iterator SI = succ_begin(BB1), E = succ_end(BB1); SI != E; ++SI)
     AddPredecessorToBlock(*SI, BIParent, BB1);
 
-  BI->eraseFromParent();
+  EraseTerminatorInstAndDCECond(BI);
   return true;
 }
 
@@ -1331,7 +1330,7 @@
     TrueSucc->removePredecessor(BI->getParent());
     FalseSucc->removePredecessor(BI->getParent());
     ReturnInst::Create(0, BI);
-    BI->eraseFromParent();
+    EraseTerminatorInstAndDCECond(BI);
     return true;
   }
     
@@ -1386,10 +1385,8 @@
        << "\n  " << *BI << "NewRet = " << *RI
        << "TRUEBLOCK: " << *TrueSucc << "FALSEBLOCK: "<< *FalseSucc;
       
-  BI->eraseFromParent();
-  
-  if (Instruction *BrCondI = dyn_cast<Instruction>(BrCond))
-    RecursivelyDeleteTriviallyDeadInstructions(BrCondI);
+  EraseTerminatorInstAndDCECond(BI);
+
   return true;
 }
 
@@ -1910,10 +1907,10 @@
           } else {
             if (BI->getSuccessor(0) == BB) {
               BranchInst::Create(BI->getSuccessor(1), BI);
-              BI->eraseFromParent();
+              EraseTerminatorInstAndDCECond(BI);
             } else if (BI->getSuccessor(1) == BB) {
               BranchInst::Create(BI->getSuccessor(0), BI);
-              BI->eraseFromParent();
+              EraseTerminatorInstAndDCECond(BI);
               Changed = true;
             }
           }
@@ -2086,11 +2083,7 @@
           }
 
           // Erase the old branch instruction.
-          (*PI)->getInstList().erase(BI);
-
-          // Erase the potentially condition tree that was used to computed the
-          // branch condition.
-          RecursivelyDeleteTriviallyDeadInstructions(Cond);
+          EraseTerminatorInstAndDCECond(BI);
           return true;
         }
       }

Added: llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll?rev=61100&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyCFG/2008-12-16-DCECond.ll Tue Dec 16 14:54:32 2008
@@ -0,0 +1,46 @@
+; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | not grep icmp
+; ModuleID = '/tmp/x.bc'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i686-pc-linux-gnu"
+
+define i32 @x(i32 %x) {
+entry:
+	%cmp = icmp eq i32 %x, 8		; <i1> [#uses=1]
+	br i1 %cmp, label %ifthen, label %ifend
+
+ifthen:		; preds = %entry
+	%call = call i32 (...)* @foo()		; <i32> [#uses=0]
+	br label %ifend
+
+ifend:		; preds = %ifthen, %entry
+	%cmp2 = icmp ne i32 %x, 8		; <i1> [#uses=1]
+	br i1 %cmp2, label %ifthen3, label %ifend5
+
+ifthen3:		; preds = %ifend
+	%call4 = call i32 (...)* @foo()		; <i32> [#uses=0]
+	br label %ifend5
+
+ifend5:		; preds = %ifthen3, %ifend
+	%cmp7 = icmp eq i32 %x, 9		; <i1> [#uses=1]
+	br i1 %cmp7, label %ifthen8, label %ifend10
+
+ifthen8:		; preds = %ifend5
+	%call9 = call i32 (...)* @bar()		; <i32> [#uses=0]
+	br label %ifend10
+
+ifend10:		; preds = %ifthen8, %ifend5
+	%cmp12 = icmp ne i32 %x, 9		; <i1> [#uses=1]
+	br i1 %cmp12, label %ifthen13, label %ifend15
+
+ifthen13:		; preds = %ifend10
+	%call14 = call i32 (...)* @bar()		; <i32> [#uses=0]
+	br label %ifend15
+
+ifend15:		; preds = %ifthen13, %ifend10
+	ret i32 0
+}
+
+declare i32 @foo(...)
+
+declare i32 @bar(...)
+





More information about the llvm-commits mailing list