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>
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.
......
......@@ -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);
}
......
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