Commit 6867d9a9 by Tom de Vries Committed by Tom de Vries

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
parent 6cf5e1d0
2012-07-06 Tom de Vries <tom@codesourcery.com> 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 PR tree-optimization/52009
* tree-ssa-tail-merge.c (gimple_equal_p): For GIMPLE_ASSIGN, compare * tree-ssa-tail-merge.c (gimple_equal_p): For GIMPLE_ASSIGN, compare
value numbers of gimple_vdef. value numbers of gimple_vdef.
......
...@@ -946,6 +946,20 @@ copy_reference_ops_from_call (gimple call, ...@@ -946,6 +946,20 @@ copy_reference_ops_from_call (gimple call,
{ {
vn_reference_op_s temp; vn_reference_op_s temp;
unsigned i; 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. */ /* Copy the type, opcode, function being called and static chain. */
memset (&temp, 0, sizeof (temp)); memset (&temp, 0, sizeof (temp));
...@@ -2633,6 +2647,10 @@ visit_reference_op_call (tree lhs, gimple stmt) ...@@ -2633,6 +2647,10 @@ visit_reference_op_call (tree lhs, gimple stmt)
tree vuse = gimple_vuse (stmt); tree vuse = gimple_vuse (stmt);
tree vdef = gimple_vdef (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.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr1.operands = valueize_shared_reference_ops_from_call (stmt); vr1.operands = valueize_shared_reference_ops_from_call (stmt);
vr1.type = gimple_expr_type (stmt); vr1.type = gimple_expr_type (stmt);
...@@ -3424,18 +3442,20 @@ visit_use (tree use) ...@@ -3424,18 +3442,20 @@ visit_use (tree use)
} }
} }
/* ??? We should handle stores from calls. */
if (!gimple_call_internal_p (stmt) if (!gimple_call_internal_p (stmt)
&& (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST) && (/* Calls to the same function with the same vuse
/* If the call has side effects, subsequent calls won't have and the same operands do not necessarily return the same
the same incoming vuse, so it's save to assume value, unless they're pure or const. */
equality. */ gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST)
|| gimple_has_side_effects (stmt)) /* If calls have a vdef, subsequent calls won't have
&& ((lhs && TREE_CODE (lhs) == SSA_NAME) the same incoming vuse. So, if 2 calls with vdef have the
|| (!lhs && gimple_vdef (stmt)))) same vuse, we know they're not subsequent.
{ We can value number 2 calls to the same function with the
changed = visit_reference_op_call (lhs, stmt); 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 else
changed = defs_to_varying (stmt); changed = defs_to_varying (stmt);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment