diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-12-14 16:15:53 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-12-14 16:15:53 +0000 |
commit | 0d759d9c1d5f7eb91c9557c6801e01915ed8ab66 (patch) | |
tree | 508d1e36512ecd1b4e57698cc4a555112ed60e53 /gcc/tree-ssa-ccp.c | |
parent | 2e204c1208737e96130449b8c480021282d61f77 (diff) | |
download | gcc-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.c | 39 |
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); |