aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-ssa-strength-reduction.c27
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-42.c17
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-*-* } } } */