diff options
author | Martin Liska <mliska@suse.cz> | 2022-08-01 15:50:43 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-08-03 10:58:22 +0200 |
commit | a6b7fff06c5b27c4ffacf4c84ea1189254b9ad84 (patch) | |
tree | 23ed79a55254e16cbabed1c70cf4dce1c861f831 | |
parent | 7585e5ecb47761516b8f397002819f2c95b8c32e (diff) |
gcov-dump: add --stable option
The option prints TOP N counters in a stable format
usage for comparison (diff).
gcc/ChangeLog:
* doc/gcov-dump.texi: Document the new option.
* gcov-dump.cc (main): Parse the new option.
(print_usage): Show the option.
(tag_counters): Sort key:value pairs of TOP N counter.
-rw-r--r-- | gcc/doc/gcov-dump.texi | 5 | ||||
-rw-r--r-- | gcc/gcov-dump.cc | 61 |
2 files changed, 59 insertions, 7 deletions
diff --git a/gcc/doc/gcov-dump.texi b/gcc/doc/gcov-dump.texi index 4f4e355dd28..0491ab17bc1 100644 --- a/gcc/doc/gcov-dump.texi +++ b/gcc/doc/gcov-dump.texi @@ -62,6 +62,7 @@ gcov-dump [@option{-v}|@option{--version}] [@option{-l}|@option{--long}] [@option{-p}|@option{--positions}] [@option{-r}|@option{--raw}] + [@option{-s}|@option{--stable}] @var{gcovfiles} @c man end @end ignore @@ -85,6 +86,10 @@ Dump positions of records. @itemx --raw Print content records in raw format. +@item -s +@itemx --stable +Print content in stable format usable for comparison. + @item -v @itemx --version Display the @command{gcov-dump} version number (on the standard output), diff --git a/gcc/gcov-dump.cc b/gcc/gcov-dump.cc index 0804c794e9e..85b1be8859e 100644 --- a/gcc/gcov-dump.cc +++ b/gcc/gcov-dump.cc @@ -28,6 +28,10 @@ along with Gcov; see the file COPYING3. If not see #include "gcov-io.h" #include "gcov-io.cc" +#include <vector> + +using namespace std; + static void dump_gcov_file (const char *); static void print_prefix (const char *, unsigned, gcov_position_t); static void print_usage (void); @@ -50,6 +54,7 @@ typedef struct tag_format static int flag_dump_contents = 0; static int flag_dump_positions = 0; static int flag_dump_raw = 0; +static int flag_dump_stable = 0; static const struct option options[] = { @@ -57,7 +62,9 @@ static const struct option options[] = { "version", no_argument, NULL, 'v' }, { "long", no_argument, NULL, 'l' }, { "positions", no_argument, NULL, 'o' }, - { 0, 0, 0, 0 } + { "raw", no_argument, NULL, 'r' }, + { "stable", no_argument, NULL, 's' }, + {} }; #define VALUE_PADDING_PREFIX " " @@ -96,7 +103,7 @@ main (int argc ATTRIBUTE_UNUSED, char **argv) diagnostic_initialize (global_dc, 0); - while ((opt = getopt_long (argc, argv, "hlprvw", options, NULL)) != -1) + while ((opt = getopt_long (argc, argv, "hlprsvw", options, NULL)) != -1) { switch (opt) { @@ -115,6 +122,9 @@ main (int argc ATTRIBUTE_UNUSED, char **argv) case 'r': flag_dump_raw = 1; break; + case 's': + flag_dump_stable = 1; + break; default: fprintf (stderr, "unknown flag `%c'\n", opt); } @@ -134,6 +144,8 @@ print_usage (void) printf (" -l, --long Dump record contents too\n"); printf (" -p, --positions Dump record positions\n"); printf (" -r, --raw Print content records in raw format\n"); + printf (" -s, --stable Print content in stable " + "format usable for comparison\n"); printf (" -v, --version Print version number\n"); printf ("\nFor bug reporting instructions, please see:\n%s.\n", bug_report_url); @@ -439,16 +451,52 @@ tag_counters (const char *filename ATTRIBUTE_UNUSED, int n_counts = GCOV_TAG_COUNTER_NUM (length); bool has_zeros = n_counts < 0; n_counts = abs (n_counts); + unsigned counter_idx = GCOV_COUNTER_FOR_TAG (tag); printf (" %s %u counts%s", - counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts, + counter_names[counter_idx], n_counts, has_zeros ? " (all zero)" : ""); if (flag_dump_contents) { + vector<gcov_type> counters; for (int ix = 0; ix != n_counts; ix++) + counters.push_back (has_zeros ? 0 : gcov_read_counter ()); + + /* Make stable sort for TOP N counters. */ + if (flag_dump_stable) + if (counter_idx == GCOV_COUNTER_V_INDIR + || counter_idx == GCOV_COUNTER_V_TOPN) + { + unsigned start = 0; + while (start < counters.size ()) + { + unsigned n = counters[start + 1]; + + /* Use bubble sort. */ + for (unsigned i = 1; i <= n; ++i) + for (unsigned j = i; j <= n; ++j) + { + gcov_type key1 = counters[start + 2 * i]; + gcov_type value1 = counters[start + 2 * i + 1]; + gcov_type key2 = counters[start + 2 * j]; + gcov_type value2 = counters[start + 2 * j + 1]; + + if (value1 < value2 || (value1 == value2 && key1 < key2)) + { + std::swap (counters[start + 2 * i], + counters[start + 2 * j]); + std::swap (counters[start + 2 * i + 1], + counters[start + 2 * j + 1]); + } + } + start += 2 * (n + 1); + } + if (start != counters.size ()) + abort (); + } + + for (unsigned ix = 0; ix < counters.size (); ++ix) { - gcov_type count; - if (flag_dump_raw) { if (ix == 0) @@ -461,8 +509,7 @@ tag_counters (const char *filename ATTRIBUTE_UNUSED, printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix); } - count = has_zeros ? 0 : gcov_read_counter (); - printf ("%" PRId64 " ", count); + printf ("%" PRId64 " ", counters[ix]); } } } |