Transform code like:
authorChris Lattner <sabre@nondot.org>
Sat, 21 Oct 2006 05:43:30 +0000 (05:43 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 21 Oct 2006 05:43:30 +0000 (05:43 +0000)
  jle FOO
  jmp BAR
BAR:

into:

  jle FOO
BAR:

... whoa!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31098 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/BranchFolding.cpp

index bcf0a846bfdf69d6e4c820f67e7fa69179b389aa..5be6baf64c209a3b7c9903c2bd20008b6f3e77a5 100644 (file)
@@ -30,7 +30,7 @@ using namespace llvm;
 static Statistic<> NumDeadBlocks("branchfold", "Number of dead blocks removed");
 static Statistic<> NumBranchOpts("branchfold", "Number of branches optimized");
 static Statistic<> NumTailMerge ("branchfold", "Number of block tails merged");
-static cl::opt<bool> EnableTailMerge("enable-tail-merge");
+static cl::opt<bool> EnableTailMerge("enable-tail-merge", cl::init(false));
 
 namespace {
   struct BranchFolder : public MachineFunctionPass {
@@ -442,7 +442,8 @@ void BranchFolder::OptimizeBlock(MachineFunction::iterator MBB) {
                                        !PriorCond.empty(), MBB);
     
     // If the previous branch is conditional and both conditions go to the same
-    // destination, remove the branch, replacing it with an unconditional one.
+    // destination, remove the branch, replacing it with an unconditional one or
+    // a fall-through.
     if (PriorTBB && PriorTBB == PriorFBB) {
       TII->RemoveBranch(PrevBB);
       PriorCond.clear(); 
@@ -461,6 +462,16 @@ void BranchFolder::OptimizeBlock(MachineFunction::iterator MBB) {
       ++NumBranchOpts;
       return OptimizeBlock(MBB);
     }
+    
+    // If the prior block branches somewhere else on the condition and here if
+    // the condition is false, remove the uncond second branch.
+    if (PriorFBB == &*MBB) {
+      TII->RemoveBranch(PrevBB);
+      TII->InsertBranch(PrevBB, PriorTBB, 0, PriorCond);
+      MadeChange = true;
+      ++NumBranchOpts;
+      return OptimizeBlock(MBB);
+    }
   }
   
   // Analyze the branch in the current block.