aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2005-05-25 18:53:25 +0000
committerDaniel Berlin <dberlin@gcc.gnu.org>2005-05-25 18:53:25 +0000
commit81def1b74bed71f407513a39908cbb9257b1e0d3 (patch)
tree61933f045e45ea3006481c301eadbce38c98ef24
parent14d63fb68e2f60dbb0146ad1618c173a0f2c3078 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c14
-rw-r--r--gcc/tree-ssa-pre.c31
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 ();