diff options
author | Richard Biener <rguenther@suse.de> | 2014-06-04 11:55:29 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-06-04 11:55:29 +0000 |
commit | b1259d34e96d27a830254cf19bb7c921cd14e4c6 (patch) | |
tree | 8a7dd276505bc9ee18b88032a2740dcfc7620216 /gcc | |
parent | 8be2dc8cb24d93b16176d3bb049482c10cf6ed54 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c | 18 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 56 |
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)) |