aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/foldstring-1.c11
-rw-r--r--gcc/tree-ssa-ccp.c39
-rw-r--r--gcc/tree-ssa-dom.c10
5 files changed, 62 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a86c2a2..1051c70 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2005-12-14 Jeff Law <law@redhat.com>
+
+ * tree-ssa-ccp.c (fold_stmt_r): DATA argument is now a pointer
+ to a structure containing state rather than a pointer to bool.
+ (case ARRAY_REF): New code to handle folding some array references.
+ (case ADDR_EXPR): Note when we are processing expressions found
+ within an ADDRE_EXPR.
+ (fold_stmt, fold_stmt_inplace): Pass in a structure to fold_stmt_r
+ for state variables rather than just a pointer to a boolean.
+ * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Remove
+ handling of constant string references.
+
2005-12-14 Adrian Straetling <straetling@de.ibm.com>
* config/s390/s390.md ("*tstdi_extimm", "*tstsi_extimm"): Merge.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1045181..c840237 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-12-14 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/foldstring-1.c: New test.
+
2005-12-14 Jakub Jelinek <jakub@redhat.com>
PR target/25254
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/foldstring-1.c b/gcc/testsuite/gcc.dg/tree-ssa/foldstring-1.c
new file mode 100644
index 0000000..25a7ef4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/foldstring-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-useless" } */
+
+void
+arf ()
+{
+ if (""[0] == 0)
+ blah ();
+}
+/* { dg-final { scan-tree-dump-times "= 0;" 1 "useless"} } */
+/* { dg-final { cleanup-tree-dump "useless" } } */
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 39ba4a8..9037b6e 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1922,13 +1922,24 @@ maybe_fold_stmt_addition (tree expr)
return t;
}
+/* For passing state through walk_tree into fold_stmt_r and its
+ children. */
+
+struct fold_stmt_r_data
+{
+ bool *changed_p;
+ bool *inside_addr_expr_p;
+};
+
/* Subroutine of fold_stmt called via walk_tree. We perform several
simplifications of EXPR_P, mostly having to do with pointer arithmetic. */
static tree
fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
{
- bool *changed_p = data;
+ struct fold_stmt_r_data *fold_stmt_r_data = data;
+ bool *inside_addr_expr_p = fold_stmt_r_data->inside_addr_expr_p;
+ bool *changed_p = fold_stmt_r_data->changed_p;
tree expr = *expr_p, t;
/* ??? It'd be nice if walk_tree had a pre-order option. */
@@ -1944,13 +1955,23 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
integer_zero_node);
break;
- /* ??? Could handle ARRAY_REF here, as a variant of INDIRECT_REF.
+ /* ??? Could handle more ARRAY_REFs here, as a variant of INDIRECT_REF.
We'd only want to bother decomposing an existing ARRAY_REF if
the base array is found to have another offset contained within.
Otherwise we'd be wasting time. */
+ case ARRAY_REF:
+ /* If we are not processing expressions found within an
+ ADDR_EXPR, then we can fold constant array references. */
+ if (!*inside_addr_expr_p)
+ t = fold_read_from_constant_string (expr);
+ else
+ t = NULL;
+ break;
case ADDR_EXPR:
+ *inside_addr_expr_p = true;
t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
+ *inside_addr_expr_p = false;
if (t)
return t;
*walk_subtrees = 0;
@@ -2290,13 +2311,18 @@ bool
fold_stmt (tree *stmt_p)
{
tree rhs, result, stmt;
+ struct fold_stmt_r_data fold_stmt_r_data;
bool changed = false;
+ bool inside_addr_expr = false;
+
+ fold_stmt_r_data.changed_p = &changed;
+ fold_stmt_r_data.inside_addr_expr_p = &inside_addr_expr;
stmt = *stmt_p;
/* If we replaced constants and the statement makes pointer dereferences,
then we may need to fold instances of *&VAR into VAR, etc. */
- if (walk_tree (stmt_p, fold_stmt_r, &changed, NULL))
+ if (walk_tree (stmt_p, fold_stmt_r, &fold_stmt_r_data, NULL))
{
*stmt_p
= build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
@@ -2375,9 +2401,14 @@ bool
fold_stmt_inplace (tree stmt)
{
tree old_stmt = stmt, rhs, new_rhs;
+ struct fold_stmt_r_data fold_stmt_r_data;
bool changed = false;
+ bool inside_addr_expr = false;
+
+ fold_stmt_r_data.changed_p = &changed;
+ fold_stmt_r_data.inside_addr_expr_p = &inside_addr_expr;
- walk_tree (&stmt, fold_stmt_r, &changed, NULL);
+ walk_tree (&stmt, fold_stmt_r, &fold_stmt_r_data, NULL);
gcc_assert (stmt == old_stmt);
rhs = get_rhs (stmt);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 4997a1b..683e134 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1837,16 +1837,6 @@ simplify_rhs_and_lookup_avail_expr (tree stmt, int insert)
}
}
- /* Optimize *"foo" into 'f'. This is done here rather than
- in fold to avoid problems with stuff like &*"foo". */
- if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
- {
- tree t = fold_read_from_constant_string (rhs);
-
- if (t)
- result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
- }
-
return result;
}