[llvm-commits] [PATCH] Use predicates more often when optimizing for size

Sean Bartell wingedtachikoma at gmail.com
Sat Apr 2 21:56:26 PDT 2011


When optimizing for size, we want to use predicates instead of branches
to save a few instructions. Predicates are used when the resulting code
is at least 1/2 as fast as with branching; this includes almost all
cases where predicates can be used. There are, of course, other
heuristics--I think GCC just uses a limit of 8 instructions.

Tested with make check in LLVM. I'd appreciate any feedback, since if
I'm accepted into GSoC I'll be doing this much more often :).

Thanks,
Sean Bartell
-------------- next part --------------
>From 58b8afd57058f6acc2662a879290a56351bd19d2 Mon Sep 17 00:00:00 2001
From: Sean Bartell <wingedtachikoma at gmail.com>
Date: Sat, 2 Apr 2011 23:32:56 -0400
Subject: [PATCH] Use predicates more often when optimizing for size.

When optimizing for size, we want to use predicates instead of branches
to save a few instructions. Predicates are used when the resulting code
is at least 1/2 as fast as with branching; this includes almost all
cases where predicates can be used.
---
 lib/Target/ARM/ARMBaseInstrInfo.cpp |    8 +++++
 test/CodeGen/ARM/ifcvt12.ll         |   49 +++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 test/CodeGen/ARM/ifcvt12.ll

diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 1acad9d..95a3067 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1282,6 +1282,10 @@ bool ARMBaseInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
   UnpredCost += 1.0; // The branch itself
   UnpredCost += (1.0 - Confidence) * Subtarget.getMispredictionPenalty();
 
+  // If optimizing for size, use predication if it's up to twice as slow.
+  if (MBB.getParent()->getFunction()->hasFnAttr(Attribute::OptimizeForSize))
+    UnpredCost *= 2;
+
   return (float)(NumCyles + ExtraPredCycles) < UnpredCost;
 }
 
@@ -1299,6 +1303,10 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB,
   UnpredCost += 1.0; // The branch itself
   UnpredCost += (1.0 - Confidence) * Subtarget.getMispredictionPenalty();
 
+  // If optimizing for size, use predication if it's up to twice as slow.
+  if (TMBB.getParent()->getFunction()->hasFnAttr(Attribute::OptimizeForSize))
+    UnpredCost *= 2;
+
   return (float)(TCycles + FCycles + TExtra + FExtra) < UnpredCost;
 }
 
diff --git a/test/CodeGen/ARM/ifcvt12.ll b/test/CodeGen/ARM/ifcvt12.ll
new file mode 100644
index 0000000..83b52a1
--- /dev/null
+++ b/test/CodeGen/ARM/ifcvt12.ll
@@ -0,0 +1,49 @@
+; RUN: llc < %s -march=arm | FileCheck %s
+; Use predicates more often when optimizing for size.
+
+define i32 @t1(i32 %x) nounwind optsize {
+; CHECK: t1:
+; CHECK-NOT: blt
+; CHECK-NOT: bge
+entry:
+  %0 = icmp sgt i32 %x, 17
+  br i1 %0, label %bb1, label %bb2
+
+; CHECK: subge
+bb1:
+  %1 = sub i32 %x, 61
+  %2 = mul i32 %1, 3
+  br label %end
+
+bb2:
+  %3 = mul i32 %x, 5
+  %4 = add i32 %3, 25
+  br label %end
+
+end:
+  %5 = phi i32 [ %2, %bb1 ], [ %4, %bb2]
+  ret i32 %5
+}
+
+define i32 @t2(i32 %x) nounwind optsize {
+; CHECK: t2:
+; CHECK-NOT: bxlt
+; CHECK-NOT: blt
+entry:
+  %0 = icmp sgt i32 %x, 17
+  br i1 %0, label %bb1, label %end
+
+; CHECK: subge
+; CHECK: andge
+bb1:
+  %1 = sub i32 %x, 61
+  %2 = mul i32 %1, 3
+  %3 = and i32 %2, 25
+  %4 = mul i32 %3, 5
+  br label %end
+
+end:
+  %5 = phi i32 [ %4, %bb1 ], [ %x, %entry ]
+  %6 = xor i32 %5, 17
+  ret i32 %6
+}
-- 
1.7.4.2



More information about the llvm-commits mailing list