mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
e81941b70e
commit
4ec0a19888
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue