[llvm-commits] [llvm] r50106 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/and-and-cond.ll

Chris Lattner sabre at nondot.org
Tue Apr 22 13:46:09 PDT 2008


Author: lattner
Date: Tue Apr 22 15:46:09 2008
New Revision: 50106

URL: http://llvm.org/viewvc/llvm-project?rev=50106&view=rev
Log:
Dig through multiple levels of AND to thread jumps if needed.

Added:
    llvm/trunk/test/Transforms/JumpThreading/and-and-cond.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp

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

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Apr 22 15:46:09 2008
@@ -60,7 +60,7 @@
     BasicBlock *FactorCommonPHIPreds(PHINode *PN, Constant *CstVal);
 
     bool ProcessJumpOnPHI(PHINode *PN);
-    bool ProcessJumpOnLogicalPHI(PHINode *PN, bool isAnd);
+    bool ProcessBranchOnLogical(Value *V, BasicBlock *BB, bool isAnd);
   };
   char JumpThreading::ID = 0;
   RegisterPass<JumpThreading> X("jump-threading", "Jump Threading");
@@ -193,16 +193,10 @@
   if (BinaryOperator *CondI = dyn_cast<BinaryOperator>(Condition)) {
     if ((CondI->getOpcode() == Instruction::And || 
          CondI->getOpcode() == Instruction::Or) &&
-        isa<BranchInst>(BB->getTerminator())) {
-      if (PHINode *PN = dyn_cast<PHINode>(CondI->getOperand(0)))
-        if (PN->getParent() == BB &&
-            ProcessJumpOnLogicalPHI(PN, CondI->getOpcode() == Instruction::And))
-          return true;
-      if (PHINode *PN = dyn_cast<PHINode>(CondI->getOperand(1)))
-        if (PN->getParent() == BB &&
-            ProcessJumpOnLogicalPHI(PN, CondI->getOpcode() == Instruction::And))
-          return true;
-    }
+        isa<BranchInst>(BB->getTerminator()) &&
+        ProcessBranchOnLogical(CondI, BB,
+                               CondI->getOpcode() == Instruction::And))
+      return true;
   }
   
   return false;
@@ -270,8 +264,23 @@
 /// the predecessor corresponding to the 'false' will always jump to the false
 /// destination of the branch.
 ///
-bool JumpThreading::ProcessJumpOnLogicalPHI(PHINode *PN, bool isAnd) {
-  
+bool JumpThreading::ProcessBranchOnLogical(Value *V, BasicBlock *BB,
+                                           bool isAnd) {
+  // If this is a binary operator tree of the same AND/OR opcode, check the
+  // LHS/RHS.
+  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
+    if (isAnd && BO->getOpcode() == Instruction::And ||
+        !isAnd && BO->getOpcode() == Instruction::Or) {
+      if (ProcessBranchOnLogical(BO->getOperand(0), BB, isAnd))
+        return true;
+      if (ProcessBranchOnLogical(BO->getOperand(1), BB, isAnd))
+        return true;
+    }
+      
+  // If this isn't a PHI node, we can't handle it.
+  PHINode *PN = dyn_cast<PHINode>(V);
+  if (!PN || PN->getParent() != BB) return false;
+                                             
   // We can only do the simplification for phi nodes of 'false' with AND or
   // 'true' with OR.  See if we have any entries in the phi for this.
   unsigned PredNo = ~0U;
@@ -288,7 +297,6 @@
     return false;
   
   // See if the cost of duplicating this block is low enough.
-  BasicBlock *BB = PN->getParent();
   unsigned JumpThreadCost = getJumpThreadDuplicationCost(BB);
   if (JumpThreadCost > Threshold) {
     DOUT << "  Not threading BB '" << BB->getNameStart()

Added: llvm/trunk/test/Transforms/JumpThreading/and-and-cond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/and-and-cond.ll?rev=50106&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/JumpThreading/and-and-cond.ll (added)
+++ llvm/trunk/test/Transforms/JumpThreading/and-and-cond.ll Tue Apr 22 15:46:09 2008
@@ -0,0 +1,33 @@
+; RUN: llvm-as < %s | opt -jump-threading -mem2reg -instcombine -simplifycfg  | llvm-dis | grep {ret i32 %v1}
+; There should be no uncond branches left.
+; RUN: llvm-as < %s | opt -jump-threading -mem2reg -instcombine -simplifycfg  | llvm-dis | not grep {br label}
+
+declare i32 @f1()
+declare i32 @f2()
+declare void @f3()
+
+define i32 @test(i1 %cond, i1 %cond2, i1 %cond3) {
+	br i1 %cond, label %T1, label %F1
+
+T1:
+	%v1 = call i32 @f1()
+	br label %Merge
+
+F1:
+	%v2 = call i32 @f2()
+	br label %Merge
+
+Merge:
+	%A = phi i1 [true, %T1], [false, %F1]
+	%B = phi i32 [%v1, %T1], [%v2, %F1]
+	%C = and i1 %A, %cond2
+	%D = and i1 %C, %cond3
+	br i1 %D, label %T2, label %F2
+
+T2:
+	call void @f3()
+	ret i32 %B
+
+F2:
+	ret i32 %B
+}





More information about the llvm-commits mailing list