diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-ssa-strength-reduction.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c | 17 |
4 files changed, 54 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 990c895..c585787 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-02 Eric Botcazou <ebotcazou@adacore.com> + + * gimple-ssa-strength-reduction.c (valid_mem_ref_cand_p): New function. + (replace_ref): Do not replace a chain of only two candidates which are + valid memory references. + 2019-09-02 Martin Liska <mliska@suse.cz> * tree-switch-conversion.c (jump_table_cluster::find_jump_tables): diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index d343da0..de7f360 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -1999,6 +1999,23 @@ replace_ref (tree *expr, slsr_cand_t c) update_stmt (c->cand_stmt); } +/* Return true if CAND_REF candidate C is a valid memory reference. */ + +static bool +valid_mem_ref_cand_p (slsr_cand_t c) +{ + if (TREE_CODE (TREE_OPERAND (c->stride, 1)) != INTEGER_CST) + return false; + + struct mem_address addr + = { NULL_TREE, c->base_expr, TREE_OPERAND (c->stride, 0), + TREE_OPERAND (c->stride, 1), wide_int_to_tree (sizetype, c->index) }; + + return + valid_mem_ref_p (TYPE_MODE (c->cand_type), TYPE_ADDR_SPACE (c->cand_type), + &addr); +} + /* Replace CAND_REF candidate C, each sibling of candidate C, and each dependent of candidate C with an equivalent strength-reduced data reference. */ @@ -2006,6 +2023,16 @@ replace_ref (tree *expr, slsr_cand_t c) static void replace_refs (slsr_cand_t c) { + /* Replacing a chain of only 2 candidates which are valid memory references + is generally counter-productive because you cannot recoup the additional + calculation added in front of them. */ + if (c->basis == 0 + && c->dependent + && !lookup_cand (c->dependent)->dependent + && valid_mem_ref_cand_p (c) + && valid_mem_ref_cand_p (lookup_cand (c->dependent))) + return; + if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("Replacing reference: ", dump_file); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 947a653..b6dbf76 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-02 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.dg/tree-ssa/slsr-42.c: New test. + 2019-09-02 Martin Liska <mliska@suse.cz> PR c++/91155 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c new file mode 100644 index 0000000..0495fcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-slsr-details" } */ + +struct x +{ + int a[16]; + int b[16]; +}; + +void +set (struct x *p, unsigned int n, int i) +{ + p->a[n] = i; + p->b[n] = i; +} + +/* { dg-final { scan-tree-dump-not "Replacing reference: " "slsr" { target i?86-*-* x86_64-*-* } } } */ |