re PR tree-optimization/50744 (ice in good_cloning_opportunity_p)

2011-12-07  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/50744
	* ipa-cp.c (good_cloning_opportunity_p): Assert size_cost is positive,
	compute evaluation in HOST_WIDEST_INT.
	(safe_add): New function
	(propagate_effects): Use safe_add to accumulate effects.

	* testsuite/gcc.dg/ipa/pr50744.c: New test.

From-SVN: r182076
This commit is contained in:
Martin Jambor 2011-12-07 11:30:49 +01:00 committed by Martin Jambor
parent c19bd76920
commit df0227c425
4 changed files with 163 additions and 12 deletions

View File

@ -1,3 +1,11 @@
2011-12-07 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/50744
* ipa-cp.c (good_cloning_opportunity_p): Assert size_cost is positive,
compute evaluation in HOST_WIDEST_INT.
(safe_add): New function
(propagate_effects): Use safe_add to accumulate effects.
2011-12-06 Joel Sherrill <joel.sherrill@oarcorp.com>
* config/rs6000/rtems.h: Switch to using global_options_set

View File

@ -1210,19 +1210,19 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
|| !optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
return false;
gcc_checking_assert (size_cost >= 0);
gcc_assert (size_cost > 0);
/* FIXME: These decisions need tuning. */
if (max_count)
{
int evaluation, factor = (count_sum * 1000) / max_count;
evaluation = (time_benefit * factor) / size_cost;
int factor = (count_sum * 1000) / max_count;
HOST_WIDEST_INT evaluation = (((HOST_WIDEST_INT) time_benefit * factor)
/ size_cost);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
"size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
") -> evaluation: %i, threshold: %i\n",
") -> evaluation: " HOST_WIDEST_INT_PRINT_DEC
", threshold: %i\n",
time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
evaluation, 500);
@ -1230,11 +1230,13 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
}
else
{
int evaluation = (time_benefit * freq_sum) / size_cost;
HOST_WIDEST_INT evaluation = (((HOST_WIDEST_INT) time_benefit * freq_sum)
/ size_cost);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
"size: %i, freq_sum: %i) -> evaluation: %i, threshold: %i\n",
"size: %i, freq_sum: %i) -> evaluation: "
HOST_WIDEST_INT_PRINT_DEC ", threshold: %i\n",
time_benefit, size_cost, freq_sum, evaluation,
CGRAPH_FREQ_BASE /2);
@ -1561,6 +1563,20 @@ propagate_constants_topo (struct topo_info *topo)
}
}
/* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
the bigger one if otherwise. */
static int
safe_add (int a, int b)
{
if (a > INT_MAX/2 || b > INT_MAX/2)
return a > b ? a : b;
else
return a + b;
}
/* Propagate the estimated effects of individual values along the topological
from the dependant values to those they depend on. */
@ -1577,8 +1593,9 @@ propagate_effects (void)
for (val = base; val; val = val->scc_next)
{
time += val->local_time_benefit + val->prop_time_benefit;
size += val->local_size_cost + val->prop_size_cost;
time = safe_add (time,
val->local_time_benefit + val->prop_time_benefit);
size = safe_add (size, val->local_size_cost + val->prop_size_cost);
}
for (val = base; val; val = val->scc_next)
@ -1586,8 +1603,10 @@ propagate_effects (void)
if (src->val
&& cgraph_maybe_hot_edge_p (src->cs))
{
src->val->prop_time_benefit += time;
src->val->prop_size_cost += size;
src->val->prop_time_benefit = safe_add (time,
src->val->prop_time_benefit);
src->val->prop_size_cost = safe_add (size,
src->val->prop_size_cost);
}
}
}

View File

@ -1,3 +1,8 @@
2011-12-07 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/50744
* gcc.dg/ipa/pr50744.c: New test.
2011-12-06 Jakub Jelinek <jakub@redhat.com>
PR c++/51430

View File

@ -0,0 +1,119 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fno-optimize-sibling-calls" } */
extern int use_data (void *p_01, void *p_02, void *p_03, void *p_04, void *p_05,
void *p_06, void *p_07, void *p_08, void *p_09, void *p_10,
void *p_11, void *p_12, void *p_13, void *p_14, void *p_15,
void *p_16, void *p_17, void *p_18, void *p_19, void *p_20,
void *p_21, void *p_22, void *p_23, void *p_24, void *p_25,
void *p_26, void *p_27, void *p_28, void *p_29,
void *p_30);
extern int idx (int i, int j, int n);
struct stuff
{
int decision;
int *a, *b, *c;
int res;
};
#define some_large_stuff(stuff, n) { \
int i, j, k; \
for (i = 0; i < n; i++) \
for (j = 0; j < n; j++) \
{ \
int v = stuff->c[idx(i, j, n)]; \
for (k = 0; k < n; k++) \
v += stuff->a[idx(i, k, n)] * stuff->b[idx(k,j,n)]; \
stuff->c[idx(i, j, n)] = v; \
} \
}
#define recursion if (iter > 0) \
foo (stuff, iter - 1, (void *) -1, p_01, p_02, p_03, p_04, p_05, p_06, \
p_07, p_08, p_09, p_10, p_11, p_12, p_13, p_14, p_15, p_16, p_17, \
p_18, p_19, p_20, p_21, p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29); \
else \
foo (stuff, iter, p_01, p_02, p_03, p_04, p_05, p_06, p_07, p_08, p_09, \
p_10, p_11, p_12, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20, \
p_21,p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30)
void
foo (struct stuff *stuff,
int iter,
void *p_01, void *p_02, void *p_03, void *p_04, void *p_05,
void *p_06, void *p_07, void *p_08, void *p_09, void *p_10,
void *p_11, void *p_12, void *p_13, void *p_14, void *p_15,
void *p_16, void *p_17, void *p_18, void *p_19, void *p_20,
void *p_21, void *p_22, void *p_23, void *p_24, void *p_25,
void *p_26, void *p_27, void *p_28, void *p_29, void *p_30)
{
switch (stuff->decision)
{
case 0:
some_large_stuff (stuff, 83);
stuff->res =
use_data (p_01, p_02, p_03, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
p_11, p_12, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
p_21, p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
recursion;
break;
case 1:
some_large_stuff (stuff, 25);
stuff->res =
use_data (p_11, p_02, p_03, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
p_21, p_12, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
p_01, p_22, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
recursion;
break;
case 3:
some_large_stuff (stuff, 139);
stuff->res =
use_data (p_01, p_12, p_03, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
p_11, p_22, p_13, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
p_21, p_02, p_23, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
recursion;
break;
case 4:
some_large_stuff (stuff, 32);
stuff->res =
use_data (p_01, p_02, p_13, p_04, p_05, p_06, p_07, p_08, p_09, p_10,
p_11, p_12, p_23, p_14, p_15, p_16, p_17, p_18, p_19, p_20,
p_21, p_22, p_03, p_24, p_25, p_26, p_27, p_28, p_29, p_30);
recursion;
break;
case 5:
some_large_stuff (stuff, 205);
stuff->res =
use_data (p_01, p_02, p_03, p_04, p_15, p_06, p_07, p_08, p_09, p_10,
p_11, p_12, p_13, p_14, p_25, p_16, p_17, p_18, p_19, p_20,
p_21, p_22, p_23, p_24, p_05, p_26, p_27, p_28, p_29, p_30);
recursion;
break;
case 6:
some_large_stuff (stuff, 64);
stuff->res =
use_data (p_01, p_02, p_03, p_04, p_05, p_16, p_07, p_08, p_09, p_10,
p_11, p_12, p_13, p_14, p_15, p_26, p_17, p_18, p_19, p_20,
p_21, p_22, p_23, p_24, p_25, p_06, p_27, p_28, p_29, p_30);
recursion;
break;
}
}
#define NULL (void *)0
void
bar (struct stuff *stuff, int iter)
{
foo (stuff, iter, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
}