Commit 4bcc5786 by Richard Biener Committed by Richard Biener

re PR tree-optimization/55107 (GCC in an infinite loop in PRE)

2012-12-10  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/55107
	* tree-ssa-pre.c (struct pre_stats): Remove constified field.
	(bitmap_set_replace_value): Add gcc_unreachable.
	(do_regular_insertion): Re-write all_same handling.  Insert
	an assignment instead of a PHI in this case.
	(eliminate_bb): Record availability also for SSA names defined
	by a constant.
	(do_pre): Do not record constified events.
	(execute_fre): Likewise.

	* gcc.dg/torture/pr55107.c: New testcase.
	* gcc.dg/tree-ssa/ssa-pre-5.c: Adjust.

From-SVN: r194358
parent 46e8409e
2012-12-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/55107
* tree-ssa-pre.c (struct pre_stats): Remove constified field.
(bitmap_set_replace_value): Add gcc_unreachable.
(do_regular_insertion): Re-write all_same handling. Insert
an assignment instead of a PHI in this case.
(eliminate_bb): Record availability also for SSA names defined
by a constant.
(do_pre): Do not record constified events.
(execute_fre): Likewise.
2012-12-10 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/spu/spu.md: Replace "operands" with "operands != NULL" in
2012-12-10 Richard Biener <rguenther@suse.de>
PR tree-optimization/55107
* gcc.dg/torture/pr55107.c: New testcase.
* gcc.dg/tree-ssa/ssa-pre-5.c: Adjust.
2012-12-10 Jakub Jelinek <jakub@redhat.com>
* g++.dg/asan/asan_test.cc: Sync from upstream.
......
/* { dg-do compile } */
typedef unsigned short uint16_t;
uint16_t a, b;
uint16_t f(void)
{
int c, **p;
short d = 2, e = 4;
for (;; b++)
{
int *j, k = 0;
for (; *j; j++)
{
for(; c; c++)
for(; k < 1; k++)
{
short *f = &d;
if(b)
return *f;
}
}
if(!c)
d *= e;
((a = d) ? b = 0 : (**p ? : 1) != (d != 1 ? : (a = 0))) != (k ? a : 0)
< (a *= c = k) && (**p = 0);
}
}
......@@ -12,5 +12,6 @@ foo (int i)
}
/* We should detect that a+b is the same along both edges, and replace it with
5 */
/* { dg-final { scan-tree-dump-times "Constified: 1" 1 "pre"} } */
/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */
/* { dg-final { scan-tree-dump-times "Insertions" 0 "pre"} } */
/* { dg-final { cleanup-tree-dump "pre" } } */
......@@ -446,10 +446,6 @@ static struct
/* The number of new PHI nodes added by PRE. */
int phis;
/* The number of values found constant. */
int constified;
} pre_stats;
static bool do_partial_partial;
......@@ -867,6 +863,8 @@ bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
return;
}
}
gcc_unreachable ();
}
/* Return true if two bitmap sets are equal. */
......@@ -3325,7 +3323,8 @@ do_regular_insertion (basic_block block, basic_block dom)
FOR_EACH_VEC_ELT (exprs, i, expr)
{
if (expr->kind != NAME)
if (expr->kind == NARY
|| expr->kind == REFERENCE)
{
unsigned int val;
bool by_some = false;
......@@ -3435,35 +3434,28 @@ do_regular_insertion (basic_block block, basic_block dom)
/* If all edges produce the same value and that value is
an invariant, then the PHI has the same value on all
edges. Note this. */
else if (!cant_insert && all_same && eprime
&& (edoubleprime->kind == CONSTANT
|| edoubleprime->kind == NAME)
&& !value_id_constant_p (val))
else if (!cant_insert && all_same)
{
unsigned int j;
bitmap_iterator bi;
bitmap exprset = value_expressions[val];
unsigned int new_val = get_expr_value_id (edoubleprime);
EXECUTE_IF_SET_IN_BITMAP (exprset, 0, j, bi)
{
pre_expr expr = expression_for_id (j);
if (expr->kind == NAME)
{
vn_ssa_aux_t info = VN_INFO (PRE_EXPR_NAME (expr));
/* Just reset the value id and valnum so it is
the same as the constant we have discovered. */
if (edoubleprime->kind == CONSTANT)
{
info->valnum = PRE_EXPR_CONSTANT (edoubleprime);
pre_stats.constified++;
}
else
info->valnum = VN_INFO (PRE_EXPR_NAME (edoubleprime))->valnum;
info->value_id = new_val;
}
}
gcc_assert (edoubleprime->kind == CONSTANT
|| edoubleprime->kind == NAME);
tree temp = make_temp_ssa_name (get_expr_type (expr),
NULL, "pretmp");
gimple assign = gimple_build_assign (temp,
edoubleprime->kind == CONSTANT ? PRE_EXPR_CONSTANT (edoubleprime) : PRE_EXPR_NAME (edoubleprime));
gimple_stmt_iterator gsi = gsi_after_labels (block);
gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
gimple_set_plf (assign, NECESSARY, false);
VN_INFO_GET (temp)->value_id = val;
VN_INFO (temp)->valnum = sccvn_valnum_from_value_id (val);
if (VN_INFO (temp)->valnum == NULL_TREE)
VN_INFO (temp)->valnum = temp;
bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp));
pre_expr newe = get_or_alloc_expr_for_name (temp);
add_to_value (val, newe);
bitmap_value_replace_in_set (AVAIL_OUT (block), newe);
bitmap_insert_into_set (NEW_SETS (block), newe);
}
}
}
......@@ -3495,7 +3487,8 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
FOR_EACH_VEC_ELT (exprs, i, expr)
{
if (expr->kind != NAME)
if (expr->kind == NARY
|| expr->kind == REFERENCE)
{
unsigned int val;
bool by_all = true;
......@@ -4142,26 +4135,32 @@ eliminate_bb (dom_walk_data *, basic_block b)
/* Lookup the RHS of the expression, see if we have an
available computation for it. If so, replace the RHS with
the available computation.
See PR43491.
We don't replace global register variable when it is a the RHS of
a single assign. We do replace local register variable since gcc
does not guarantee local variable will be allocated in register. */
the available computation. */
if (gimple_has_lhs (stmt)
&& TREE_CODE (lhs) == SSA_NAME
&& !gimple_assign_ssa_name_copy_p (stmt)
&& (!gimple_assign_single_p (stmt)
|| (!is_gimple_min_invariant (rhs)
&& (gimple_assign_rhs_code (stmt) != VAR_DECL
|| !is_global_var (rhs)
|| !DECL_HARD_REGISTER (rhs))))
&& !gimple_has_volatile_ops (stmt))
{
tree sprime;
gimple orig_stmt = stmt;
sprime = eliminate_avail (lhs);
/* If there is no usable leader mark lhs as leader for its value. */
if (!sprime)
eliminate_push_avail (lhs);
/* See PR43491. Do not replace a global register variable when
it is a the RHS of an assignment. Do replace local register
variables since gcc does not guarantee a local variable will
be allocated in register.
Do not perform copy propagation or undo constant propagation. */
if (gimple_assign_single_p (stmt)
&& (TREE_CODE (rhs) == SSA_NAME
|| is_gimple_min_invariant (rhs)
|| (TREE_CODE (rhs) == VAR_DECL
&& is_global_var (rhs)
&& DECL_HARD_REGISTER (rhs))))
continue;
if (!sprime)
{
/* If there is no existing usable leader but SCCVN thinks
......@@ -4208,10 +4207,6 @@ eliminate_bb (dom_walk_data *, basic_block b)
continue;
}
/* If there is no usable leader mark lhs as leader for its value. */
if (!sprime)
eliminate_push_avail (lhs);
if (sprime
&& sprime != lhs
&& (rhs == NULL_TREE
......@@ -4742,7 +4737,6 @@ do_pre (void)
statistics_counter_event (cfun, "PA inserted", pre_stats.pa_insert);
statistics_counter_event (cfun, "New PHIs", pre_stats.phis);
statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
statistics_counter_event (cfun, "Constified", pre_stats.constified);
clear_expression_ids ();
remove_dead_inserted_code ();
......@@ -4823,7 +4817,6 @@ execute_fre (void)
statistics_counter_event (cfun, "Insertions", pre_stats.insertions);
statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
statistics_counter_event (cfun, "Constified", pre_stats.constified);
return todo;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment