aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tom@codesourcery.com>2012-07-06 11:22:06 +0000
committerTom de Vries <vries@gcc.gnu.org>2012-07-06 11:22:06 +0000
commit6867d9a9c5d90644fd0d1a20c802dc10cdd2c614 (patch)
treeb8a5232a7a7ad1c720000d14143a6703598865c1
parent6cf5e1d0514b6bba0e3b5d59b440dd7a451e6d1f (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/tree-ssa-sccvn.c42
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);
}