summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-14 16:15:53 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-14 16:15:53 +0000
commit0d759d9c1d5f7eb91c9557c6801e01915ed8ab66 (patch)
tree508d1e36512ecd1b4e57698cc4a555112ed60e53 /gcc/tree-ssa-ccp.c
parent2e204c1208737e96130449b8c480021282d61f77 (diff)
downloadgcc-0d759d9c1d5f7eb91c9557c6801e01915ed8ab66.tar.gz
* 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. * gcc.dg/tree-ssa/foldstring-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108519 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 39ba4a8a48f..9037b6e1d37 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);