diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2005-05-25 18:53:25 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2005-05-25 18:53:25 +0000 |
commit | 81def1b74bed71f407513a39908cbb9257b1e0d3 (patch) | |
tree | 61933f045e45ea3006481c301eadbce38c98ef24 | |
parent | 14d63fb68e2f60dbb0146ad1618c173a0f2c3078 (diff) | |
download | gcc-81def1b74bed71f407513a39908cbb9257b1e0d3.zip gcc-81def1b74bed71f407513a39908cbb9257b1e0d3.tar.gz gcc-81def1b74bed71f407513a39908cbb9257b1e0d3.tar.bz2 |
re PR tree-optimization/21705 (FRE does not eliminate a redundant pure call.)
2005-05-25 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/21705
* tree-ssa-pre.c (in_fre): New static variable.
(create_value_expr_from): Recursively value number reference ops
in argument lists.
(can_value_number_call): Temporary restrict only exists for
PRE, not FRE.
From-SVN: r100156
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c | 14 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.c | 31 |
3 files changed, 49 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9974687..175726d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-05-25 Daniel Berlin <dberlin@dberlin.org> + + Fix PR tree-optimization/21705 + + * tree-ssa-pre.c (in_fre): New static variable. + (create_value_expr_from): Recursively value number reference ops + in argument lists. + (can_value_number_call): Temporary restrict only exists for + PRE, not FRE. + 2005-05-25 Kazu Hirata <kazu@cs.umass.edu> * tree-into-ssa.c (rewrite_into_ssa, update_ssa): Replace diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c new file mode 100644 index 0000000..9ead438 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +extern unsigned int strlen (const char *) __attribute__ ((__pure__)); + +void +foo (const char *str) +{ + unsigned int a = strlen (str); + unsigned int b = strlen (str); + if (a != b) + link_error (); +} +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 2482a13..c0b8e45 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -178,6 +178,8 @@ Boston, MA 02111-1307, USA. */ useful only for debugging, since we don't do identity lookups. */ +static bool in_fre = false; + /* A value set element. Basically a single linked list of expressions/values. */ typedef struct value_set_node @@ -2030,17 +2032,32 @@ create_value_expr_from (tree expr, basic_block block, tree stmt) if (code == TREE_LIST) { + tree op = NULL_TREE; tree temp = NULL_TREE; if (TREE_CHAIN (vexpr)) temp = create_value_expr_from (TREE_CHAIN (vexpr), block, stmt); TREE_CHAIN (vexpr) = temp ? temp : TREE_CHAIN (vexpr); + + /* Recursively value-numberize reference ops. */ + if (REFERENCE_CLASS_P (TREE_VALUE (vexpr))) + { + tree tempop; + op = TREE_VALUE (vexpr); + tempop = create_value_expr_from (op, block, stmt); + op = tempop ? tempop : op; + + TREE_VALUE (vexpr) = vn_lookup_or_add (op, stmt); + } + else + { + op = TREE_VALUE (vexpr); + TREE_VALUE (vexpr) = vn_lookup_or_add (TREE_VALUE (vexpr), NULL); + } /* This is the equivalent of inserting op into EXP_GEN like we do below */ - if (!is_undefined_value (TREE_VALUE (vexpr))) - value_insert_into_set (EXP_GEN (block), TREE_VALUE (vexpr)); - - TREE_VALUE (vexpr) = vn_lookup_or_add (TREE_VALUE (vexpr), NULL); + if (!is_undefined_value (op)) + value_insert_into_set (EXP_GEN (block), op); return vexpr; } @@ -2108,8 +2125,8 @@ can_value_number_call (tree stmt) tree call = get_call_expr_in (stmt); /* This is a temporary restriction until we translate vuses through - phi nodes. */ - if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)) + phi nodes. This is only needed for PRE, of course. */ + if (!in_fre && !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)) return false; if (call_expr_flags (call) & (ECF_PURE | ECF_CONST)) return true; @@ -2454,6 +2471,8 @@ static void init_pre (bool do_fre) { basic_block bb; + + in_fre = do_fre; inserted_exprs = NULL; vn_init (); |