Tail duplication still needs to iterate. Duplicating new instructions onto
authorBob Wilson <bob.wilson@apple.com>
Wed, 18 Nov 2009 22:52:37 +0000 (22:52 +0000)
committerBob Wilson <bob.wilson@apple.com>
Wed, 18 Nov 2009 22:52:37 +0000 (22:52 +0000)
the tail of a block may make that block a new candidate for duplication.

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

lib/CodeGen/BranchFolding.cpp
test/CodeGen/ARM/tail-opts.ll [new file with mode: 0644]

index af5fbd1202a726ae86967d6fa36c12fdd655da27..871d6dc5765538bf3026fd6b4356639a730d472d 100644 (file)
@@ -197,7 +197,6 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
     MadeChange |= OptimizeImpDefsBlock(MBB);
   }
 
-
   bool MadeChangeThisIteration = true;
   while (MadeChangeThisIteration) {
     MadeChangeThisIteration = false;
@@ -206,10 +205,15 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
     MadeChange |= MadeChangeThisIteration;
   }
 
-  // Do tail duplication once after tail merging is done.  Otherwise it is
+  // Do tail duplication after tail merging is done.  Otherwise it is
   // tough to avoid situations where tail duplication and tail merging undo
   // each other's transformations ad infinitum.
-  MadeChange |= TailDuplicateBlocks(MF);
+  MadeChangeThisIteration = true;
+  while (MadeChangeThisIteration) {
+    MadeChangeThisIteration = false;
+    MadeChangeThisIteration |= TailDuplicateBlocks(MF);
+    MadeChange |= MadeChangeThisIteration;
+  }
 
   // See if any jump tables have become mergable or dead as the code generator
   // did its thing.
diff --git a/test/CodeGen/ARM/tail-opts.ll b/test/CodeGen/ARM/tail-opts.ll
new file mode 100644 (file)
index 0000000..c0651ba
--- /dev/null
@@ -0,0 +1,64 @@
+; RUN: llc < %s -march=arm -mcpu=cortex-a8 -asm-verbose=false | FileCheck %s
+
+declare void @bar(i32)
+declare void @car(i32)
+declare void @dar(i32)
+declare void @ear(i32)
+declare void @far(i32)
+declare i1 @qux()
+
+@GHJK = global i32 0
+
+declare i8* @choose(i8*, i8*);
+
+; BranchFolding should tail-duplicate the indirect jump to avoid
+; redundant branching.
+
+; CHECK: tail_duplicate_me:
+; CHECK:      qux
+; CHECK:      qux
+; CHECK:      ldr r{{.}}, LCPI
+; CHECK:      str r
+; CHECK-NEXT: bx r
+; CHECK:      ldr r{{.}}, LCPI
+; CHECK:      str r
+; CHECK-NEXT: bx r
+; CHECK:      ldr r{{.}}, LCPI
+; CHECK:      str r
+; CHECK-NEXT: bx r
+
+define void @tail_duplicate_me() nounwind {
+entry:
+  %a = call i1 @qux()
+  %c = call i8* @choose(i8* blockaddress(@tail_duplicate_me, %return),
+                        i8* blockaddress(@tail_duplicate_me, %altret))
+  br i1 %a, label %A, label %next
+next:
+  %b = call i1 @qux()
+  br i1 %b, label %B, label %C
+
+A:
+  call void @bar(i32 0)
+  store i32 0, i32* @GHJK
+  br label %M
+
+B:
+  call void @car(i32 1)
+  store i32 0, i32* @GHJK
+  br label %M
+
+C:
+  call void @dar(i32 2)
+  store i32 0, i32* @GHJK
+  br label %M
+
+M:
+  indirectbr i8* %c, [label %return, label %altret]
+
+return:
+  call void @ear(i32 1000)
+  ret void
+altret:
+  call void @far(i32 1001)
+  ret void
+}