From ed10d09bcc8e7af47896f9ca1f5dbc5fd710929d Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 14 Nov 2017 10:06:12 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 ++++ gcc/ipa-split.c | 43 ++++++++++++++--------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c | 1 + gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c | 33 +++++++++++++++++ 5 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13a60e8ed7d..6d719d31688 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-11-13 Jan Hubicka + + * 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 * config/rs6000/altivec.md (altivec_vsumsws_be): Add define_expand. diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 252ea053e2a..9f893915c17 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -129,6 +129,10 @@ struct split_point /* Basic block where we split (that will become entry point of new function. */ 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. */ bitmap split_bbs; @@ -426,7 +430,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, edge_iterator ei; gphi_iterator bsi; unsigned int i; - int incoming_freq = 0; tree retval; tree retbnd; 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)) dump_split_point (dump_file, current); + current->count = profile_count::zero (); FOR_EACH_EDGE (e, ei, current->entry_bb->preds) { if (e->flags & EDGE_DFS_BACK) back_edge = true; 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. */ - if (incoming_freq - >= (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun) - * PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100)) + /* Do not split when we would end up calling function anyway. + Compares are three state, use !(...<...) to also give up when outcome + is unknown. */ + 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 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. */ if (back_edge && profile_status_for_fn (cfun) != PROFILE_READ - && incoming_freq - < ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun)) + && current->count + < ENTRY_BLOCK_PTR_FOR_FN (cfun)->count) { if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - " Split before loop, accepting despite low frequencies %i %i.\n", - incoming_freq, - ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.to_frequency (cfun)); + { + fprintf (dump_file, + " Split before loop, accepting despite low counts"); + current->count.dump (dump_file); + fprintf (dump_file, " "); + ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.dump (dump_file); + } } else { @@ -711,14 +720,13 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, if (dump_file && (dump_flags & TDF_DETAILS)) 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. In future we might re-consider this heuristics. */ if (!best_split_point.split_bbs - || best_split_point.entry_bb->count.to_frequency (cfun) - > current->entry_bb->count.to_frequency (cfun) - || (best_split_point.entry_bb->count.to_frequency (cfun) - == current->entry_bb->count.to_frequency (cfun) + || best_split_point.count + > current->count + || (best_split_point.count == current->count && best_split_point.split_size < current->split_size)) { @@ -1446,6 +1454,7 @@ split_function (basic_block return_bb, struct split_point *split_point, } else break; + call_bb->count = split_point->count; e = split_block (split_point->entry_bb, last_stmt); remove_edge (e); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3c4c37d517b..11a4a121f13 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-11-13 Jan Hubicka + + * gcc.dg/tree-ssa/fnsplit-2.c: New testcase. + 2017-11-13 Fritz Reese PR fortran/78240 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c index ad5fc101cd8..1b9696dcb11 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c @@ -19,4 +19,5 @@ main(void) return 0; } /* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */ +/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "fnsplit"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c new file mode 100644 index 00000000000..c00213cc182 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-2.c @@ -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"} } */