[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