diff mbox

RFR: Minor optimisation for divide by 2

Message ID 1398763004.20174.7.camel@localhost.localdomain
State New
Headers show

Commit Message

Edward Nevill April 29, 2014, 9:16 a.m. UTC
Hi,

C2 currently generates

mov rdst, rsrc, asr #31
mov rdst, rdst, lsr #31
add rdst, rsrc, rdst
mov rdst, rdst, asr #1

for divide by 2. The following patch reduces this to

add rdst, rsrc, rsrc, lsr #31
mov rdst, rdst, asr #1

I know this is very minor, but it offends me:-)

OK?
Ed.

--- CUT HERE ---
# HG changeset patch
# User Edward Nevill edward.nevill@linaro.org
# Date 1398762402 -3600
#      Tue Apr 29 10:06:42 2014 +0100
# Node ID 7f9ab7b86d7a690e04ffc6331c2b9519aae2a565
# Parent  d9468835bc5160b7fac6709b0afbc751b2159fbb
Minor optimisation for divide by 2

Comments

Andrew Haley April 29, 2014, 9:37 a.m. UTC | #1
On 04/29/2014 10:16 AM, Edward Nevill wrote:

> C2 currently generates
> 
> mov rdst, rsrc, asr #31
> mov rdst, rdst, lsr #31
> add rdst, rsrc, rdst
> mov rdst, rdst, asr #1
> 
> for divide by 2. The following patch reduces this to
> 
> add rdst, rsrc, rsrc, lsr #31
> mov rdst, rdst, asr #1
> 
> I know this is very minor, but it offends me:-)
> 
> OK?

How strange.  That must be a generic C2 bug, but OK.

I'm a bit mystified why the add and shift operation isn't being
combined.  It should match AddI_reg_URShift_reg.

Andrew.
Andrew Haley May 12, 2014, 12:10 p.m. UTC | #2
Hi,

On 04/29/2014 10:16 AM, Edward Nevill wrote:

> C2 currently generates
> 
> mov rdst, rsrc, asr #31
> mov rdst, rdst, lsr #31
> add rdst, rsrc, rdst
> mov rdst, rdst, asr #1
> 
> for divide by 2.

I get

 asr	rdst, rsrc, #31
 add	rtmp, rsrc, rdst, lsr #31
 asr	rdst, rtmp, #1

from C2.  Which is not as nice as yours, but less worrying.

> The following patch reduces this to
> 
> add rdst, rsrc, rsrc, lsr #31
> mov rdst, rdst, asr #1
> 
> I know this is very minor, but it offends me:-)
> 
> OK?

Why is there no long version of this?

Andrew.
diff mbox

Patch

diff -r d9468835bc51 -r 7f9ab7b86d7a src/cpu/aarch64/vm/aarch64.ad
--- a/src/cpu/aarch64/vm/aarch64.ad	Thu Apr 10 06:50:43 2014 -0400
+++ b/src/cpu/aarch64/vm/aarch64.ad	Tue Apr 29 10:06:42 2014 +0100
@@ -3356,6 +3356,16 @@ 
   interface(CONST_INTER);
 %}
 
+operand immI_31()
+%{
+  predicate(n->get_int() == 31);
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 operand immI_8()
 %{
   predicate(n->get_int() == 8);
@@ -7274,6 +7284,30 @@ 
   ins_pipe(pipe_class_default);
 %}
 
+instruct signExtract(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{
+  match(Set dst (URShiftI (RShiftI src div1) div2));
+  ins_cost(INSN_COST);
+  format %{ "lsrw $dst, $src, $div1" %}
+  ins_encode %{
+    __ lsrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct div2Round(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{
+  match(Set dst (AddI src (URShiftI (RShiftI src div1) div2)));
+  ins_cost(INSN_COST);
+  format %{ "addw $dst, $src, $div1" %}
+
+  ins_encode %{
+    __ addw(as_Register($dst$$reg),
+	      as_Register($src$$reg),
+	      as_Register($src$$reg),
+	      Assembler::LSR, 31);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
 // Long Divide
 
 instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
--- CUT HERE ---