tree-ssa-ccp.c (get_symbol_constant_value): Strip all conversions.

2010-02-05  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-ccp.c (get_symbol_constant_value): Strip all
	conversions.
	(fold_const_aggregate_ref): Likewise.
	(ccp_fold_stmt): Substitute loads.
	(maybe_fold_reference): Verify types before substituting.
	Unshare properly.
	(fold_gimple_assign): Unshare properly.
	(fold_stmt_1): Insert conversion if necessary before replacing
	the RHS.

	* gcc.dg/tree-ssa/ssa-ccp-28.c: New testcase.

From-SVN: r156519
This commit is contained in:
Richard Guenther 2010-02-05 15:28:31 +00:00 committed by Richard Biener
parent 64aa00b171
commit 5c95f07b61
4 changed files with 77 additions and 7 deletions

View File

@ -1,3 +1,15 @@
2010-02-05 Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c (get_symbol_constant_value): Strip all
conversions.
(fold_const_aggregate_ref): Likewise.
(ccp_fold_stmt): Substitute loads.
(maybe_fold_reference): Verify types before substituting.
Unshare properly.
(fold_gimple_assign): Unshare properly.
(fold_stmt_1): Insert conversion if necessary before replacing
the RHS.
2010-02-05 Nathan Froyd <froydnj@codesourcery.com>
* config/rs6000/rs6000.c (rs6000_override_options): Invert check

View File

@ -1,3 +1,7 @@
2010-02-05 Richard Guenther <rguenther@suse.de>
* gcc.dg/tree-ssa/ssa-ccp-28.c: New testcase.
2010-02-05 Dodji Seketeli <dodji@redhat.com>
PR c++/42915

View File

@ -0,0 +1,26 @@
/* { dg-do run } */
/* { dg-options "-O -fdump-tree-ccp1" } */
extern void abort (void);
static int g[1];
static int * const p = &g[0];
static int * const q = &g[0];
int main(void)
{
g[0] = 1;
*p = 0;
*p = *q;
if (g[0] != 0)
abort ();
return 0;
}
/* We should have replaced all loads from p and q with the constant
initial value. */
/* { dg-final { scan-tree-dump-times "= p;" 0 "ccp1" } } */
/* { dg-final { scan-tree-dump-times "= q;" 0 "ccp1" } } */
/* { dg-final { cleanup-tree-dump "ccp1" } } */

View File

@ -283,7 +283,7 @@ get_symbol_constant_value (tree sym)
tree val = DECL_INITIAL (sym);
if (val)
{
STRIP_USELESS_TYPE_CONVERSION (val);
STRIP_NOPS (val);
if (is_gimple_min_invariant (val))
{
if (TREE_CODE (val) == ADDR_EXPR)
@ -1297,7 +1297,7 @@ fold_const_aggregate_ref (tree t)
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
if (tree_int_cst_equal (cfield, idx))
{
STRIP_USELESS_TYPE_CONVERSION (cval);
STRIP_NOPS (cval);
if (TREE_CODE (cval) == ADDR_EXPR)
{
tree base = get_base_address (TREE_OPERAND (cval, 0));
@ -1346,7 +1346,7 @@ fold_const_aggregate_ref (tree t)
/* FIXME: Handle bit-fields. */
&& ! DECL_BIT_FIELD (cfield))
{
STRIP_USELESS_TYPE_CONVERSION (cval);
STRIP_NOPS (cval);
if (TREE_CODE (cval) == ADDR_EXPR)
{
tree base = get_base_address (TREE_OPERAND (cval, 0));
@ -1552,6 +1552,28 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
return changed;
}
case GIMPLE_ASSIGN:
{
tree lhs = gimple_assign_lhs (stmt);
prop_value_t *val;
/* If we have a load that turned out to be constant replace it
as we cannot propagate into all uses in all cases. */
if (gimple_assign_single_p (stmt)
&& TREE_CODE (lhs) == SSA_NAME
&& (val = get_value (lhs))
&& val->lattice_val == CONSTANT)
{
tree rhs = unshare_expr (val->value);
if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
rhs = fold_convert (TREE_TYPE (lhs), rhs);
gimple_assign_set_rhs_from_tree (gsi, rhs);
return true;
}
return false;
}
default:
return false;
}
@ -2412,9 +2434,10 @@ maybe_fold_reference (tree expr, bool is_lhs)
&& DECL_P (*t))
{
tree tem = get_symbol_constant_value (*t);
if (tem)
if (tem
&& useless_type_conversion_p (TREE_TYPE (*t), TREE_TYPE (tem)))
{
*t = tem;
*t = unshare_expr (tem);
tem = maybe_fold_reference (expr, is_lhs);
if (tem)
return tem;
@ -2824,7 +2847,7 @@ fold_gimple_assign (gimple_stmt_iterator *si)
}
else if (DECL_P (rhs))
return get_symbol_constant_value (rhs);
return unshare_expr (get_symbol_constant_value (rhs));
/* If we couldn't fold the RHS, hand over to the generic
fold routines. */
@ -3035,7 +3058,12 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
{
unsigned old_num_ops = gimple_num_ops (stmt);
tree new_rhs = fold_gimple_assign (gsi);
if (new_rhs != NULL_TREE
tree lhs = gimple_assign_lhs (stmt);
if (new_rhs
&& !useless_type_conversion_p (TREE_TYPE (lhs),
TREE_TYPE (new_rhs)))
new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
if (new_rhs
&& (!inplace
|| get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
{