From 5c95f07b6154507f16f349d69f0aef23266c81ac Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Fri, 5 Feb 2010 15:28:31 +0000 Subject: [PATCH] tree-ssa-ccp.c (get_symbol_constant_value): Strip all conversions. 2010-02-05 Richard Guenther * 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 --- gcc/ChangeLog | 12 +++++++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-28.c | 26 ++++++++++++++++++ gcc/tree-ssa-ccp.c | 42 +++++++++++++++++++++++++----- 4 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-28.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a627eaf..1fe28e5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2010-02-05 Richard Guenther + + * 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 * config/rs6000/rs6000.c (rs6000_override_options): Invert check diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c8a911a..bc91d58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-02-05 Richard Guenther + + * gcc.dg/tree-ssa/ssa-ccp-28.c: New testcase. + 2010-02-05 Dodji Seketeli PR c++/42915 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-28.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-28.c new file mode 100644 index 0000000..f5dbe70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-28.c @@ -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" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 2383611..a4869d2 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -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)) { -- 2.7.4