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:
parent
c9dd1d3940
commit
0011592137
@ -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...
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user