Commit 8194dcdd by Tom de Vries Committed by Jeff Law

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
parent 6b8805cf
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> 2016-12-06 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/78700 PR middle-end/78700
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> 2016-12-06 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/78658 PR target/78658
......
/* { 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"} } */
...@@ -2316,6 +2316,78 @@ stmt_may_clobber_ref_p (gimple *stmt, tree ref) ...@@ -2316,6 +2316,78 @@ stmt_may_clobber_ref_p (gimple *stmt, tree ref)
return stmt_may_clobber_ref_p_1 (stmt, &r); 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 /* If STMT kills the memory reference REF return true, otherwise
return false. */ return false. */
...@@ -2393,6 +2465,11 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref) ...@@ -2393,6 +2465,11 @@ stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
so base == ref->base does not always hold. */ so base == ref->base does not always hold. */
if (base != ref->base) 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 /* If both base and ref->base are MEM_REFs, only compare the
first operand, and if the second operand isn't equal constant, first operand, and if the second operand isn't equal constant,
try to add the offsets into offset and ref_offset. */ try to add the offsets into offset and ref_offset. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment