aboutsummaryrefslogtreecommitdiff
path: root/libgcc/libgcov-merge.c
diff options
context:
space:
mode:
authorRong Xu <xur@gcc.gnu.org>2014-10-07 04:02:31 +0000
committerRong Xu <xur@gcc.gnu.org>2014-10-07 04:02:31 +0000
commitafe0c5ee91ab504daf13f1c07ee5559b2ba5b6e4 (patch)
treed43837c0db3f96bc2d979153fab89e2f3767ac1f /libgcc/libgcov-merge.c
parentc5b0abd3ef7a0d1311b63783435ddf15bbe507fa (diff)
downloadgcc-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-merge.c')
-rw-r--r--libgcc/libgcov-merge.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c
index f6eacd1..5ed4793 100644
--- a/libgcc/libgcov-merge.c
+++ b/libgcc/libgcov-merge.c
@@ -166,4 +166,67 @@ __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
}
}
#endif /* L_gcov_merge_delta */
+
+#ifdef L_gcov_merge_icall_topn
+/* The profile merging function used for merging indirect call counts
+ This function is given array COUNTERS of N_COUNTERS old counters and it
+ reads the same number of counters from the gcov file. */
+
+void
+__gcov_merge_icall_topn (gcov_type *counters, unsigned n_counters)
+{
+ unsigned i, j, k, m;
+
+ gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS));
+ for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS)
+ {
+ gcov_type *value_array = &counters[i + 1];
+ unsigned tmp_size = 2 * (GCOV_ICALL_TOPN_NCOUNTS - 1);
+ gcov_type *tmp_array
+ = (gcov_type *) alloca (tmp_size * sizeof (gcov_type));
+
+ for (j = 0; j < tmp_size; j++)
+ tmp_array[j] = 0;
+
+ for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2)
+ {
+ tmp_array[j] = value_array[j];
+ tmp_array[j + 1] = value_array [j + 1];
+ }
+
+ /* Skip the number_of_eviction entry. */
+ gcov_get_counter ();
+ for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
+ {
+ int found = 0;
+ gcov_type global_id = gcov_get_counter_target ();
+ gcov_type call_count = gcov_get_counter ();
+ for (m = 0; m < j; m += 2)
+ {
+ if (tmp_array[m] == global_id)
+ {
+ found = 1;
+ tmp_array[m + 1] += call_count;
+ break;
+ }
+ }
+ if (!found)
+ {
+ tmp_array[j] = global_id;
+ tmp_array[j + 1] = call_count;
+ j += 2;
+ }
+ }
+ /* Now sort the temp array */
+ gcov_sort_n_vals (tmp_array, j);
+
+ /* Now copy back the top half of the temp array */
+ for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
+ {
+ value_array[k] = tmp_array[k];
+ value_array[k + 1] = tmp_array[k + 1];
+ }
+ }
+}
+#endif /* L_gcov_merge_icall_topn */
#endif /* inhibit_libc */