diff options
author | Richard Guenther <rguenther@suse.de> | 2007-05-02 09:12:49 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-05-02 09:12:49 +0000 |
commit | f6c5fefc1dee760599da3d7b1bc513fd59f6c6e8 (patch) | |
tree | 0cd1c91e1be36ab612ad8a524b6f6fdb8d5392e2 /gcc/tree-ssa-forwprop.c | |
parent | d7598e110d060f8b7fb6598736f68700b20c400f (diff) | |
download | gcc-f6c5fefc1dee760599da3d7b1bc513fd59f6c6e8.zip gcc-f6c5fefc1dee760599da3d7b1bc513fd59f6c6e8.tar.gz gcc-f6c5fefc1dee760599da3d7b1bc513fd59f6c6e8.tar.bz2 |
re PR tree-optimization/31146 (forwprop does not look through casts)
2007-05-02 Richard Guenther <rguenther@suse.de>
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.
From-SVN: r124349
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 860a4c4..d91aa89 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); |