From 60f34b9fb0323688e93cf347d63b56327d6250f8 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Wed, 18 Nov 2009 22:52:37 +0000 Subject: [PATCH] Tail duplication still needs to iterate. Duplicating new instructions onto 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 | 10 ++++-- test/CodeGen/ARM/tail-opts.ll | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/ARM/tail-opts.ll diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index af5fbd1202a..871d6dc5765 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -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 index 00000000000..c0651ba6a82 --- /dev/null +++ b/test/CodeGen/ARM/tail-opts.ll @@ -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 +} -- 2.34.1