diff mbox

Find auto-increment use both before and after candidate's increment in IVOPT

Message ID 004301cea7aa$949ae0a0$bdd0a1e0$@arm.com
State New
Headers show

Commit Message

Bin Cheng Sept. 2, 2013, 7:03 a.m. UTC
Hi,
For now set_autoinc_for_original_candidates only searches auto-inc uses
before candidate's increment, causing pre-increment opportunities missed for
original candidates.  This is a straightforward fix by searching after
candidate's increment too.

The patch also includes a test case to illustrate the problem.  Without the
patch, assembly of the test is:
foo:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	movw	r3, #:lower16:__ctype_ptr__
	ldrb	r2, [r0]	@ zero_extendqisi2
	movt	r3, #:upper16:__ctype_ptr__
	ldr	r1, [r3]
	adds	r3, r1, r2
	ldrb	r3, [r3, #1]	@ zero_extendqisi2
	lsls	r3, r3, #29
	bmi	.L2
	adds	r3, r0, #1
.L3:
	mov	r0, r3
	adds	r3, r3, #1
	ldrb	r2, [r0]	@ zero_extendqisi2
	add	r2, r2, r1
	ldrb	r2, [r2, #1]	@ zero_extendqisi2
	lsls	r2, r2, #29
	bpl	.L3
.L2:
	bx	lr
	.size	foo, .-foo

Which can be optimized into below:
foo:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	movw	r3, #:lower16:__ctype_ptr__
	ldrb	r1, [r0]	@ zero_extendqisi2
	movt	r3, #:upper16:__ctype_ptr__
	ldr	r2, [r3]
	adds	r3, r2, r1
	ldrb	r3, [r3, #1]	@ zero_extendqisi2
	lsls	r1, r3, #29
	bmi	.L2
.L3:
	ldrb	r3, [r0, #1]!	@ zero_extendqisi2
	add	r3, r3, r2
	ldrb	r3, [r3, #1]	@ zero_extendqisi2
	lsls	r3, r3, #29
	bpl	.L3
.L2:
	bx	lr
	.size	foo, .-foo

Bootstrapped and tested on arm a15, is it OK?

Thanks.
bin

2013-09-02  Bin Cheng  <bin.cheng@arm.com>

	* tree-ssa-loop-ivopts.c (set_autoinc_for_original_candidates):
	Find auto-increment use both before and after candidate.

gcc/testsuite/ChangeLog
2013-09-02  Bin Cheng  <bin.cheng@arm.com>

	* gcc.target/arm/ivopts-orig_biv-inc.c: New test.

Comments

Richard Biener Sept. 2, 2013, 9:17 a.m. UTC | #1
On Mon, Sep 2, 2013 at 9:03 AM, bin.cheng <bin.cheng@arm.com> wrote:
> Hi,
> For now set_autoinc_for_original_candidates only searches auto-inc uses
> before candidate's increment, causing pre-increment opportunities missed for
> original candidates.  This is a straightforward fix by searching after
> candidate's increment too.
>
> The patch also includes a test case to illustrate the problem.  Without the
> patch, assembly of the test is:
> foo:
>         @ args = 0, pretend = 0, frame = 0
>         @ frame_needed = 0, uses_anonymous_args = 0
>         @ link register save eliminated.
>         movw    r3, #:lower16:__ctype_ptr__
>         ldrb    r2, [r0]        @ zero_extendqisi2
>         movt    r3, #:upper16:__ctype_ptr__
>         ldr     r1, [r3]
>         adds    r3, r1, r2
>         ldrb    r3, [r3, #1]    @ zero_extendqisi2
>         lsls    r3, r3, #29
>         bmi     .L2
>         adds    r3, r0, #1
> .L3:
>         mov     r0, r3
>         adds    r3, r3, #1
>         ldrb    r2, [r0]        @ zero_extendqisi2
>         add     r2, r2, r1
>         ldrb    r2, [r2, #1]    @ zero_extendqisi2
>         lsls    r2, r2, #29
>         bpl     .L3
> .L2:
>         bx      lr
>         .size   foo, .-foo
>
> Which can be optimized into below:
> foo:
>         @ args = 0, pretend = 0, frame = 0
>         @ frame_needed = 0, uses_anonymous_args = 0
>         @ link register save eliminated.
>         movw    r3, #:lower16:__ctype_ptr__
>         ldrb    r1, [r0]        @ zero_extendqisi2
>         movt    r3, #:upper16:__ctype_ptr__
>         ldr     r2, [r3]
>         adds    r3, r2, r1
>         ldrb    r3, [r3, #1]    @ zero_extendqisi2
>         lsls    r1, r3, #29
>         bmi     .L2
> .L3:
>         ldrb    r3, [r0, #1]!   @ zero_extendqisi2
>         add     r3, r3, r2
>         ldrb    r3, [r3, #1]    @ zero_extendqisi2
>         lsls    r3, r3, #29
>         bpl     .L3
> .L2:
>         bx      lr
>         .size   foo, .-foo
>
> Bootstrapped and tested on arm a15, is it OK?

Ok.

Thanks,
Richard.

> Thanks.
> bin
>
> 2013-09-02  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-ssa-loop-ivopts.c (set_autoinc_for_original_candidates):
>         Find auto-increment use both before and after candidate.
>
> gcc/testsuite/ChangeLog
> 2013-09-02  Bin Cheng  <bin.cheng@arm.com>
>
>         * gcc.target/arm/ivopts-orig_biv-inc.c: New test.
diff mbox

Patch

Index: gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c
===================================================================
--- gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c	(revision 0)
@@ -0,0 +1,19 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+/* { dg-skip-if "" { arm_thumb1 } } */
+
+extern char *__ctype_ptr__;
+
+unsigned char * foo(unsigned char *ReadPtr)
+{
+
+ unsigned char c;
+
+ while (!(((__ctype_ptr__+sizeof(""[*ReadPtr]))[(int)(*ReadPtr)])&04) == (!(0)))
+  ReadPtr++;
+
+ return ReadPtr;
+}
+
+/* { dg-final { scan-tree-dump-times "original biv" 2 "ivopts"} } */
+/* { dg-final { cleanup-tree-dump "ivopts" } } */
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c	(revision 200774)
+++ gcc/tree-ssa-loop-ivopts.c	(working copy)
@@ -4876,22 +4876,36 @@  set_autoinc_for_original_candidates (struct ivopts
   for (i = 0; i < n_iv_cands (data); i++)
     {
       struct iv_cand *cand = iv_cand (data, i);
-      struct iv_use *closest = NULL;
+      struct iv_use *closest_before = NULL;
+      struct iv_use *closest_after = NULL;
       if (cand->pos != IP_ORIGINAL)
 	continue;
+
       for (j = 0; j < n_iv_uses (data); j++)
 	{
 	  struct iv_use *use = iv_use (data, j);
 	  unsigned uid = gimple_uid (use->stmt);
-	  if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at)
-	      || uid > gimple_uid (cand->incremented_at))
+
+	  if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at))
 	    continue;
-	  if (closest == NULL || uid > gimple_uid (closest->stmt))
-	    closest = use;
+
+	  if (uid < gimple_uid (cand->incremented_at)
+	      && (closest_before == NULL
+		  || uid > gimple_uid (closest_before->stmt)))
+	    closest_before = use;
+
+	  if (uid > gimple_uid (cand->incremented_at)
+	      && (closest_after == NULL
+		  || uid < gimple_uid (closest_after->stmt)))
+	    closest_after = use;
 	}
-      if (closest == NULL || !autoinc_possible_for_pair (data, closest, cand))
-	continue;
-      cand->ainc_use = closest;
+
+      if (closest_before != NULL
+	  && autoinc_possible_for_pair (data, closest_before, cand))
+	cand->ainc_use = closest_before;
+      else if (closest_after != NULL
+	       && autoinc_possible_for_pair (data, closest_after, cand))
+	cand->ainc_use = closest_after;
     }
 }