Message ID | 004301cea7aa$949ae0a0$bdd0a1e0$@arm.com |
---|---|
State | New |
Headers | show |
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.
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; } }