[llvm-commits] [llvm] r73755 - in /llvm/trunk: lib/Transforms/Scalar/JumpThreading.cpp test/Transforms/JumpThreading/branch-no-const.ll
Nick Lewycky
nicholas at mxc.ca
Thu Jun 18 21:56:29 PDT 2009
Author: nicholas
Date: Thu Jun 18 23:56:29 2009
New Revision: 73755
URL: http://llvm.org/viewvc/llvm-project?rev=73755&view=rev
Log:
Teach jump threading to look at comparisons between phi nodes and non-constants.
Added:
llvm/trunk/test/Transforms/JumpThreading/branch-no-const.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=73755&r1=73754&r2=73755&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Thu Jun 18 23:56:29 2009
@@ -76,7 +76,7 @@
bool ProcessBlock(BasicBlock *BB);
bool ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, BasicBlock *SuccBB,
unsigned JumpThreadCost);
- BasicBlock *FactorCommonPHIPreds(PHINode *PN, Constant *CstVal);
+ BasicBlock *FactorCommonPHIPreds(PHINode *PN, Value *Val);
bool ProcessBranchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB);
bool ProcessSwitchOnDuplicateCond(BasicBlock *PredBB, BasicBlock *DestBB);
@@ -163,10 +163,10 @@
/// This is important for things like "phi i1 [true, true, false, true, x]"
/// where we only need to clone the block for the true blocks once.
///
-BasicBlock *JumpThreading::FactorCommonPHIPreds(PHINode *PN, Constant *CstVal) {
+BasicBlock *JumpThreading::FactorCommonPHIPreds(PHINode *PN, Value *Val) {
SmallVector<BasicBlock*, 16> CommonPreds;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
- if (PN->getIncomingValue(i) == CstVal)
+ if (PN->getIncomingValue(i) == Val)
CommonPreds.push_back(PN->getIncomingBlock(i));
if (CommonPreds.size() == 1)
@@ -346,13 +346,19 @@
CondInst->getOpcode() == Instruction::And))
return true;
- // If we have "br (phi != 42)" and the phi node has any constant values as
- // operands, we can thread through this block.
- if (CmpInst *CondCmp = dyn_cast<CmpInst>(CondInst))
- if (isa<PHINode>(CondCmp->getOperand(0)) &&
- isa<Constant>(CondCmp->getOperand(1)) &&
- ProcessBranchOnCompare(CondCmp, BB))
- return true;
+ if (CmpInst *CondCmp = dyn_cast<CmpInst>(CondInst)) {
+ if (isa<PHINode>(CondCmp->getOperand(0))) {
+ // If we have "br (phi != 42)" and the phi node has any constant values
+ // as operands, we can thread through this block.
+ //
+ // If we have "br (cmp phi, x)" and the phi node contains x such that the
+ // comparison uniquely identifies the branch target, we can thread
+ // through this block.
+
+ if (ProcessBranchOnCompare(CondCmp, BB))
+ return true;
+ }
+ }
// Check for some cases that are worth simplifying. Right now we want to look
// for loads that are used by a switch or by the condition for the branch. If
@@ -770,12 +776,30 @@
return ThreadEdge(BB, PredBB, SuccBB, JumpThreadCost);
}
+/// GetResultOfComparison - Given an icmp/fcmp predicate and the left and right
+/// hand sides of the compare instruction, try to determine the result. If the
+/// result can not be determined, a null pointer is returned.
+static Constant *GetResultOfComparison(CmpInst::Predicate pred,
+ Value *LHS, Value *RHS) {
+ if (Constant *CLHS = dyn_cast<Constant>(LHS))
+ if (Constant *CRHS = dyn_cast<Constant>(RHS))
+ return ConstantExpr::getCompare(pred, CLHS, CRHS);
+
+ if (LHS == RHS)
+ if (isa<IntegerType>(LHS->getType()) || isa<PointerType>(LHS->getType()))
+ return ICmpInst::isTrueWhenEqual(pred) ?
+ ConstantInt::getTrue() : ConstantInt::getFalse();
+
+ return 0;
+}
+
/// ProcessBranchOnCompare - We found a branch on a comparison between a phi
-/// node and a constant. If the PHI node contains any constants as inputs, we
-/// can fold the compare for that edge and thread through it.
+/// node and a value. If we can identify when the comparison is true between
+/// the phi inputs and the value, we can fold the compare for that edge and
+/// thread through it.
bool JumpThreading::ProcessBranchOnCompare(CmpInst *Cmp, BasicBlock *BB) {
PHINode *PN = cast<PHINode>(Cmp->getOperand(0));
- Constant *RHS = cast<Constant>(Cmp->getOperand(1));
+ Value *RHS = Cmp->getOperand(1);
// If the phi isn't in the current block, an incoming edge to this block
// doesn't control the destination.
@@ -784,18 +808,17 @@
// We can do this simplification if any comparisons fold to true or false.
// See if any do.
- Constant *PredCst = 0;
+ Value *PredVal = 0;
bool TrueDirection = false;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- PredCst = dyn_cast<Constant>(PN->getIncomingValue(i));
- if (PredCst == 0) continue;
+ PredVal = PN->getIncomingValue(i);
+
+ Constant *Res = GetResultOfComparison(Cmp->getPredicate(), PredVal, RHS);
+ if (!Res) {
+ PredVal = 0;
+ continue;
+ }
- Constant *Res;
- if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cmp))
- Res = ConstantExpr::getICmp(ICI->getPredicate(), PredCst, RHS);
- else
- Res = ConstantExpr::getFCmp(cast<FCmpInst>(Cmp)->getPredicate(),
- PredCst, RHS);
// If this folded to a constant expr, we can't do anything.
if (ConstantInt *ResC = dyn_cast<ConstantInt>(Res)) {
TrueDirection = ResC->getZExtValue();
@@ -808,11 +831,11 @@
}
// Otherwise, we can't fold this input.
- PredCst = 0;
+ PredVal = 0;
}
// If no match, bail out.
- if (PredCst == 0)
+ if (PredVal == 0)
return false;
// See if the cost of duplicating this block is low enough.
@@ -825,7 +848,7 @@
// If so, we can actually do this threading. Merge any common predecessors
// that will act the same.
- BasicBlock *PredBB = FactorCommonPHIPreds(PN, PredCst);
+ BasicBlock *PredBB = FactorCommonPHIPreds(PN, PredVal);
// Next, get our successor.
BasicBlock *SuccBB = BB->getTerminator()->getSuccessor(!TrueDirection);
Added: llvm/trunk/test/Transforms/JumpThreading/branch-no-const.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/JumpThreading/branch-no-const.ll?rev=73755&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/JumpThreading/branch-no-const.ll (added)
+++ llvm/trunk/test/Transforms/JumpThreading/branch-no-const.ll Thu Jun 18 23:56:29 2009
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | opt -jump-threading | llvm-dis | not grep phi
+
+declare i8 @mcguffin()
+
+define i32 @test(i1 %foo, i8 %b) {
+entry:
+ %a = call i8 @mcguffin()
+ br i1 %foo, label %bb1, label %bb2
+bb1:
+ br label %jt
+bb2:
+ br label %jt
+jt:
+ %x = phi i8 [%a, %bb1], [%b, %bb2]
+ %A = icmp eq i8 %x, %a
+ br i1 %A, label %rt, label %rf
+rt:
+ ret i32 7
+rf:
+ ret i32 8
+}
More information about the llvm-commits
mailing list