re PR tree-optimization/52009 (Another missed tail merging opportunity)

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.
	* tree-ssa-sccvn.h (vn_reference_insert): Add vdef parameter to
	prototype.
	* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle MODIFY_EXPR.
	(vn_reference_insert): Add and handle vdef parameter.
	(visit_reference_op_load): Add argument to vn_reference_insert call.
	(visit_reference_op_store): Find value number of vdef of store.  Insert
	value number of vdef of store.

From-SVN: r189321
This commit is contained in:
Tom de Vries 2012-07-06 11:07:32 +00:00 committed by Tom de Vries
parent e81941b70e
commit 4ec0a19888
4 changed files with 50 additions and 13 deletions

View File

@ -1,3 +1,16 @@
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.
* tree-ssa-sccvn.h (vn_reference_insert): Add vdef parameter to
prototype.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Handle MODIFY_EXPR.
(vn_reference_insert): Add and handle vdef parameter.
(visit_reference_op_load): Add argument to vn_reference_insert call.
(visit_reference_op_store): Find value number of vdef of store. Insert
value number of vdef of store.
2012-07-06 Uros Bizjak <ubizjak@gmail.com> 2012-07-06 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (simple lea to add peephole): Also transform * config/i386/i386.md (simple lea to add peephole): Also transform

View File

@ -628,6 +628,9 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
switch (temp.opcode) switch (temp.opcode)
{ {
case MODIFY_EXPR:
temp.op0 = TREE_OPERAND (ref, 1);
break;
case WITH_SIZE_EXPR: case WITH_SIZE_EXPR:
temp.op0 = TREE_OPERAND (ref, 1); temp.op0 = TREE_OPERAND (ref, 1);
temp.off = 0; temp.off = 0;
@ -748,6 +751,7 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
VEC_safe_push (vn_reference_op_s, heap, *result, &temp); VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
if (REFERENCE_CLASS_P (ref) if (REFERENCE_CLASS_P (ref)
|| TREE_CODE (ref) == MODIFY_EXPR
|| TREE_CODE (ref) == WITH_SIZE_EXPR || TREE_CODE (ref) == WITH_SIZE_EXPR
|| (TREE_CODE (ref) == ADDR_EXPR || (TREE_CODE (ref) == ADDR_EXPR
&& !is_gimple_min_invariant (ref))) && !is_gimple_min_invariant (ref)))
@ -1941,7 +1945,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
RESULT, and return the resulting reference structure we created. */ RESULT, and return the resulting reference structure we created. */
vn_reference_t vn_reference_t
vn_reference_insert (tree op, tree result, tree vuse) vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
{ {
void **slot; void **slot;
vn_reference_t vr1; vn_reference_t vr1;
@ -1957,6 +1961,7 @@ vn_reference_insert (tree op, tree result, tree vuse)
vr1->set = get_alias_set (op); vr1->set = get_alias_set (op);
vr1->hashcode = vn_reference_compute_hash (vr1); vr1->hashcode = vn_reference_compute_hash (vr1);
vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result; vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
vr1->result_vdef = vdef;
slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode, slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
INSERT); INSERT);
@ -2775,7 +2780,7 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt)
else else
{ {
changed = set_ssa_val_to (lhs, lhs); changed = set_ssa_val_to (lhs, lhs);
vn_reference_insert (op, lhs, last_vuse); vn_reference_insert (op, lhs, last_vuse, NULL_TREE);
} }
return changed; return changed;
@ -2789,8 +2794,11 @@ static bool
visit_reference_op_store (tree lhs, tree op, gimple stmt) visit_reference_op_store (tree lhs, tree op, gimple stmt)
{ {
bool changed = false; bool changed = false;
tree result; vn_reference_t vnresult = NULL;
tree result, assign;
bool resultsame = false; bool resultsame = false;
tree vuse = gimple_vuse (stmt);
tree vdef = gimple_vdef (stmt);
/* First we want to lookup using the *vuses* from the store and see /* First we want to lookup using the *vuses* from the store and see
if there the last store to this location with the same address if there the last store to this location with the same address
@ -2808,7 +2816,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
Otherwise, the vdefs for the store are used when inserting into Otherwise, the vdefs for the store are used when inserting into
the table, since the store generates a new memory state. */ the table, since the store generates a new memory state. */
result = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_NOWALK, NULL); result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL);
if (result) if (result)
{ {
@ -2821,8 +2829,17 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
if (!result || !resultsame) if (!result || !resultsame)
{ {
tree vdef; assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult);
if (vnresult)
{
VN_INFO (vdef)->use_processed = true;
return set_ssa_val_to (vdef, vnresult->result_vdef);
}
}
if (!result || !resultsame)
{
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
fprintf (dump_file, "No store match\n"); fprintf (dump_file, "No store match\n");
@ -2834,7 +2851,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
} }
/* Have to set value numbers before insert, since insert is /* Have to set value numbers before insert, since insert is
going to valueize the references in-place. */ going to valueize the references in-place. */
if ((vdef = gimple_vdef (stmt))) if (vdef)
{ {
changed |= set_ssa_val_to (vdef, vdef); changed |= set_ssa_val_to (vdef, vdef);
} }
@ -2842,22 +2859,21 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
/* Do not insert structure copies into the tables. */ /* Do not insert structure copies into the tables. */
if (is_gimple_min_invariant (op) if (is_gimple_min_invariant (op)
|| is_gimple_reg (op)) || is_gimple_reg (op))
vn_reference_insert (lhs, op, vdef); vn_reference_insert (lhs, op, vdef, NULL);
assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
vn_reference_insert (assign, lhs, vuse, vdef);
} }
else else
{ {
/* We had a match, so value number the vdef to have the value /* We had a match, so value number the vdef to have the value
number of the vuse it came from. */ number of the vuse it came from. */
tree def, use;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Store matched earlier value," fprintf (dump_file, "Store matched earlier value,"
"value numbering store vdefs to matching vuses.\n"); "value numbering store vdefs to matching vuses.\n");
def = gimple_vdef (stmt); changed |= set_ssa_val_to (vdef, SSA_VAL (vuse));
use = gimple_vuse (stmt);
changed |= set_ssa_val_to (def, SSA_VAL (use));
} }
return changed; return changed;

View File

@ -200,7 +200,7 @@ tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *, VEC (vn_reference_op_s, heap) *,
vn_reference_t *, vn_lookup_kind); vn_reference_t *, vn_lookup_kind);
tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *); tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *);
vn_reference_t vn_reference_insert (tree, tree, tree); vn_reference_t vn_reference_insert (tree, tree, tree, tree);
vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree, vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *, VEC (vn_reference_op_s, heap) *,
tree, unsigned int); tree, unsigned int);

View File

@ -1119,6 +1119,14 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
case GIMPLE_ASSIGN: case GIMPLE_ASSIGN:
lhs1 = gimple_get_lhs (s1); lhs1 = gimple_get_lhs (s1);
lhs2 = gimple_get_lhs (s2); lhs2 = gimple_get_lhs (s2);
if (gimple_vdef (s1))
{
if (vn_valueize (gimple_vdef (s1)) != vn_valueize (gimple_vdef (s2)))
return false;
if (TREE_CODE (lhs1) != SSA_NAME
&& TREE_CODE (lhs2) != SSA_NAME)
return true;
}
return (TREE_CODE (lhs1) == SSA_NAME return (TREE_CODE (lhs1) == SSA_NAME
&& TREE_CODE (lhs2) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME
&& vn_valueize (lhs1) == vn_valueize (lhs2)); && vn_valueize (lhs1) == vn_valueize (lhs2));