tree-ssa-ccp.c (ccp_fold): Also read from constant values and fold constant aggregate...
authorRichard Guenther <rguenther@suse.de>
Sat, 15 Mar 2008 18:22:26 +0000 (18:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Sat, 15 Mar 2008 18:22:26 +0000 (18:22 +0000)
2008-03-15  Richard Guenther  <rguenther@suse.de>

* tree-ssa-ccp.c (ccp_fold): Also read from constant values
and fold constant aggregate refs.
(fold_const_aggregate_ref): Handle string constants
and constructors in ARRAY_REFs.  Handle INDIRECT_REF.
(evaluate_stmt): Simplify now that ccp_fold folds constant
aggregate refs.

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

From-SVN: r133257

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

index 7c10c75..c3f2d7d 100644 (file)
@@ -1,3 +1,12 @@
+2008-03-15  Richard Guenther  <rguenther@suse.de>
+
+       * tree-ssa-ccp.c (ccp_fold): Also read from constant values
+       and fold constant aggregate refs.
+       (fold_const_aggregate_ref): Handle string constants
+       and constructors in ARRAY_REFs.  Handle INDIRECT_REF.
+       (evaluate_stmt): Simplify now that ccp_fold folds constant
+       aggregate refs.
+
 2008-03-15  Paul Brook  <paul@codesourcery.com>
 
        * config/arm/arm.md (insv): Use gen_insv_t2 and gen_insv_zero.
index ec3196b..da901b2 100644 (file)
@@ -1,3 +1,7 @@
+2008-03-15  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-ccp-16.c: New testcase.
+
 2008-03-15  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR testsuite/35184
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-16.c
new file mode 100644 (file)
index 0000000..33f9744
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1" } */
+
+static const int x;
+
+int test1 (void)
+{
+  char *p = "hello";
+  int i = x;
+  i = i + 5;
+  return p[i];
+}
+
+int test2 (void)
+{
+  int i = x;
+  i = i + 5;
+  return "hello"[i];
+}
+
+/* { dg-final { scan-tree-dump-times "return 0;" 2 "ccp1" } } */
+/* { dg-final { cleanup-tree-dump "ccp1" } } */
index a1eaab2..f087a8d 100644 (file)
@@ -984,6 +984,12 @@ ccp_fold (tree stmt)
       return fold_binary (code, TREE_TYPE (rhs), op0, op1);
     }
 
+  else if (kind == tcc_declaration)
+    return get_symbol_constant_value (rhs);
+
+  else if (kind == tcc_reference)
+    return fold_const_aggregate_ref (rhs);
+
   /* We may be able to fold away calls to builtin functions if their
      arguments are constants.  */
   else if (code == CALL_EXPR
@@ -1062,6 +1068,11 @@ fold_const_aggregate_ref (tree t)
          ctor = fold_const_aggregate_ref (base);
          break;
 
+       case STRING_CST:
+       case CONSTRUCTOR:
+         ctor = base;
+         break;
+
        default:
          return NULL_TREE;
        }
@@ -1162,7 +1173,18 @@ fold_const_aggregate_ref (tree t)
          return fold_build1 (TREE_CODE (t), TREE_TYPE (t), c);
        break;
       }
-    
+
+    case INDIRECT_REF:
+      {
+       tree base = TREE_OPERAND (t, 0);
+       if (TREE_CODE (base) == SSA_NAME
+           && (value = get_value (base))
+           && value->lattice_val == CONSTANT
+           && TREE_CODE (value->value) == ADDR_EXPR)
+         return fold_const_aggregate_ref (TREE_OPERAND (value->value, 0));
+       break;
+      }
+
     default:
       break;
     }
@@ -1190,15 +1212,8 @@ evaluate_stmt (tree stmt)
     simplified = ccp_fold (stmt);
   /* If the statement is likely to have a VARYING result, then do not
      bother folding the statement.  */
-  if (likelyvalue == VARYING)
+  else if (likelyvalue == VARYING)
     simplified = get_rhs (stmt);
-  /* If the statement is an ARRAY_REF or COMPONENT_REF into constant
-     aggregates, extract the referenced constant.  Otherwise the
-     statement is likely to have an UNDEFINED value, and there will be
-     nothing to do.  Note that fold_const_aggregate_ref returns
-     NULL_TREE if the first case does not match.  */
-  else if (!simplified)
-    simplified = fold_const_aggregate_ref (get_rhs (stmt));
 
   is_constant = simplified && is_gimple_min_invariant (simplified);
 
@@ -1265,7 +1280,7 @@ visit_assignment (tree stmt, tree *output_p)
     }
   else
     /* Evaluate the statement.  */
-      val = evaluate_stmt (stmt);
+    val = evaluate_stmt (stmt);
 
   /* If the original LHS was a VIEW_CONVERT_EXPR, modify the constant
      value to be a VIEW_CONVERT_EXPR of the old constant value.