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

2013-02-05  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	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.
	(execute_pre): Do not record constified events.

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

From-SVN: r195755
This commit is contained in:
Richard Biener 2013-02-05 12:56:51 +00:00 committed by Richard Biener
parent f8d7d4b7ff
commit be1fc7ce63
5 changed files with 89 additions and 34 deletions

View File

@ -1,3 +1,15 @@
2013-02-05 Richard Biener <rguenther@suse.de>
Backport from mainline
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.
(execute_pre): Do not record constified events.
2013-02-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/54767

View File

@ -1,3 +1,12 @@
2013-02-05 Richard Biener <rguenther@suse.de>
Backport from mainline
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.
2013-02-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/54767

View File

@ -0,0 +1,34 @@
/* { 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);
}
}

View File

@ -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" } } */

View File

@ -448,10 +448,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;
@ -862,6 +858,8 @@ bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
return;
}
}
gcc_unreachable ();
}
/* Return true if two bitmap sets are equal. */
@ -3511,7 +3509,8 @@ do_regular_insertion (basic_block block, basic_block dom)
FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
{
if (expr->kind != NAME)
if (expr->kind == NARY
|| expr->kind == REFERENCE)
{
pre_expr *avail;
unsigned int val;
@ -3612,36 +3611,36 @@ 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_set_t exprset = VEC_index (bitmap_set_t,
value_expressions, val);
tree exprtype = get_expr_type (expr);
tree temp;
gimple assign;
pre_expr newe;
gimple_stmt_iterator gsi;
unsigned int new_val = get_expr_value_id (edoubleprime);
FOR_EACH_EXPR_ID_IN_SET (exprset, j, bi)
gcc_assert (edoubleprime->kind == CONSTANT
|| edoubleprime->kind == NAME);
if (!pretemp || TREE_TYPE (pretemp) != exprtype)
{
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;
}
pretemp = create_tmp_reg (exprtype, "pretmp");
add_referenced_var (pretemp);
}
temp = make_ssa_name (pretemp, NULL);
assign = gimple_build_assign (temp,
edoubleprime->kind == CONSTANT ? PRE_EXPR_CONSTANT (edoubleprime) : PRE_EXPR_NAME (edoubleprime));
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 = temp;
bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp));
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);
}
free (avail);
}
@ -3669,7 +3668,8 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
{
if (expr->kind != NAME)
if (expr->kind == NARY
|| expr->kind == REFERENCE)
{
pre_expr *avail;
unsigned int val;
@ -4926,7 +4926,6 @@ execute_pre (bool do_fre)
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 ();
if (!do_fre)