diff options
author | Tom de Vries <tom@codesourcery.com> | 2012-07-06 11:22:06 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2012-07-06 11:22:06 +0000 |
commit | 6867d9a9c5d90644fd0d1a20c802dc10cdd2c614 (patch) | |
tree | b8a5232a7a7ad1c720000d14143a6703598865c1 | |
parent | 6cf5e1d0514b6bba0e3b5d59b440dd7a451e6d1f (diff) | |
download | gcc-6867d9a9c5d90644fd0d1a20c802dc10cdd2c614.zip gcc-6867d9a9c5d90644fd0d1a20c802dc10cdd2c614.tar.gz gcc-6867d9a9c5d90644fd0d1a20c802dc10cdd2c614.tar.bz2 |
re PR tree-optimization/51879 (Missed tail merging with non-const/pure calls)
2012-07-06 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/51879
* tree-ssa-sccvn.c (copy_reference_ops_from_call)
(visit_reference_op_call): Handle case that lhs is not an SSA_NAME.
(visit_use): Also call visit_reference_op_call for calls with a vdef.
From-SVN: r189323
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 42 |
2 files changed, 38 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 12339ad..871e023 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2012-07-06 Tom de Vries <tom@codesourcery.com> + PR tree-optimization/51879 + * tree-ssa-sccvn.c (copy_reference_ops_from_call) + (visit_reference_op_call): Handle case that lhs is not an SSA_NAME. + (visit_use): Also call visit_reference_op_call for calls with a vdef. + +2012-07-06 Tom de Vries <tom@codesourcery.com> + PR tree-optimization/52009 * tree-ssa-tail-merge.c (gimple_equal_p): For GIMPLE_ASSIGN, compare value numbers of gimple_vdef. diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index cd1acde..c1102a2 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -946,6 +946,20 @@ copy_reference_ops_from_call (gimple call, { vn_reference_op_s temp; unsigned i; + tree lhs = gimple_call_lhs (call); + + /* If 2 calls have a different non-ssa lhs, vdef value numbers should be + different. By adding the lhs here in the vector, we ensure that the + hashcode is different, guaranteeing a different value number. */ + if (lhs && TREE_CODE (lhs) != SSA_NAME) + { + memset (&temp, 0, sizeof (temp)); + temp.opcode = MODIFY_EXPR; + temp.type = TREE_TYPE (lhs); + temp.op0 = lhs; + temp.off = -1; + VEC_safe_push (vn_reference_op_s, heap, *result, &temp); + } /* Copy the type, opcode, function being called and static chain. */ memset (&temp, 0, sizeof (temp)); @@ -2633,6 +2647,10 @@ visit_reference_op_call (tree lhs, gimple stmt) tree vuse = gimple_vuse (stmt); tree vdef = gimple_vdef (stmt); + /* Non-ssa lhs is handled in copy_reference_ops_from_call. */ + if (lhs && TREE_CODE (lhs) != SSA_NAME) + lhs = NULL_TREE; + vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE; vr1.operands = valueize_shared_reference_ops_from_call (stmt); vr1.type = gimple_expr_type (stmt); @@ -3424,18 +3442,20 @@ visit_use (tree use) } } - /* ??? We should handle stores from calls. */ if (!gimple_call_internal_p (stmt) - && (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST) - /* If the call has side effects, subsequent calls won't have - the same incoming vuse, so it's save to assume - equality. */ - || gimple_has_side_effects (stmt)) - && ((lhs && TREE_CODE (lhs) == SSA_NAME) - || (!lhs && gimple_vdef (stmt)))) - { - changed = visit_reference_op_call (lhs, stmt); - } + && (/* Calls to the same function with the same vuse + and the same operands do not necessarily return the same + value, unless they're pure or const. */ + gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST) + /* If calls have a vdef, subsequent calls won't have + the same incoming vuse. So, if 2 calls with vdef have the + same vuse, we know they're not subsequent. + We can value number 2 calls to the same function with the + same vuse and the same operands which are not subsequent + the same, because there is no code in the program that can + compare the 2 values. */ + || gimple_vdef (stmt))) + changed = visit_reference_op_call (lhs, stmt); else changed = defs_to_varying (stmt); } |