re PR tree-optimization/48290 (FAIL: gcc.dg/vect/pr38529.c, ICE in vect_get_vec_def_for_operand, at tree-vect-stmts.c:1072)
2011-04-15 Richard Guenther <rguenther@suse.de> PR tree-optimization/48290 * tree-ssa-copy.c (copy_prop_visit_phi_node): Propagate constants. Properly decide inhibiting propagation based on the valueized operand. Do loop-closed SSA form preserving here ... (init_copy_prop): ... not here. From-SVN: r172494
This commit is contained in:
parent
266446be6f
commit
8456558d4a
2 changed files with 47 additions and 42 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2011-04-15 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/48290
|
||||||
|
* tree-ssa-copy.c (copy_prop_visit_phi_node): Propagate constants.
|
||||||
|
Properly decide inhibiting propagation based on the valueized
|
||||||
|
operand. Do loop-closed SSA form preserving here ...
|
||||||
|
(init_copy_prop): ... not here.
|
||||||
|
|
||||||
2011-04-15 H.J. Lu <hongjiu.lu@intel.com>
|
2011-04-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR target/48612
|
PR target/48612
|
||||||
|
|
|
@ -567,6 +567,7 @@ copy_prop_visit_phi_node (gimple phi)
|
||||||
for (i = 0; i < gimple_phi_num_args (phi); i++)
|
for (i = 0; i < gimple_phi_num_args (phi); i++)
|
||||||
{
|
{
|
||||||
prop_value_t *arg_val;
|
prop_value_t *arg_val;
|
||||||
|
tree arg_value;
|
||||||
tree arg = gimple_phi_arg_def (phi, i);
|
tree arg = gimple_phi_arg_def (phi, i);
|
||||||
edge e = gimple_phi_arg_edge (phi, i);
|
edge e = gimple_phi_arg_edge (phi, i);
|
||||||
|
|
||||||
|
@ -575,24 +576,9 @@ copy_prop_visit_phi_node (gimple phi)
|
||||||
if (!(e->flags & EDGE_EXECUTABLE))
|
if (!(e->flags & EDGE_EXECUTABLE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Constants in the argument list never generate a useful copy.
|
/* Names that flow through abnormal edges cannot be used to
|
||||||
Similarly, names that flow through abnormal edges cannot be
|
derive copies. */
|
||||||
used to derive copies. */
|
if (TREE_CODE (arg) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
|
||||||
if (TREE_CODE (arg) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
|
|
||||||
{
|
|
||||||
phi_val.value = lhs;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Avoid copy propagation from an inner into an outer loop.
|
|
||||||
Otherwise, this may move loop variant variables outside of
|
|
||||||
their loops and prevent coalescing opportunities. If the
|
|
||||||
value was loop invariant, it will be hoisted by LICM and
|
|
||||||
exposed for copy propagation. Not a problem for virtual
|
|
||||||
operands though.
|
|
||||||
??? The value will be always loop invariant. */
|
|
||||||
if (is_gimple_reg (lhs)
|
|
||||||
&& loop_depth_of_name (arg) > loop_depth_of_name (lhs))
|
|
||||||
{
|
{
|
||||||
phi_val.value = lhs;
|
phi_val.value = lhs;
|
||||||
break;
|
break;
|
||||||
|
@ -605,26 +591,51 @@ copy_prop_visit_phi_node (gimple phi)
|
||||||
fprintf (dump_file, "\n");
|
fprintf (dump_file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_val = get_copy_of_val (arg);
|
if (TREE_CODE (arg) == SSA_NAME)
|
||||||
|
{
|
||||||
|
arg_val = get_copy_of_val (arg);
|
||||||
|
|
||||||
/* If we didn't visit the definition of arg yet treat it as
|
/* If we didn't visit the definition of arg yet treat it as
|
||||||
UNDEFINED. This also handles PHI arguments that are the
|
UNDEFINED. This also handles PHI arguments that are the
|
||||||
same as lhs. We'll come here again. */
|
same as lhs. We'll come here again. */
|
||||||
if (!arg_val->value)
|
if (!arg_val->value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
arg_value = arg_val->value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
arg_value = valueize_val (arg);
|
||||||
|
|
||||||
|
/* Avoid copy propagation from an inner into an outer loop.
|
||||||
|
Otherwise, this may move loop variant variables outside of
|
||||||
|
their loops and prevent coalescing opportunities. If the
|
||||||
|
value was loop invariant, it will be hoisted by LICM and
|
||||||
|
exposed for copy propagation.
|
||||||
|
??? The value will be always loop invariant.
|
||||||
|
In loop-closed SSA form do not copy-propagate through
|
||||||
|
PHI nodes in blocks with a loop exit edge predecessor. */
|
||||||
|
if (current_loops
|
||||||
|
&& TREE_CODE (arg_value) == SSA_NAME
|
||||||
|
&& (loop_depth_of_name (arg_value) > loop_depth_of_name (lhs)
|
||||||
|
|| (loops_state_satisfies_p (LOOP_CLOSED_SSA)
|
||||||
|
&& loop_exit_edge_p (e->src->loop_father, e))))
|
||||||
|
{
|
||||||
|
phi_val.value = lhs;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* If the LHS didn't have a value yet, make it a copy of the
|
/* If the LHS didn't have a value yet, make it a copy of the
|
||||||
first argument we find. */
|
first argument we find. */
|
||||||
if (phi_val.value == NULL_TREE)
|
if (phi_val.value == NULL_TREE)
|
||||||
{
|
{
|
||||||
phi_val.value = arg_val->value;
|
phi_val.value = arg_value;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If PHI_VAL and ARG don't have a common copy-of chain, then
|
/* If PHI_VAL and ARG don't have a common copy-of chain, then
|
||||||
this PHI node cannot be a copy operation. */
|
this PHI node cannot be a copy operation. */
|
||||||
if (phi_val.value != arg_val->value
|
if (phi_val.value != arg_value
|
||||||
&& !operand_equal_p (phi_val.value, arg_val->value, 0))
|
&& !operand_equal_p (phi_val.value, arg_value, 0))
|
||||||
{
|
{
|
||||||
phi_val.value = lhs;
|
phi_val.value = lhs;
|
||||||
break;
|
break;
|
||||||
|
@ -669,7 +680,6 @@ init_copy_prop (void)
|
||||||
{
|
{
|
||||||
gimple_stmt_iterator si;
|
gimple_stmt_iterator si;
|
||||||
int depth = bb->loop_depth;
|
int depth = bb->loop_depth;
|
||||||
bool loop_exit_p = false;
|
|
||||||
|
|
||||||
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
|
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
|
||||||
{
|
{
|
||||||
|
@ -706,26 +716,13 @@ init_copy_prop (void)
|
||||||
set_copy_of_val (def, def);
|
set_copy_of_val (def, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In loop-closed SSA form do not copy-propagate through
|
|
||||||
PHI nodes in blocks with a loop exit edge predecessor. */
|
|
||||||
if (current_loops
|
|
||||||
&& loops_state_satisfies_p (LOOP_CLOSED_SSA))
|
|
||||||
{
|
|
||||||
edge_iterator ei;
|
|
||||||
edge e;
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
|
||||||
if (loop_exit_edge_p (e->src->loop_father, e))
|
|
||||||
loop_exit_p = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
|
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
|
||||||
{
|
{
|
||||||
gimple phi = gsi_stmt (si);
|
gimple phi = gsi_stmt (si);
|
||||||
tree def;
|
tree def;
|
||||||
|
|
||||||
def = gimple_phi_result (phi);
|
def = gimple_phi_result (phi);
|
||||||
if (!is_gimple_reg (def)
|
if (!is_gimple_reg (def))
|
||||||
|| loop_exit_p)
|
|
||||||
prop_set_simulate_again (phi, false);
|
prop_set_simulate_again (phi, false);
|
||||||
else
|
else
|
||||||
prop_set_simulate_again (phi, true);
|
prop_set_simulate_again (phi, true);
|
||||||
|
|
Loading…
Add table
Reference in a new issue