aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-06-04 11:55:29 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-06-04 11:55:29 +0000
commitb1259d34e96d27a830254cf19bb7c921cd14e4c6 (patch)
tree8a7dd276505bc9ee18b88032a2740dcfc7620216 /gcc
parent8be2dc8cb24d93b16176d3bb049482c10cf6ed54 (diff)
downloadgcc-b1259d34e96d27a830254cf19bb7c921cd14e4c6.zip
gcc-b1259d34e96d27a830254cf19bb7c921cd14e4c6.tar.gz
gcc-b1259d34e96d27a830254cf19bb7c921cd14e4c6.tar.bz2
tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling of accesses with non-invariant address.
2014-06-04 Richard Biener <rguenther@suse.de> * tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling of accesses with non-invariant address. * gcc.dg/tree-ssa/ssa-dse-16.c: New testcase. From-SVN: r211223
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c18
-rw-r--r--gcc/tree-ssa-alias.c56
4 files changed, 76 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e892d70..d82234c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-06-04 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling
+ of accesses with non-invariant address.
+
2014-06-04 Martin Liska <mliska@suse.cz>
* cgraph.h (cgraph_make_wrapper): New function introduced.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4146bde..b3e39d3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-06-04 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-dse-16.c: New testcase.
+
2014-06-04 Igor Zamyatin <igor.zamyatin@intel.com>
PR c/58942
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c
new file mode 100644
index 0000000..1cc512c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dse1-details" } */
+
+struct X { struct A { int a[2]; } b[10]; };
+void foo (struct X *x, int i)
+{
+ struct A a;
+ /* Confuse SRA here with using a variable index, otherwise it will mess
+ with the IL too much. */
+ a.a[i] = 3;
+ a.a[1] = 0;
+ /* The following store is dead. */
+ x->b[i].a[0] = 1;
+ x->b[i] = a;
+}
+
+/* { dg-final { scan-tree-dump "Deleted dead store" "dse1" } } */
+/* { dg-final { cleanup-tree-dump "dse1" } } */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 0371070..f18cb48 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2174,11 +2174,7 @@ stmt_may_clobber_ref_p (gimple stmt, tree ref)
static bool
stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
{
- /* For a must-alias check we need to be able to constrain
- the access properly.
- FIXME: except for BUILTIN_FREE. */
- if (!ao_ref_base (ref)
- || ref->max_size == -1)
+ if (!ao_ref_base (ref))
return false;
if (gimple_has_lhs (stmt)
@@ -2191,9 +2187,51 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
might throw as well. */
&& !stmt_can_throw_internal (stmt))
{
- tree base, lhs = gimple_get_lhs (stmt);
+ tree lhs = gimple_get_lhs (stmt);
+ /* If LHS is literally a base of the access we are done. */
+ if (ref->ref)
+ {
+ tree base = ref->ref;
+ if (handled_component_p (base))
+ {
+ tree saved_lhs0 = NULL_TREE;
+ if (handled_component_p (lhs))
+ {
+ saved_lhs0 = TREE_OPERAND (lhs, 0);
+ TREE_OPERAND (lhs, 0) = integer_zero_node;
+ }
+ do
+ {
+ /* Just compare the outermost handled component, if
+ they are equal we have found a possible common
+ base. */
+ tree saved_base0 = TREE_OPERAND (base, 0);
+ TREE_OPERAND (base, 0) = integer_zero_node;
+ bool res = operand_equal_p (lhs, base, 0);
+ TREE_OPERAND (base, 0) = saved_base0;
+ if (res)
+ break;
+ /* Otherwise drop handled components of the access. */
+ base = saved_base0;
+ }
+ while (handled_component_p (base));
+ if (saved_lhs0)
+ TREE_OPERAND (lhs, 0) = saved_lhs0;
+ }
+ /* Finally check if lhs is equal or equal to the base candidate
+ of the access. */
+ if (operand_equal_p (lhs, base, 0))
+ return true;
+ }
+
+ /* Now look for non-literal equal bases with the restriction of
+ handling constant offset and size. */
+ /* For a must-alias check we need to be able to constrain
+ the access properly. */
+ if (ref->max_size == -1)
+ return false;
HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset;
- base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
+ tree base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
/* We can get MEM[symbol: sZ, index: D.8862_1] here,
so base == ref->base does not always hold. */
if (base != ref->base)
@@ -2261,6 +2299,10 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
case BUILT_IN_MEMMOVE_CHK:
case BUILT_IN_MEMSET_CHK:
{
+ /* For a must-alias check we need to be able to constrain
+ the access properly. */
+ if (ref->max_size == -1)
+ return false;
tree dest = gimple_call_arg (stmt, 0);
tree len = gimple_call_arg (stmt, 2);
if (!tree_fits_shwi_p (len))