diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 7 | ||||
-rw-r--r-- | libgcc/libgcov-merge.c | 50 |
2 files changed, 42 insertions, 15 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7b46ccb..dedc308 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,10 @@ +2020-02-18 Martin Liska <mliska@suse.cz> + + PR ipa/92924 + * libgcov-merge.c (merge_topn_values_set): Record + when a TOP N counter becomes invalid. When merging + remove a smallest value if the space is needed. + 2020-02-12 Sandra Loosemore <sandra@codesourcery.com> PR libstdc++/79193 diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c index 19b8ee7..c0785b0 100644 --- a/libgcc/libgcov-merge.c +++ b/libgcc/libgcov-merge.c @@ -86,36 +86,47 @@ __gcov_merge_time_profile (gcov_type *counters, unsigned n_counters) #ifdef L_gcov_merge_topn +/* To merging of TOPN profiles. + counters[0] is the number of executions + for i in 0 ... TOPN-1 + counters[2 * i + 1] is target + counters[2 * i + 2] is corresponding hitrate counter. + + Because we prune counters only those with probability >= 1/TOPN are + present now. + + We use sign of counters[0] to track whether the number of different + targets exceeds TOPN. */ + static void merge_topn_values_set (gcov_type *counters) { /* First value is number of total executions of the profiler. */ - gcov_type all = gcov_get_counter_ignore_scaling (-1); - counters[0] += all; + gcov_type all = gcov_get_counter (); + gcov_type *total = &counters[0]; ++counters; + /* Negative value means that counter is missing some of values. */ + if (all < 0) + *total = -(*total); + + *total += all; + /* Read all part values. */ gcov_type read_counters[2 * GCOV_TOPN_VALUES]; - for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++) { read_counters[2 * i] = gcov_get_counter_target (); read_counters[2 * i + 1] = gcov_get_counter_ignore_scaling (-1); } - if (read_counters[1] == -1) - { - counters[1] = -1; - return; - } - for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++) { if (read_counters[2 * i + 1] == 0) continue; unsigned j; - int slot = -1; + int slot = 0; for (j = 0; j < GCOV_TOPN_VALUES; j++) { @@ -124,13 +135,15 @@ merge_topn_values_set (gcov_type *counters) counters[2 * j + 1] += read_counters[2 * i + 1]; break; } - else if (counters[2 * j + 1] == 0) + else if (counters[2 * j + 1] < counters[2 * slot + 1]) slot = j; } if (j == GCOV_TOPN_VALUES) { - if (slot > 0) + gcov_type slot_count = counters[2 * slot + 1]; + /* We found an empty slot. */ + if (slot_count == 0) { /* If we found empty slot, add the value. */ counters[2 * slot] = read_counters[2 * i]; @@ -138,9 +151,16 @@ merge_topn_values_set (gcov_type *counters) } else { - /* We haven't found a slot, bail out. */ - counters[1] = -1; - return; + /* Here we are loosing some values. */ + if (*total >= 0) + *total = -(*total); + if (read_counters[2 * i + 1] > slot_count) + { + counters[2 * slot] = read_counters[2 * i]; + counters[2 * slot + 1] = read_counters[2 * i + 1]; + } + else + counters[2 * slot + 1] -= read_counters[2 * i + 1]; } } } |