re PR tree-optimization/51879 (Missed tail merging with non-const/pure calls)

2012-04-27  Tom de Vries  <tom@codesourcery.com>

	PR tree-optimization/51879
	* tree-ssa-sccvn.h (struct vn_reference_s): Add result_vdef field.
	* tree-ssa-sccvn.c (mark_use_processed): New function, factored out
	of ...
	(defs_to_varying): ... here.  Don't set use_processed.
	(visit_reference_op_call): Handle gimple_vdef.
	Handle case that lhs is NULL_TREE.
	(visit_use): Use mark_use_processed.  Handle calls with side-effect
	using visit_reference_op_call.

From-SVN: r186894
This commit is contained in:
Tom de Vries 2012-04-27 06:12:49 +00:00 committed by Tom de Vries
parent c9dd1d3940
commit 0011592137
3 changed files with 91 additions and 34 deletions

View File

@ -1,3 +1,15 @@
2012-04-27 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/51879
* tree-ssa-sccvn.h (struct vn_reference_s): Add result_vdef field.
* tree-ssa-sccvn.c (mark_use_processed): New function, factored out
of ...
(defs_to_varying): ... here. Don't set use_processed.
(visit_reference_op_call): Handle gimple_vdef.
Handle case that lhs is NULL_TREE.
(visit_use): Use mark_use_processed. Handle calls with side-effect
using visit_reference_op_call.
2012-04-26 Richard Sandiford <richard.sandiford@linaro.org> 2012-04-26 Richard Sandiford <richard.sandiford@linaro.org>
* sched-deps.c (fixup_sched_groups): Rename to... * sched-deps.c (fixup_sched_groups): Rename to...

View File

@ -2525,6 +2525,30 @@ set_ssa_val_to (tree from, tree to)
return false; return false;
} }
/* Mark as processed all the definitions in the defining stmt of USE, or
the USE itself. */
static void
mark_use_processed (tree use)
{
ssa_op_iter iter;
def_operand_p defp;
gimple stmt = SSA_NAME_DEF_STMT (use);
if (SSA_NAME_IS_DEFAULT_DEF (use) || gimple_code (stmt) == GIMPLE_PHI)
{
VN_INFO (use)->use_processed = true;
return;
}
FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
{
tree def = DEF_FROM_PTR (defp);
VN_INFO (def)->use_processed = true;
}
}
/* Set all definitions in STMT to value number to themselves. /* Set all definitions in STMT to value number to themselves.
Return true if a value number changed. */ Return true if a value number changed. */
@ -2538,8 +2562,6 @@ defs_to_varying (gimple stmt)
FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS) FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_ALL_DEFS)
{ {
tree def = DEF_FROM_PTR (defp); tree def = DEF_FROM_PTR (defp);
VN_INFO (def)->use_processed = true;
changed |= set_ssa_val_to (def, def); changed |= set_ssa_val_to (def, def);
} }
return changed; return changed;
@ -2598,27 +2620,41 @@ visit_reference_op_call (tree lhs, gimple stmt)
{ {
bool changed = false; bool changed = false;
struct vn_reference_s vr1; struct vn_reference_s vr1;
tree result; vn_reference_t vnresult = NULL;
tree vuse = gimple_vuse (stmt); tree vuse = gimple_vuse (stmt);
tree vdef = gimple_vdef (stmt);
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);
vr1.set = 0; vr1.set = 0;
vr1.hashcode = vn_reference_compute_hash (&vr1); vr1.hashcode = vn_reference_compute_hash (&vr1);
result = vn_reference_lookup_1 (&vr1, NULL); vn_reference_lookup_1 (&vr1, &vnresult);
if (result)
if (vnresult)
{ {
changed = set_ssa_val_to (lhs, result); if (vnresult->result_vdef)
if (TREE_CODE (result) == SSA_NAME changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
&& VN_INFO (result)->has_constants)
VN_INFO (lhs)->has_constants = true; if (!vnresult->result && lhs)
vnresult->result = lhs;
if (vnresult->result && lhs)
{
changed |= set_ssa_val_to (lhs, vnresult->result);
if (VN_INFO (vnresult->result)->has_constants)
VN_INFO (lhs)->has_constants = true;
}
} }
else else
{ {
void **slot; void **slot;
vn_reference_t vr2; vn_reference_t vr2;
changed = set_ssa_val_to (lhs, lhs); if (vdef)
changed |= set_ssa_val_to (vdef, vdef);
if (lhs)
changed |= set_ssa_val_to (lhs, lhs);
vr2 = (vn_reference_t) pool_alloc (current_info->references_pool); vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
vr2->vuse = vr1.vuse; vr2->vuse = vr1.vuse;
vr2->operands = valueize_refs (create_reference_ops_from_call (stmt)); vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
@ -2626,6 +2662,7 @@ visit_reference_op_call (tree lhs, gimple stmt)
vr2->set = vr1.set; vr2->set = vr1.set;
vr2->hashcode = vr1.hashcode; vr2->hashcode = vr1.hashcode;
vr2->result = lhs; vr2->result = lhs;
vr2->result_vdef = vdef;
slot = htab_find_slot_with_hash (current_info->references, slot = htab_find_slot_with_hash (current_info->references,
vr2, vr2->hashcode, INSERT); vr2, vr2->hashcode, INSERT);
if (*slot) if (*slot)
@ -2795,7 +2832,6 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
going to valueize the references in-place. */ going to valueize the references in-place. */
if ((vdef = gimple_vdef (stmt))) if ((vdef = gimple_vdef (stmt)))
{ {
VN_INFO (vdef)->use_processed = true;
changed |= set_ssa_val_to (vdef, vdef); changed |= set_ssa_val_to (vdef, vdef);
} }
@ -2817,7 +2853,6 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
def = gimple_vdef (stmt); def = gimple_vdef (stmt);
use = gimple_vuse (stmt); use = gimple_vuse (stmt);
VN_INFO (def)->use_processed = true;
changed |= set_ssa_val_to (def, SSA_VAL (use)); changed |= set_ssa_val_to (def, SSA_VAL (use));
} }
@ -3167,7 +3202,7 @@ visit_use (tree use)
bool changed = false; bool changed = false;
gimple stmt = SSA_NAME_DEF_STMT (use); gimple stmt = SSA_NAME_DEF_STMT (use);
VN_INFO (use)->use_processed = true; mark_use_processed (use);
gcc_assert (!SSA_NAME_IN_FREE_LIST (use)); gcc_assert (!SSA_NAME_IN_FREE_LIST (use));
if (dump_file && (dump_flags & TDF_DETAILS) if (dump_file && (dump_flags & TDF_DETAILS)
@ -3186,8 +3221,7 @@ visit_use (tree use)
{ {
if (gimple_code (stmt) == GIMPLE_PHI) if (gimple_code (stmt) == GIMPLE_PHI)
changed = visit_phi (stmt); changed = visit_phi (stmt);
else if (!gimple_has_lhs (stmt) else if (gimple_has_volatile_ops (stmt))
|| gimple_has_volatile_ops (stmt))
changed = defs_to_varying (stmt); changed = defs_to_varying (stmt);
else if (is_gimple_assign (stmt)) else if (is_gimple_assign (stmt))
{ {
@ -3349,34 +3383,44 @@ visit_use (tree use)
/* ??? We could try to simplify calls. */ /* ??? We could try to simplify calls. */
if (stmt_has_constants (stmt) if (lhs && TREE_CODE (lhs) == SSA_NAME)
&& TREE_CODE (lhs) == SSA_NAME)
VN_INFO (lhs)->has_constants = true;
else if (TREE_CODE (lhs) == SSA_NAME)
{ {
/* We reset expr and constantness here because we may if (stmt_has_constants (stmt))
have been value numbering optimistically, and VN_INFO (lhs)->has_constants = true;
iterating. They may become non-constant in this case, else
even if they were optimistically constant. */ {
VN_INFO (lhs)->has_constants = false; /* We reset expr and constantness here because we may
VN_INFO (lhs)->expr = NULL_TREE; have been value numbering optimistically, and
iterating. They may become non-constant in this case,
even if they were optimistically constant. */
VN_INFO (lhs)->has_constants = false;
VN_INFO (lhs)->expr = NULL_TREE;
}
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
{
changed = defs_to_varying (stmt);
goto done;
}
} }
if (TREE_CODE (lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
changed = defs_to_varying (stmt);
/* ??? We should handle stores from calls. */ /* ??? We should handle stores from calls. */
else if (TREE_CODE (lhs) == SSA_NAME) 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))))
{ {
if (!gimple_call_internal_p (stmt) changed = visit_reference_op_call (lhs, stmt);
&& gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
changed = visit_reference_op_call (lhs, stmt);
else
changed = defs_to_varying (stmt);
} }
else else
changed = defs_to_varying (stmt); changed = defs_to_varying (stmt);
} }
else
changed = defs_to_varying (stmt);
} }
done: done:
return changed; return changed;

View File

@ -110,6 +110,7 @@ typedef struct vn_reference_s
tree type; tree type;
VEC (vn_reference_op_s, heap) *operands; VEC (vn_reference_op_s, heap) *operands;
tree result; tree result;
tree result_vdef;
} *vn_reference_t; } *vn_reference_t;
typedef const struct vn_reference_s *const_vn_reference_t; typedef const struct vn_reference_s *const_vn_reference_t;