[llvm-commits] [llvm] r86909 - in /llvm/trunk: lib/CodeGen/BranchFolding.cpp test/CodeGen/X86/tail-opts.ll

Dan Gohman gohman at apple.com
Wed Nov 11 16:39:10 PST 2009


Author: djg
Date: Wed Nov 11 18:39:10 2009
New Revision: 86909

URL: http://llvm.org/viewvc/llvm-project?rev=86909&view=rev
Log:
Tail merge at any size when there are two potentials blocks and one
can be made to fall through into the other.

Modified:
    llvm/trunk/lib/CodeGen/BranchFolding.cpp
    llvm/trunk/test/CodeGen/X86/tail-opts.ll

Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=86909&r1=86908&r2=86909&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original)
+++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Nov 11 18:39:10 2009
@@ -495,6 +495,15 @@
       return true;
   }
 
+  // If one of the blocks can be completely merged and happens to be in
+  // a position where the other could fall through into it, merge any number
+  // of instructions, because it can be done without a branch.
+  // TODO: If the blocks are not adjacent, move one of them so that they are?
+  if (MBB1->isLayoutSuccessor(MBB2) && I2 == MBB2->begin())
+    return true;
+  if (MBB2->isLayoutSuccessor(MBB1) && I1 == MBB1->begin())
+    return true;
+
   // If both blocks have an unconditional branch temporarily stripped out,
   // treat that as an additional common instruction.
   if (MBB1 != PredBB && MBB2 != PredBB && 
@@ -716,16 +725,31 @@
     MachineBasicBlock *EntryBB = MergePotentials.begin()->getBlock()->
                                  getParent()->begin();
     unsigned commonTailIndex = SameTails.size();
-    for (unsigned i=0; i<SameTails.size(); i++) {
-      MachineBasicBlock *MBB = SameTails[i].getBlock();
-      if (MBB == EntryBB)
-        continue;
-      if (MBB == PredBB) {
-        commonTailIndex = i;
-        break;
+    // If there are two blocks, check to see if one can be made to fall through
+    // into the other.
+    if (SameTails.size() == 2 &&
+        SameTails[0].getBlock()->isLayoutSuccessor(SameTails[1].getBlock()) &&
+        SameTails[1].tailIsWholeBlock())
+      commonTailIndex = 1;
+    else if (SameTails.size() == 2 &&
+             SameTails[1].getBlock()->isLayoutSuccessor(
+                                                     SameTails[0].getBlock()) &&
+             SameTails[0].tailIsWholeBlock())
+      commonTailIndex = 0;
+    else {
+      // Otherwise just pick one, favoring the fall-through predecessor if
+      // there is one.
+      for (unsigned i = 0, e = SameTails.size(); i != e; ++i) {
+        MachineBasicBlock *MBB = SameTails[i].getBlock();
+        if (MBB == EntryBB && SameTails[i].tailIsWholeBlock())
+          continue;
+        if (MBB == PredBB) {
+          commonTailIndex = i;
+          break;
+        }
+        if (SameTails[i].tailIsWholeBlock())
+          commonTailIndex = i;
       }
-      if (MBB->begin() == SameTails[i].getTailStartPos())
-        commonTailIndex = i;
     }
 
     if (commonTailIndex == SameTails.size() ||
@@ -1049,7 +1073,7 @@
       continue;
     // Don't duplicate into a fall-through predecessor unless its the
     // only predecessor.
-    if (&*next(MachineFunction::iterator(PredBB)) == TailBB &&
+    if (PredBB->isLayoutSuccessor(TailBB) &&
         PrevFallsThrough &&
         TailBB->pred_size() != 1)
       continue;

Modified: llvm/trunk/test/CodeGen/X86/tail-opts.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tail-opts.ll?rev=86909&r1=86908&r2=86909&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/X86/tail-opts.ll (original)
+++ llvm/trunk/test/CodeGen/X86/tail-opts.ll Wed Nov 11 18:39:10 2009
@@ -266,3 +266,30 @@
 declare fastcc i32 @lvalue_p(%union.tree_node* nocapture) nounwind readonly
 
 declare fastcc %union.tree_node* @default_conversion(%union.tree_node*) nounwind
+
+
+; If one tail merging candidate falls through into the other,
+; tail merging is likely profitable regardless of how few
+; instructions are involved. This function should have only
+; one ret instruction.
+
+; CHECK: foo:
+; CHECK:        call func
+; CHECK-NEXT: .LBB5_2:
+; CHECK-NEXT:   addq $8, %rsp
+; CHECK-NEXT:   ret
+
+define void @foo(i1* %V) nounwind {
+entry:
+  %t0 = icmp eq i1* %V, null
+  br i1 %t0, label %return, label %bb
+
+bb:
+  call void @func()
+  ret void
+
+return:
+  ret void
+}
+
+declare void @func()





More information about the llvm-commits mailing list