aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2016-12-06 23:18:17 +0000
committerJeff Law <law@gcc.gnu.org>2016-12-06 16:18:17 -0700
commit8194dcdd37de477dcb0be39d912a7eb1d465a2c4 (patch)
treecdfd7ffd14ae7f74519400f89ffe5243b71aeb31 /gcc
parent6b8805cfce8847a0d944150845cb908b6ee0ba57 (diff)
downloadgcc-8194dcdd37de477dcb0be39d912a7eb1d465a2c4.zip
gcc-8194dcdd37de477dcb0be39d912a7eb1d465a2c4.tar.gz
gcc-8194dcdd37de477dcb0be39d912a7eb1d465a2c4.tar.bz2
re PR tree-optimization/67955 (tree-dse does not use pointer info)
PR tree-optimization/67955 * tree-ssa-alias.c (same_addr_size_stores_p): New function. (stmt_kills_ref_p): Use it. PR tree-optimization/67955 * gcc.dg/tree-ssa/dse-points-to.c: New test. From-SVN: r243325
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c15
-rw-r--r--gcc/tree-ssa-alias.c77
4 files changed, 103 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61eeea3..797b711 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-12-06 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/67955
+ * tree-ssa-alias.c (same_addr_size_stores_p): New function.
+ (stmt_kills_ref_p): Use it.
+
2016-12-06 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/78700
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5adcdd2..6090a96 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-12-06 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/67955
+ * gcc.dg/tree-ssa/dse-points-to.c: New test.
+
2016-12-06 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78658
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c b/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
new file mode 100644
index 0000000..8003556
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre -fno-tree-vrp" } */
+/* { dg-additional-options "-fdump-tree-dse1-details" } */
+
+int
+f ()
+{
+ int a;
+ int *p = &a;
+ *p = 1;
+ a = 2;
+ return a;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store.*p_1" 1 "dse1"} } */
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 10f1677..37b581d 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2316,6 +2316,78 @@ stmt_may_clobber_ref_p (gimple *stmt, tree ref)
return stmt_may_clobber_ref_p_1 (stmt, &r);
}
+/* Return true if store1 and store2 described by corresponding tuples
+ <BASE, OFFSET, SIZE, MAX_SIZE> have the same size and store to the same
+ address. */
+
+static bool
+same_addr_size_stores_p (tree base1, HOST_WIDE_INT offset1, HOST_WIDE_INT size1,
+ HOST_WIDE_INT max_size1,
+ tree base2, HOST_WIDE_INT offset2, HOST_WIDE_INT size2,
+ HOST_WIDE_INT max_size2)
+{
+ /* For now, just handle VAR_DECL. */
+ bool base1_obj_p = VAR_P (base1);
+ bool base2_obj_p = VAR_P (base2);
+
+ /* We need one object. */
+ if (base1_obj_p == base2_obj_p)
+ return false;
+ tree obj = base1_obj_p ? base1 : base2;
+
+ /* And we need one MEM_REF. */
+ bool base1_memref_p = TREE_CODE (base1) == MEM_REF;
+ bool base2_memref_p = TREE_CODE (base2) == MEM_REF;
+ if (base1_memref_p == base2_memref_p)
+ return false;
+ tree memref = base1_memref_p ? base1 : base2;
+
+ /* Sizes need to be valid. */
+ if (max_size1 == -1 || max_size2 == -1
+ || size1 == -1 || size2 == -1)
+ return false;
+
+ /* Max_size needs to match size. */
+ if (max_size1 != size1
+ || max_size2 != size2)
+ return false;
+
+ /* Sizes need to match. */
+ if (size1 != size2)
+ return false;
+
+ /* Offsets need to be 0. */
+ if (offset1 != 0
+ || offset2 != 0)
+ return false;
+
+ /* Check that memref is a store to pointer with singleton points-to info. */
+ if (!tree_int_cst_equal (TREE_OPERAND (memref, 1), integer_zero_node))
+ return false;
+ tree ptr = TREE_OPERAND (memref, 0);
+ if (TREE_CODE (ptr) != SSA_NAME)
+ return false;
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
+ unsigned int pt_uid;
+ if (pi == NULL
+ || !pt_solution_singleton_or_null_p (&pi->pt, &pt_uid))
+ return false;
+
+ /* Check that ptr points relative to obj. */
+ unsigned int obj_uid = (DECL_PT_UID_SET_P (obj)
+ ? DECL_PT_UID (obj)
+ : DECL_UID (obj));
+ if (obj_uid != pt_uid)
+ return false;
+
+ /* Check that the object size is the same as the store size. That ensures us
+ that ptr points to the start of obj. */
+ if (!tree_fits_shwi_p (DECL_SIZE (obj)))
+ return false;
+ HOST_WIDE_INT obj_size = tree_to_shwi (DECL_SIZE (obj));
+ return obj_size == size1;
+}
+
/* If STMT kills the memory reference REF return true, otherwise
return false. */
@@ -2393,6 +2465,11 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
so base == ref->base does not always hold. */
if (base != ref->base)
{
+ /* Try using points-to info. */
+ if (same_addr_size_stores_p (base, offset, size, max_size, ref->base,
+ ref->offset, ref->size, ref->max_size))
+ return true;
+
/* If both base and ref->base are MEM_REFs, only compare the
first operand, and if the second operand isn't equal constant,
try to add the offsets into offset and ref_offset. */