From: rguenth Date: Wed, 2 May 2007 09:12:49 +0000 (+0000) Subject: 2007-05-02 Richard Guenther X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=6776dec81181ac5268babea9d9e258e8c2ea02b7;hp=1aa4b9ce6554e1b5687f1e0c9a4d1c8cf4a93cd8 2007-05-02 Richard Guenther PR tree-optimization/31146 * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): New argument, single_use_p. If we have a single use that is a conversion to the definition rhs type, propagate that rhs. (forward_propagate_addr_expr): Pass single_use_p argument to forward_propagate_addr_expr_1. * g++.dg/tree-ssa/pr31146-2.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124349 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3882b8b5cd0..d45664ece7c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-05-02 Richard Guenther + + PR tree-optimization/31146 + * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): New + argument, single_use_p. If we have a single use that is + a conversion to the definition rhs type, propagate that rhs. + (forward_propagate_addr_expr): Pass single_use_p argument + to forward_propagate_addr_expr_1. + 2007-05-01 H.J. Lu * config/i386/i386.c (ix86_expand_sse_comi): Remove unused diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ed9816f80e7..287a0973101 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-05-02 Richard Guenther + + PR tree-optimization/31146 + * g++.dg/tree-ssa/pr31146-2.C: New testcase. + 2007-05-01 Geoffrey Keating * gcc.c-torture/compile/limits-blockid.c: New. diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C new file mode 100644 index 00000000000..0fd60275b53 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop1" } */ + +#include + +template +struct Vec +{ + Vec() + { + for (int i=0; i<3; ++i) + new (&a[i]) T(0); + } + T a[3]; +}; + +double foo (void) +{ + Vec v; + return v.a[2]; +} + +/* { dg-final { scan-tree-dump "Replaced .*iftmp.* != 0B. with .1" "forwprop1" } } */ +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 860a4c4da68..d91aa89325d 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -559,7 +559,8 @@ forward_propagate_addr_into_variable_array_index (tree offset, tree lhs, be not totally successful, yet things may have been changed). */ static bool -forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt) +forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt, + bool single_use_p) { tree lhs, rhs, array_ref; @@ -584,10 +585,20 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt) /* Continue propagating into the RHS. */ } - /* Trivial case. The use statement could be a trivial copy or a + /* Trivial cases. The use statement could be a trivial copy or a useless conversion. Recurse to the uses of the lhs as copyprop does not copy through differen variant pointers and FRE does not catch - all useless conversions. */ + all useless conversions. Treat the case of a single-use name and + a conversion to def_rhs type separate, though. */ + else if (TREE_CODE (lhs) == SSA_NAME + && (TREE_CODE (rhs) == NOP_EXPR + || TREE_CODE (rhs) == CONVERT_EXPR) + && TREE_TYPE (rhs) == TREE_TYPE (def_rhs) + && single_use_p) + { + GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs); + return true; + } else if ((TREE_CODE (lhs) == SSA_NAME && rhs == name) || ((TREE_CODE (rhs) == NOP_EXPR @@ -702,6 +713,7 @@ forward_propagate_addr_expr (tree name, tree rhs) imm_use_iterator iter; tree use_stmt; bool all = true; + bool single_use_p = has_single_use (name); FOR_EACH_IMM_USE_STMT (use_stmt, iter, name) { @@ -726,7 +738,8 @@ forward_propagate_addr_expr (tree name, tree rhs) push_stmt_changes (&use_stmt); - result = forward_propagate_addr_expr_1 (name, rhs, use_stmt); + result = forward_propagate_addr_expr_1 (name, rhs, use_stmt, + single_use_p); all &= result; pop_stmt_changes (&use_stmt);