OSDN Git Service

2010-02-05 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Feb 2010 15:28:31 +0000 (15:28 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 5 Feb 2010 15:28:31 +0000 (15:28 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156519 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-28.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index a627eaf..1fe28e5 100644 (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
index c8a911a..bc91d58 100644 (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
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 (file)
index 0000000..f5dbe70
--- /dev/null
@@ -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" } } */
index 2383611..a4869d2 100644 (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))
          {