re PR tree-optimization/43415 (Consumes large amounts of memory and time in PRE at -O3)

2010-03-19  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43415
	* tree-ssa-pre.c (phi_translate): Split out worker to ...
	(phi_translate_1): ... this.
	(phi_translate): Move all caching here.  Cache all NARY
	and REFERENCE translations.

	* gcc.c-torture/compile/pr43415.c: New testcase.

From-SVN: r157562
This commit is contained in:
Richard Guenther 2010-03-19 10:18:25 +00:00 committed by Richard Biener
parent a29d9e20cc
commit 3e999e7b28
4 changed files with 92 additions and 25 deletions

View File

@ -1,3 +1,11 @@
2010-03-19 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43415
* tree-ssa-pre.c (phi_translate): Split out worker to ...
(phi_translate_1): ... this.
(phi_translate): Move all caching here. Cache all NARY
and REFERENCE translations.
2010-03-19 David S. Miller <davem@davemloft.net>
With help from Eric Botcazou.

View File

@ -1,3 +1,8 @@
2010-03-19 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43415
* gcc.c-torture/compile/pr43415.c: New testcase.
2010-03-19 Eric Botcazou <ebotcazou@adacore.com>
PR ada/43106

View File

@ -0,0 +1,36 @@
int main()
{
unsigned long long table[256];
unsigned int i;
for (i=0; i<256; ++i) {
unsigned long long j;
unsigned char x=i;
for (j=0; j<5; ++j) {
x += x<<1;
x ^= x>>1;
}
for (j=0; j<5; ++j) {
x += x<<1;
x ^= x>>1;
}
for (j=0; j<5; ++j) {
x += x<<1;
x ^= x>>1;
}
for (j=0; j<5; ++j) {
x += x<<1;
x ^= x>>1;
}
for (j=0; j<5; ++j) {
x += x<<1;
x ^= x>>1;
}
table[i] ^= (((unsigned long long)x)<<16);
}
for (i=0; i<256; ++i) {
if ((table[i]&0xff)==i)
return 1;
}
return 0;
}

View File

@ -1471,32 +1471,18 @@ get_representative_for (const pre_expr e)
static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
basic_block pred, basic_block phiblock);
/* Translate EXPR using phis in PHIBLOCK, so that it has the values of
the phis in PRED. Return NULL if we can't find a leader for each part
of the translated expression. */
static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
basic_block pred, basic_block phiblock)
phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
basic_block pred, basic_block phiblock)
{
pre_expr oldexpr = expr;
pre_expr phitrans;
if (!expr)
return NULL;
/* Constants contain no values that need translation. */
if (expr->kind == CONSTANT)
return expr;
if (value_id_constant_p (get_expr_value_id (expr)))
return expr;
phitrans = phi_trans_lookup (expr, pred);
if (phitrans)
return phitrans;
switch (expr->kind)
{
case NARY:
@ -1584,7 +1570,6 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
}
add_to_value (new_val_id, expr);
}
phi_trans_add (oldexpr, expr, pred);
return expr;
}
break;
@ -1765,7 +1750,6 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
add_to_value (new_val_id, expr);
}
VEC_free (vn_reference_op_s, heap, newoperands);
phi_trans_add (oldexpr, expr, pred);
return expr;
}
break;
@ -1811,6 +1795,44 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
}
}
/* Wrapper around phi_translate_1 providing caching functionality. */
static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
basic_block pred, basic_block phiblock)
{
pre_expr phitrans;
if (!expr)
return NULL;
/* Constants contain no values that need translation. */
if (expr->kind == CONSTANT)
return expr;
if (value_id_constant_p (get_expr_value_id (expr)))
return expr;
if (expr->kind != NAME)
{
phitrans = phi_trans_lookup (expr, pred);
if (phitrans)
return phitrans;
}
/* Translate. */
phitrans = phi_translate_1 (expr, set1, set2, pred, phiblock);
/* Don't add empty translations to the cache. Neither add
translations of NAMEs as those are cheap to translate. */
if (phitrans
&& expr->kind != NAME)
phi_trans_add (expr, phitrans, pred);
return phitrans;
}
/* For each expression in SET, translate the values through phi nodes
in PHIBLOCK using edge PHIBLOCK->PRED, and store the resulting
expressions in DEST. */
@ -1834,13 +1856,9 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
{
pre_expr translated;
translated = phi_translate (expr, set, NULL, pred, phiblock);
/* Don't add empty translations to the cache */
if (!translated)
continue;
phi_trans_add (expr, translated, pred);
/* We might end up with multiple expressions from SET being
translated to the same value. In this case we do not want
to retain the NARY or REFERENCE expression but prefer a NAME