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:
parent
6b8805cfce
commit
8194dcdd37
@ -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
|
||||
|
@ -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
|
||||
|
15
gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
Normal file
15
gcc/testsuite/gcc.dg/tree-ssa/dse-points-to.c
Normal 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"} } */
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user