diff options
author | Rong Xu <xur@gcc.gnu.org> | 2014-10-07 04:02:31 +0000 |
---|---|---|
committer | Rong Xu <xur@gcc.gnu.org> | 2014-10-07 04:02:31 +0000 |
commit | afe0c5ee91ab504daf13f1c07ee5559b2ba5b6e4 (patch) | |
tree | d43837c0db3f96bc2d979153fab89e2f3767ac1f /libgcc/libgcov-driver.c | |
parent | c5b0abd3ef7a0d1311b63783435ddf15bbe507fa (diff) | |
download | gcc-afe0c5ee91ab504daf13f1c07ee5559b2ba5b6e4.zip gcc-afe0c5ee91ab504daf13f1c07ee5559b2ba5b6e4.tar.gz gcc-afe0c5ee91ab504daf13f1c07ee5559b2ba5b6e4.tar.bz2 |
Makefile.in: Fix dependence.
2014-10-06 Rong Xu <xur@google.com>
* gcc/Makefile.in: Fix dependence.
* gcc/gcov-counter.def (GCOV_COUNTER_ICALL_TOPNV): Add
indirect call topn profiler.
* gcc/gcov-io.h: Ditto.
* libgcc/Makefile.in: Ditto.
* libgcc/libgcov-driver.c (gcov_sort_n_vals): New utility function.
(gcov_sort_icall_topn_counter): Ditto.
(gcov_sort_topn_counter_arrays): Ditto.
(dump_one_gcov): Sort indirect_call topn counters.
* libgcc/libgcov-merge.c (__gcov_merge_icall_topn): New merge
function.
* libgcc/libgcov-profiler.c (__gcov_topn_value_profiler_body): New
utility function.
(__gcov_indirect_call_topn_profiler): New profiler function.
* libgcc/libgcov-util.c (__gcov_icall_topn_counter_op): New.
* libgcc/libgcov.h: New decls.
From-SVN: r215962
Diffstat (limited to 'libgcc/libgcov-driver.c')
-rw-r--r-- | libgcc/libgcov-driver.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index 7bde526..754584d 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -665,6 +665,85 @@ merge_summary (const char *filename, int run_counted, return 0; } + +/* Sort N entries in VALUE_ARRAY in descending order. + Each entry in VALUE_ARRAY has two values. The sorting + is based on the second value. */ + +GCOV_LINKAGE void +gcov_sort_n_vals (gcov_type *value_array, int n) +{ + int j, k; + + for (j = 2; j < n; j += 2) + { + gcov_type cur_ent[2]; + + cur_ent[0] = value_array[j]; + cur_ent[1] = value_array[j + 1]; + k = j - 2; + while (k >= 0 && value_array[k + 1] < cur_ent[1]) + { + value_array[k + 2] = value_array[k]; + value_array[k + 3] = value_array[k+1]; + k -= 2; + } + value_array[k + 2] = cur_ent[0]; + value_array[k + 3] = cur_ent[1]; + } +} + +/* Sort the profile counters for all indirect call sites. Counters + for each call site are allocated in array COUNTERS. */ + +static void +gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters) +{ + int i; + gcov_type *values; + int n = counters->num; + + gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS)); + values = counters->values; + + for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS) + { + gcov_type *value_array = &values[i + 1]; + gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1); + } +} + +/* Sort topn indirect_call profile counters in GI_PTR. */ + +static void +gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr) +{ + unsigned int i; + int f_ix; + const struct gcov_fn_info *gfi_ptr; + const struct gcov_ctr_info *ci_ptr; + + if (!gi_ptr->merge[GCOV_COUNTER_ICALL_TOPNV]) + return; + + for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++) + { + gfi_ptr = gi_ptr->functions[f_ix]; + ci_ptr = gfi_ptr->ctrs; + for (i = 0; i < GCOV_COUNTERS; i++) + { + if (!gi_ptr->merge[i]) + continue; + if (i == GCOV_COUNTER_ICALL_TOPNV) + { + gcov_sort_icall_topn_counter (ci_ptr); + break; + } + ci_ptr++; + } + } +} + /* Dump the coverage counts for one gcov_info object. We merge with existing counts when possible, to avoid growing the .da files ad infinitum. We use this program's checksum to make sure we only accumulate whole program @@ -687,6 +766,8 @@ dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf, fn_buffer = 0; sum_buffer = 0; + gcov_sort_topn_counter_arrays (gi_ptr); + error = gcov_exit_open_gcda_file (gi_ptr, gf); if (error == -1) return; |