Make jump threading eliminate blocks that just contain phi nodes,
authorChris Lattner <sabre@nondot.org>
Tue, 10 Nov 2009 21:40:01 +0000 (21:40 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 10 Nov 2009 21:40:01 +0000 (21:40 +0000)
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

lib/Transforms/Scalar/JumpThreading.cpp
test/Transforms/JumpThreading/basic.ll

index 9c9461fa382ca028e85bca2ae16f001390a427c9..1d89399e7411b9d74f9d26e735ac64039feb7107 100644 (file)
@@ -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;
index 1be086b645d33d8d6e84974f37c993b9873e50ed..ccb2a3f833010da35f91e91e5e8ac2f81ee8998c 100644 (file)
@@ -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