aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-11-10 21:40:01 +0000
committerChris Lattner <sabre@nondot.org>2009-11-10 21:40:01 +0000
commitf3183f6da6321c6496daa107ea5d6d48b99d9330 (patch)
treefa8b2d2016d562a065dc58d23248747a7829c7e1
parent81ebdcf7dd3c182f5fca352b59b336f79d5da23e (diff)
Make jump threading eliminate blocks that just contain phi nodes,
debug intrinsics, and an unconditional branch when possible. This reuses the TryToSimplifyUncondBranchFromEmptyBlock function split out of simplifycfg. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86722 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp21
-rw-r--r--test/Transforms/JumpThreading/basic.ll16
2 files changed, 34 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp
index 9c9461fa38..1d89399e74 100644
--- a/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/lib/Transforms/Scalar/JumpThreading.cpp
@@ -115,6 +115,7 @@ bool JumpThreading::runOnFunction(Function &F) {
bool Changed = false;
for (Function::iterator I = F.begin(), E = F.end(); I != E;) {
BasicBlock *BB = I;
+ // Thread all of the branches we can over this block.
while (ProcessBlock(BB))
Changed = true;
@@ -129,6 +130,26 @@ bool JumpThreading::runOnFunction(Function &F) {
LoopHeaders.erase(BB);
DeleteDeadBlock(BB);
Changed = true;
+ } else if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator())) {
+ // Can't thread an unconditional jump, but if the block is "almost
+ // empty", we can replace uses of it with uses of the successor and make
+ // this dead.
+ if (BI->isUnconditional() &&
+ BB != &BB->getParent()->getEntryBlock()) {
+ BasicBlock::iterator BBI = BB->getFirstNonPHI();
+ // Ignore dbg intrinsics.
+ while (isa<DbgInfoIntrinsic>(BBI))
+ ++BBI;
+ // If the terminator is the only non-phi instruction, try to nuke it.
+ if (BBI->isTerminator()) {
+ bool Erased = LoopHeaders.erase(BB);
+
+ if (TryToSimplifyUncondBranchFromEmptyBlock(BB))
+ Changed = true;
+ else if (Erased)
+ LoopHeaders.insert(BB);
+ }
+ }
}
}
AnotherIteration = Changed;
diff --git a/test/Transforms/JumpThreading/basic.ll b/test/Transforms/JumpThreading/basic.ll
index 1be086b645..ccb2a3f833 100644
--- a/test/Transforms/JumpThreading/basic.ll
+++ b/test/Transforms/JumpThreading/basic.ll
@@ -211,19 +211,29 @@ define i32 @test8b(i1 %cond, i1 %cond2) {
T0:
%A = call i1 @test8a()
br i1 %A, label %T1, label %F1
+
+; CHECK: T0:
+; CHECK-NEXT: call
+; CHECK-NEXT: br i1 %A, label %T1, label %Y
+
T1:
%B = call i1 @test8a()
br i1 %B, label %T2, label %F1
+
+; CHECK: T1:
+; CHECK-NEXT: call
+; CHECK-NEXT: br i1 %B, label %T2, label %Y
T2:
%C = call i1 @test8a()
br i1 %cond, label %T3, label %F1
+
+; CHECK: T2:
+; CHECK-NEXT: call
+; CHECK-NEXT: br i1 %cond, label %T3, label %Y
T3:
ret i32 0
F1:
-; TODO: F1 uncond branch block should be removed, T2 should jump directly to Y.
-; CHECK: F1:
-; CHECK-NEXT br label %Y
%D = phi i32 [0, %T0], [0, %T1], [1, %T2]
%E = icmp eq i32 %D, 1
%F = and i1 %E, %cond