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>
* sched-deps.c (fixup_sched_groups): Rename to...

View File

@ -2525,6 +2525,30 @@ set_ssa_val_to (tree from, tree to)
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.
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)
{
tree def = DEF_FROM_PTR (defp);
VN_INFO (def)->use_processed = true;
changed |= set_ssa_val_to (def, def);
}
return changed;
@ -2598,27 +2620,41 @@ visit_reference_op_call (tree lhs, gimple stmt)
{
bool changed = false;
struct vn_reference_s vr1;
tree result;
vn_reference_t vnresult = NULL;
tree vuse = gimple_vuse (stmt);
tree vdef = gimple_vdef (stmt);
vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr1.operands = valueize_shared_reference_ops_from_call (stmt);
vr1.type = gimple_expr_type (stmt);
vr1.set = 0;
vr1.hashcode = vn_reference_compute_hash (&vr1);
result = vn_reference_lookup_1 (&vr1, NULL);
if (result)
vn_reference_lookup_1 (&vr1, &vnresult);
if (vnresult)
{
changed = set_ssa_val_to (lhs, result);
if (TREE_CODE (result) == SSA_NAME
&& VN_INFO (result)->has_constants)
VN_INFO (lhs)->has_constants = true;
if (vnresult->result_vdef)
changed |= set_ssa_val_to (vdef, vnresult->result_vdef);
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
{
void **slot;
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->vuse = vr1.vuse;
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->hashcode = vr1.hashcode;
vr2->result = lhs;
vr2->result_vdef = vdef;
slot = htab_find_slot_with_hash (current_info->references,
vr2, vr2->hashcode, INSERT);
if (*slot)
@ -2795,7 +2832,6 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
going to valueize the references in-place. */
if ((vdef = gimple_vdef (stmt)))
{
VN_INFO (vdef)->use_processed = true;
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);
use = gimple_vuse (stmt);
VN_INFO (def)->use_processed = true;
changed |= set_ssa_val_to (def, SSA_VAL (use));
}
@ -3167,7 +3202,7 @@ visit_use (tree use)
bool changed = false;
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));
if (dump_file && (dump_flags & TDF_DETAILS)
@ -3186,8 +3221,7 @@ visit_use (tree use)
{
if (gimple_code (stmt) == GIMPLE_PHI)
changed = visit_phi (stmt);
else if (!gimple_has_lhs (stmt)
|| gimple_has_volatile_ops (stmt))
else if (gimple_has_volatile_ops (stmt))
changed = defs_to_varying (stmt);
else if (is_gimple_assign (stmt))
{
@ -3349,34 +3383,44 @@ visit_use (tree use)
/* ??? We could try to simplify calls. */
if (stmt_has_constants (stmt)
&& TREE_CODE (lhs) == SSA_NAME)
VN_INFO (lhs)->has_constants = true;
else if (TREE_CODE (lhs) == SSA_NAME)
if (lhs && TREE_CODE (lhs) == SSA_NAME)
{
/* We reset expr and constantness here because we may
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 (stmt_has_constants (stmt))
VN_INFO (lhs)->has_constants = true;
else
{
/* We reset expr and constantness here because we may
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. */
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)
&& gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
changed = visit_reference_op_call (lhs, stmt);
else
changed = defs_to_varying (stmt);
changed = visit_reference_op_call (lhs, stmt);
}
else
changed = defs_to_varying (stmt);
}
else
changed = defs_to_varying (stmt);
}
done:
return changed;

View File

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