ipa-split.c (struct split_point): Add count.

* ipa-split.c (struct split_point): Add count.
	(consider_split): Do not compute incoming frequency; compute incoming
	count and store it to split_point.
	(split_function): Set count of the call to split part correctly.

	* testsuite/gcc.dg/tree-ssa/fnsplit-2.c: New testcase.

From-SVN: r254720
This commit is contained in:
Jan Hubicka 2017-11-14 10:06:12 +01:00 committed by Jan Hubicka
parent 9b24c104ae
commit ed10d09bcc
5 changed files with 71 additions and 17 deletions

View File

@ -1,3 +1,10 @@
2017-11-13 Jan Hubicka <hubicka@ucw.cz>
* ipa-split.c (struct split_point): Add count.
(consider_split): Do not compute incoming frequency; compute incoming
count and store it to split_point.
(split_function): Set count of the call to split part correctly.
2017-11-13 Carl Love <cel@us.ibm.com> 2017-11-13 Carl Love <cel@us.ibm.com>
* config/rs6000/altivec.md (altivec_vsumsws_be): Add define_expand. * config/rs6000/altivec.md (altivec_vsumsws_be): Add define_expand.

View File

@ -129,6 +129,10 @@ struct split_point
/* Basic block where we split (that will become entry point of new function. */ /* Basic block where we split (that will become entry point of new function. */
basic_block entry_bb; basic_block entry_bb;
/* Count for entering the split part.
This is not count of the entry_bb because it may be in loop. */
profile_count count;
/* Basic blocks we are splitting away. */ /* Basic blocks we are splitting away. */
bitmap split_bbs; bitmap split_bbs;
@ -426,7 +430,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
edge_iterator ei; edge_iterator ei;
gphi_iterator bsi; gphi_iterator bsi;
unsigned int i; unsigned int i;
int incoming_freq = 0;
tree retval; tree retval;
tree retbnd; tree retbnd;
bool back_edge = false; bool back_edge = false;
@ -434,18 +437,21 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
dump_split_point (dump_file, current); dump_split_point (dump_file, current);
current->count = profile_count::zero ();
FOR_EACH_EDGE (e, ei, current->entry_bb->preds) FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
{ {
if (e->flags & EDGE_DFS_BACK) if (e->flags & EDGE_DFS_BACK)
back_edge = true; back_edge = true;
if (!bitmap_bit_p (current->split_bbs, e->src->index)) if (!bitmap_bit_p (current->split_bbs, e->src->index))
incoming_freq += EDGE_FREQUENCY (e); current->count += e->count ();
} }
/* Do not split when we would end up calling function anyway. */ /* Do not split when we would end up calling function anyway.
if (incoming_freq Compares are three state, use !(...<...) to also give up when outcome
>= (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun) is unknown. */
* PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100)) if (!(current->count
< (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale
(PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY), 100))))
{ {
/* When profile is guessed, we can not expect it to give us /* When profile is guessed, we can not expect it to give us
realistic estimate on likelyness of function taking the realistic estimate on likelyness of function taking the
@ -454,14 +460,17 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
is likely noticeable win. */ is likely noticeable win. */
if (back_edge if (back_edge
&& profile_status_for_fn (cfun) != PROFILE_READ && profile_status_for_fn (cfun) != PROFILE_READ
&& incoming_freq && current->count
< ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun)) < ENTRY_BLOCK_PTR_FOR_FN (cfun)->count)
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, {
" Split before loop, accepting despite low frequencies %i %i.\n", fprintf (dump_file,
incoming_freq, " Split before loop, accepting despite low counts");
ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun)); current->count.dump (dump_file);
fprintf (dump_file, " ");
ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.dump (dump_file);
}
} }
else else
{ {
@ -711,14 +720,13 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Accepted!\n"); fprintf (dump_file, " Accepted!\n");
/* At the moment chose split point with lowest frequency and that leaves /* At the moment chose split point with lowest count and that leaves
out smallest size of header. out smallest size of header.
In future we might re-consider this heuristics. */ In future we might re-consider this heuristics. */
if (!best_split_point.split_bbs if (!best_split_point.split_bbs
|| best_split_point.entry_bb->count.to_frequency (cfun) || best_split_point.count
> current->entry_bb->count.to_frequency (cfun) > current->count
|| (best_split_point.entry_bb->count.to_frequency (cfun) || (best_split_point.count == current->count
== current->entry_bb->count.to_frequency (cfun)
&& best_split_point.split_size < current->split_size)) && best_split_point.split_size < current->split_size))
{ {
@ -1446,6 +1454,7 @@ split_function (basic_block return_bb, struct split_point *split_point,
} }
else else
break; break;
call_bb->count = split_point->count;
e = split_block (split_point->entry_bb, last_stmt); e = split_block (split_point->entry_bb, last_stmt);
remove_edge (e); remove_edge (e);

View File

@ -1,3 +1,7 @@
2017-11-13 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/tree-ssa/fnsplit-2.c: New testcase.
2017-11-13 Fritz Reese <fritzoreese@gmail.com> 2017-11-13 Fritz Reese <fritzoreese@gmail.com>
PR fortran/78240 PR fortran/78240

View File

@ -19,4 +19,5 @@ main(void)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */ /* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */
/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "fnsplit"} } */

View File

@ -0,0 +1,33 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-fnsplit-blocks-details" } */
void q (void);
int b;
void test (void);
void
split_me (int *a)
{
if (__builtin_expect (a==0, 0))
do
{
test();
test();
test();
test();
test();
}
while (b);
else
q();
}
int
main(void)
{
int i;
for (i = 0; i < 1000; i++)
split_me(&i);
return 0;
}
/* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */
/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "fnsplit"} } */