summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-04-23 20:31:35 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-04-23 20:31:35 +0000
commit391b2c39f7d738a9bf49fe404cdbf0fa0825e1a5 (patch)
tree89009de21d22a202261d73af2e6fb687e10f48e2
parent1ad0f741557afc28b626cb6fde8113e8aa997332 (diff)
Thumb2: When applying branch optimizations, visit branches in reverse order.
The order in which branches appear in ImmBranches is approximately their order within the function body. By visiting later branches first, we reduce the distance between earlier forward branches and their targets, making it more likely that the cbn?z optimization, which can only apply to forward branches, will succeed for those earlier branches. Differential Revision: http://reviews.llvm.org/D9185 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235640 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp9
-rw-r--r--test/CodeGen/Thumb2/cbnz.ll54
2 files changed, 61 insertions, 2 deletions
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index 00c92fcddd..e6d4b14a26 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -1745,8 +1745,13 @@ bool ARMConstantIslands::optimizeThumb2Instructions() {
bool ARMConstantIslands::optimizeThumb2Branches() {
bool MadeChange = false;
- for (unsigned i = 0, e = ImmBranches.size(); i != e; ++i) {
- ImmBranch &Br = ImmBranches[i];
+ // The order in which branches appear in ImmBranches is approximately their
+ // order within the function body. By visiting later branches first, we reduce
+ // the distance between earlier forward branches and their targets, making it
+ // more likely that the cbn?z optimization, which can only apply to forward
+ // branches, will succeed.
+ for (unsigned i = ImmBranches.size(); i != 0; --i) {
+ ImmBranch &Br = ImmBranches[i-1];
unsigned Opcode = Br.MI->getOpcode();
unsigned NewOpc = 0;
unsigned Scale = 1;
diff --git a/test/CodeGen/Thumb2/cbnz.ll b/test/CodeGen/Thumb2/cbnz.ll
new file mode 100644
index 0000000000..5c0bb5bfe1
--- /dev/null
+++ b/test/CodeGen/Thumb2/cbnz.ll
@@ -0,0 +1,54 @@
+; RUN: llc -mtriple thumbv7-unknown-linux -o - %s | FileCheck %s
+
+declare void @x()
+declare void @y()
+
+define void @f(i32 %x, i32 %y) {
+ ; CHECK-LABEL: f:
+ ; CHECK: cbnz
+ %p = icmp eq i32 %x, 0
+ br i1 %p, label %t, label %f
+
+t:
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ ; CHECK: cbnz
+ %q = icmp eq i32 %y, 0
+ br i1 %q, label %t2, label %f
+
+t2:
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ call void @x()
+ br label %f
+
+f:
+ call void @y()
+ ret void
+}