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
This commit is contained in:
Tom de Vries 2016-12-06 23:18:17 +00:00 committed by Jeff Law
parent 6b8805cfce
commit 8194dcdd37
4 changed files with 103 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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"} } */

View File

@ -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. */