diff options
author | Chris Lattner <sabre@nondot.org> | 2009-11-10 21:40:01 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-11-10 21:40:01 +0000 |
commit | 80e7e5a4297edceecb53514ad3fc766a3ed5ff8b (patch) | |
tree | 26e0fd329d8a9b6ce4b2ce34c67528e4e839d355 | |
parent | 4a720a363c829c7152a4cc15c3134bffaf03abeb (diff) | |
download | bcm5719-llvm-80e7e5a4297edceecb53514ad3fc766a3ed5ff8b.tar.gz bcm5719-llvm-80e7e5a4297edceecb53514ad3fc766a3ed5ff8b.zip |
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.
llvm-svn: 86722
-rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 21 | ||||
-rw-r--r-- | llvm/test/Transforms/JumpThreading/basic.ll | 16 |
2 files changed, 34 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 9c9461fa382..1d89399e741 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/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/llvm/test/Transforms/JumpThreading/basic.ll b/llvm/test/Transforms/JumpThreading/basic.ll index 1be086b645d..ccb2a3f8330 100644 --- a/llvm/test/Transforms/JumpThreading/basic.ll +++ b/llvm/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 |