[llvm-commits] [llvm] r69102 - in /llvm/trunk: lib/Transforms/Scalar/CondPropagate.cpp test/Transforms/CondProp/phisimplify3.ll

Evan Cheng evan.cheng at apple.com
Tue Apr 14 16:40:03 PDT 2009


Author: evancheng
Date: Tue Apr 14 18:40:03 2009
New Revision: 69102

URL: http://llvm.org/viewvc/llvm-project?rev=69102&view=rev
Log:
Optimize conditional branch on i1 phis with non-constant inputs.

This turns:

eq:
        %3 = icmp eq i32 %1, %2
        br label %join

ne:
        %4 = icmp ne i32 %1, %2
        br label %join

join:
        %5 = phi i1 [%3, %eq], [%4, %ne]
        br i1 %5, label %yes, label %no

=>

eq:
        %3 = icmp eq i32 %1, %2
        br i1 %3, label %yes, label %no

ne:
        %4 = icmp ne i32 %1, %2
        br i1 %4, label %yes, label %no

Added:
    llvm/trunk/test/Transforms/CondProp/phisimplify3.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp?rev=69102&r1=69101&r2=69102&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/CondPropagate.cpp Tue Apr 14 18:40:03 2009
@@ -51,6 +51,7 @@
     void SimplifyPredecessors(BranchInst *BI);
     void SimplifyPredecessors(SwitchInst *SI);
     void RevectorBlockTo(BasicBlock *FromBB, BasicBlock *ToBB);
+    bool RevectorBlockTo(BasicBlock *FromBB, Value *Cond, BranchInst *BI);
   };
 }
   
@@ -160,20 +161,19 @@
   // Ok, we have this really simple case, walk the PHI operands, looking for
   // constants.  Walk from the end to remove operands from the end when
   // possible, and to avoid invalidating "i".
-  for (unsigned i = PN->getNumIncomingValues(); i != 0; --i)
-    if (ConstantInt *CB = dyn_cast<ConstantInt>(PN->getIncomingValue(i-1))) {
-      // If we have a constant, forward the edge from its current to its
-      // ultimate destination.
-      RevectorBlockTo(PN->getIncomingBlock(i-1),
-                      BI->getSuccessor(CB->isZero()));
-      ++NumBrThread;
-
-      // If there were two predecessors before this simplification, or if the
-      // PHI node contained all the same value except for the one we just
-      // substituted, the PHI node may be deleted.  Don't iterate through it the
-      // last time.
-      if (BI->getCondition() != PN) return;
-    }
+  for (unsigned i = PN->getNumIncomingValues(); i != 0; --i) {
+    Value *InVal = PN->getIncomingValue(i-1);
+    if (!RevectorBlockTo(PN->getIncomingBlock(i-1), InVal, BI))
+      continue;
+
+    ++NumBrThread;
+
+    // If there were two predecessors before this simplification, or if the
+    // PHI node contained all the same value except for the one we just
+    // substituted, the PHI node may be deleted.  Don't iterate through it the
+    // last time.
+    if (BI->getCondition() != PN) return;
+  }
 }
 
 // SimplifyPredecessors(switch) - We know that SI is switch based on a PHI node
@@ -242,3 +242,44 @@
 
   MadeChange = true;
 }
+
+bool CondProp::RevectorBlockTo(BasicBlock *FromBB, Value *Cond, BranchInst *BI){
+  BranchInst *FromBr = cast<BranchInst>(FromBB->getTerminator());
+  if (!FromBr->isUnconditional())
+    return false;
+
+  // Get the old block we are threading through.
+  BasicBlock *OldSucc = FromBr->getSuccessor(0);
+
+  // If the condition is a constant, simply revector the unconditional branch at
+  // the end of FromBB to one of the successors of its current successor.
+  if (ConstantInt *CB = dyn_cast<ConstantInt>(Cond)) {
+    BasicBlock *ToBB = BI->getSuccessor(CB->isZero());
+
+    // OldSucc had multiple successors. If ToBB has multiple predecessors, then 
+    // the edge between them would be critical, which we already took care of.
+    // If ToBB has single operand PHI node then take care of it here.
+    FoldSingleEntryPHINodes(ToBB);
+
+    // Update PHI nodes in OldSucc to know that FromBB no longer branches to it.
+    OldSucc->removePredecessor(FromBB);
+
+    // Change FromBr to branch to the new destination.
+    FromBr->setSuccessor(0, ToBB);
+  } else {
+    // Insert the new conditional branch.
+    BranchInst::Create(BI->getSuccessor(0), BI->getSuccessor(1), Cond, FromBr);
+
+    FoldSingleEntryPHINodes(BI->getSuccessor(0));
+    FoldSingleEntryPHINodes(BI->getSuccessor(1));
+
+    // Update PHI nodes in OldSucc to know that FromBB no longer branches to it.
+    OldSucc->removePredecessor(FromBB);
+
+    // Delete the old branch.
+    FromBr->eraseFromParent();
+  }
+
+  MadeChange = true;
+  return true;
+}

Added: llvm/trunk/test/Transforms/CondProp/phisimplify3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CondProp/phisimplify3.ll?rev=69102&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/CondProp/phisimplify3.ll (added)
+++ llvm/trunk/test/Transforms/CondProp/phisimplify3.ll Tue Apr 14 18:40:03 2009
@@ -0,0 +1,26 @@
+; RUN: llvm-as < %s | opt -condprop | llvm-dis | not grep phi
+
+define i32 @foo(i1, i32, i32) {
+prologue:
+	br i1 %0, label %eq, label %ne
+
+eq:		; preds = %prologue
+	store i32 0, i32* inttoptr (i32 10000 to i32*)
+	%3 = icmp eq i32 %1, %2		; <i1> [#uses=1]
+	br label %join
+
+ne:		; preds = %prologue
+	%4 = icmp ne i32 %1, %2		; <i1> [#uses=1]
+	br label %join
+
+join:		; preds = %ne, %eq
+	%5 = phi i1 [ %3, %eq ], [ %4, %ne ]		; <i1> [#uses=1]
+	br i1 %5, label %yes, label %no
+
+yes:		; preds = %join
+	store i32 0, i32* inttoptr (i32 20000 to i32*)
+	ret i32 5
+
+no:		; preds = %join
+	ret i32 20
+}





More information about the llvm-commits mailing list