diff options
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/foldstring-1.c | 11 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 39 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.c | 10 |
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; } |