diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c | 19 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 30 |
4 files changed, 50 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f24b24a..5b31266 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +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. + 2013-09-02 Marek Polacek <polacek@redhat.com> * Makefile.in (ubsan.o): Add $(TM_P_H) dependency. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c87b30a..b74effc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-09-02 Bin Cheng <bin.cheng@arm.com> + + * gcc.target/arm/ivopts-orig_biv-inc.c: New testcase. + 2013-09-02 Paolo Carlini <paolo.carlini@oracle.com> PR c++/21682, implement DR 565 diff --git a/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c b/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c new file mode 100644 index 0000000..f466ff3 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c @@ -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" } } */ diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 7cfe80d..c45f316 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -4876,22 +4876,36 @@ set_autoinc_for_original_candidates (struct ivopts_data *data) 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; } } |