Mercurial > hg > CbC > CbC_gcc
diff gcc/gcov-dump.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/gcov-dump.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/gcov-dump.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,6 +1,5 @@ /* Dump a gcov file, for debugging use. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 2002-2017 Free Software Foundation, Inc. Contributed by Nathan Sidwell <nathan@codesourcery.com> Gcov is free software; you can redistribute it and/or modify @@ -22,32 +21,38 @@ #include "coretypes.h" #include "tm.h" #include "version.h" +#include "intl.h" +#include "diagnostic.h" #include <getopt.h> #define IN_GCOV (-1) #include "gcov-io.h" #include "gcov-io.c" -static void dump_file (const char *); +static void dump_gcov_file (const char *); static void print_prefix (const char *, unsigned, gcov_position_t); static void print_usage (void); static void print_version (void); -static void tag_function (const char *, unsigned, unsigned); -static void tag_blocks (const char *, unsigned, unsigned); -static void tag_arcs (const char *, unsigned, unsigned); -static void tag_lines (const char *, unsigned, unsigned); -static void tag_counters (const char *, unsigned, unsigned); -static void tag_summary (const char *, unsigned, unsigned); +static void tag_function (const char *, unsigned, unsigned, unsigned); +static void tag_blocks (const char *, unsigned, unsigned, unsigned); +static void tag_arcs (const char *, unsigned, unsigned, unsigned); +static void tag_lines (const char *, unsigned, unsigned, unsigned); +static void tag_counters (const char *, unsigned, unsigned, unsigned); +static void tag_summary (const char *, unsigned, unsigned, unsigned); +static void dump_working_sets (const char *filename ATTRIBUTE_UNUSED, + const struct gcov_ctr_summary *summary, + unsigned depth); extern int main (int, char **); typedef struct tag_format { unsigned tag; char const *name; - void (*proc) (const char *, unsigned, unsigned); + void (*proc) (const char *, unsigned, unsigned, unsigned); } tag_format_t; static int flag_dump_contents = 0; static int flag_dump_positions = 0; +static int flag_dump_working_sets = 0; static const struct option options[] = { @@ -55,9 +60,13 @@ { "version", no_argument, NULL, 'v' }, { "long", no_argument, NULL, 'l' }, { "positions", no_argument, NULL, 'o' }, + { "working-sets", no_argument, NULL, 'w' }, { 0, 0, 0, 0 } }; +#define VALUE_PADDING_PREFIX " " +#define VALUE_PREFIX "%2d: " + static const tag_format_t tag_table[] = { {0, "NOP", NULL}, @@ -76,11 +85,23 @@ main (int argc ATTRIBUTE_UNUSED, char **argv) { int opt; + const char *p; + + p = argv[0] + strlen (argv[0]); + while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) + --p; + progname = p; + + xmalloc_set_program_name (progname); /* Unlock the stdio streams. */ unlock_std_streams (); - while ((opt = getopt_long (argc, argv, "hlpv", options, NULL)) != -1) + gcc_init_libintl (); + + diagnostic_initialize (global_dc, 0); + + while ((opt = getopt_long (argc, argv, "hlpvw", options, NULL)) != -1) { switch (opt) { @@ -96,13 +117,16 @@ case 'p': flag_dump_positions = 1; break; + case 'w': + flag_dump_working_sets = 1; + break; default: fprintf (stderr, "unknown flag `%c'\n", opt); } } while (argv[optind]) - dump_file (argv[optind++]); + dump_gcov_file (argv[optind++]); return 0; } @@ -112,16 +136,19 @@ printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n"); printf ("Print coverage file contents\n"); printf (" -h, --help Print this help\n"); - printf (" -v, --version Print version number\n"); printf (" -l, --long Dump record contents too\n"); printf (" -p, --positions Dump record positions\n"); + printf (" -v, --version Print version number\n"); + printf (" -w, --working-sets Dump working set computed from summary\n"); + printf ("\nFor bug reporting instructions, please see:\n%s.\n", + bug_report_url); } static void print_version (void) { printf ("gcov-dump %s%s\n", pkgversion_string, version_string); - printf ("Copyright (C) 2011 Free Software Foundation, Inc.\n"); + printf ("Copyright (C) 2017 Free Software Foundation, Inc.\n"); printf ("This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or \n" "FITNESS FOR A PARTICULAR PURPOSE.\n\n"); @@ -134,12 +161,12 @@ printf ("%s:", filename); if (flag_dump_positions) - printf ("%lu:", (unsigned long) position); - printf ("%.*s", (int) depth, prefix); + printf ("%5lu:", (unsigned long) position); + printf ("%.*s", (int) 2 * depth, prefix); } static void -dump_file (const char *filename) +dump_gcov_file (const char *filename) { unsigned tags[4]; unsigned depth = 0; @@ -234,7 +261,7 @@ print_prefix (filename, tag_depth, position); printf ("%08x:%4u:%s", tag, length, format->name); if (format->proc) - (*format->proc) (filename, tag, length); + (*format->proc) (filename, tag, length, depth); printf ("\n"); if (flag_dump_contents && format->proc) @@ -262,53 +289,44 @@ static void tag_function (const char *filename ATTRIBUTE_UNUSED, - unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) + unsigned tag ATTRIBUTE_UNUSED, unsigned length, + unsigned depth ATTRIBUTE_UNUSED) { unsigned long pos = gcov_position (); - printf (" ident=%u", gcov_read_unsigned ()); - printf (", checksum=0x%08x", gcov_read_unsigned ()); - - if (gcov_position () - pos < length) + if (!length) + printf (" placeholder"); + else { - const char *name; + printf (" ident=%u", gcov_read_unsigned ()); + printf (", lineno_checksum=0x%08x", gcov_read_unsigned ()); + printf (", cfg_checksum=0x%08x", gcov_read_unsigned ()); - name = gcov_read_string (); - printf (", `%s'", name ? name : "NULL"); - name = gcov_read_string (); - printf (" %s", name ? name : "NULL"); - printf (":%u", gcov_read_unsigned ()); + if (gcov_position () - pos < length) + { + const char *name; + + name = gcov_read_string (); + printf (", `%s'", name ? name : "NULL"); + name = gcov_read_string (); + printf (" %s", name ? name : "NULL"); + printf (":%u", gcov_read_unsigned ()); + } } } static void tag_blocks (const char *filename ATTRIBUTE_UNUSED, - unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) + unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED, + unsigned depth ATTRIBUTE_UNUSED) { - unsigned n_blocks = GCOV_TAG_BLOCKS_NUM (length); - - printf (" %u blocks", n_blocks); - - if (flag_dump_contents) - { - unsigned ix; - - for (ix = 0; ix != n_blocks; ix++) - { - if (!(ix & 7)) - { - printf ("\n"); - print_prefix (filename, 0, gcov_position ()); - printf ("\t\t%u", ix); - } - printf (" %04x", gcov_read_unsigned ()); - } - } + printf (" %u blocks", gcov_read_unsigned ()); } static void tag_arcs (const char *filename ATTRIBUTE_UNUSED, - unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) + unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED, + unsigned depth) { unsigned n_arcs = GCOV_TAG_ARCS_NUM (length); @@ -325,19 +343,32 @@ if (!(ix & 3)) { printf ("\n"); - print_prefix (filename, 0, gcov_position ()); - printf ("\tblock %u:", blockno); + print_prefix (filename, depth, gcov_position ()); + printf (VALUE_PADDING_PREFIX "block %u:", blockno); } dst = gcov_read_unsigned (); flags = gcov_read_unsigned (); printf (" %u:%04x", dst, flags); + if (flags) + { + char c = '('; + + if (flags & GCOV_ARC_ON_TREE) + printf ("%ctree", c), c = ','; + if (flags & GCOV_ARC_FAKE) + printf ("%cfake", c), c = ','; + if (flags & GCOV_ARC_FALLTHROUGH) + printf ("%cfall", c), c = ','; + printf (")"); + } } } } static void tag_lines (const char *filename ATTRIBUTE_UNUSED, - unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) + unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED, + unsigned depth) { if (flag_dump_contents) { @@ -361,8 +392,8 @@ if (!sep) { printf ("\n"); - print_prefix (filename, 0, position); - printf ("\tblock %u:", blockno); + print_prefix (filename, depth, position); + printf (VALUE_PADDING_PREFIX "block %u:", blockno); sep = ""; } if (lineno) @@ -381,9 +412,14 @@ static void tag_counters (const char *filename ATTRIBUTE_UNUSED, - unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) + unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED, + unsigned depth) { - static const char *const counter_names[] = GCOV_COUNTER_NAMES; +#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME, + static const char *const counter_names[] = { +#include "gcov-counter.def" +}; +#undef DEF_GCOV_COUNTER unsigned n_counts = GCOV_TAG_COUNTER_NUM (length); printf (" %s %u counts", @@ -399,23 +435,24 @@ if (!(ix & 7)) { printf ("\n"); - print_prefix (filename, 0, gcov_position ()); - printf ("\t\t%u", ix); + print_prefix (filename, depth, gcov_position ()); + printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix); } count = gcov_read_counter (); - printf (" "); - printf (HOST_WIDEST_INT_PRINT_DEC, count); + printf ("%" PRId64 " ", count); } } } static void tag_summary (const char *filename ATTRIBUTE_UNUSED, - unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) + unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED, + unsigned depth) { struct gcov_summary summary; - unsigned ix; + unsigned ix, h_ix; + gcov_bucket_type *histo_bucket; gcov_read_summary (&summary); printf (" checksum=0x%08x", summary.checksum); @@ -423,15 +460,68 @@ for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++) { printf ("\n"); - print_prefix (filename, 0, 0); - printf ("\t\tcounts=%u, runs=%u", + print_prefix (filename, depth, 0); + printf (VALUE_PADDING_PREFIX "counts=%u, runs=%u", summary.ctrs[ix].num, summary.ctrs[ix].runs); - printf (", sum_all=" HOST_WIDEST_INT_PRINT_DEC, - (HOST_WIDEST_INT)summary.ctrs[ix].sum_all); - printf (", run_max=" HOST_WIDEST_INT_PRINT_DEC, - (HOST_WIDEST_INT)summary.ctrs[ix].run_max); - printf (", sum_max=" HOST_WIDEST_INT_PRINT_DEC, - (HOST_WIDEST_INT)summary.ctrs[ix].sum_max); + printf (", sum_all=%" PRId64, + (int64_t)summary.ctrs[ix].sum_all); + printf (", run_max=%" PRId64, + (int64_t)summary.ctrs[ix].run_max); + printf (", sum_max=%" PRId64, + (int64_t)summary.ctrs[ix].sum_max); + if (ix != GCOV_COUNTER_ARCS) + continue; + printf ("\n"); + print_prefix (filename, depth, 0); + printf (VALUE_PADDING_PREFIX "counter histogram:"); + for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) + { + histo_bucket = &summary.ctrs[ix].histogram[h_ix]; + if (!histo_bucket->num_counters) + continue; + printf ("\n"); + print_prefix (filename, depth, 0); + printf (VALUE_PADDING_PREFIX VALUE_PREFIX "num counts=%u, " + "min counter=%" PRId64 ", cum_counter=%" PRId64, + h_ix, histo_bucket->num_counters, + (int64_t)histo_bucket->min_value, + (int64_t)histo_bucket->cum_value); + } + if (flag_dump_working_sets) + dump_working_sets (filename, &summary.ctrs[ix], depth); } } + +static void +dump_working_sets (const char *filename ATTRIBUTE_UNUSED, + const struct gcov_ctr_summary *summary, + unsigned depth) +{ + gcov_working_set_t gcov_working_sets[NUM_GCOV_WORKING_SETS]; + unsigned ws_ix, pctinc, pct; + gcov_working_set_t *ws_info; + + compute_working_sets (summary, gcov_working_sets); + + printf ("\n"); + print_prefix (filename, depth, 0); + printf (VALUE_PADDING_PREFIX "counter working sets:"); + /* Multiply the percentage by 100 to avoid float. */ + pctinc = 100 * 100 / NUM_GCOV_WORKING_SETS; + for (ws_ix = 0, pct = pctinc; ws_ix < NUM_GCOV_WORKING_SETS; + ws_ix++, pct += pctinc) + { + if (ws_ix == NUM_GCOV_WORKING_SETS - 1) + pct = 9990; + ws_info = &gcov_working_sets[ws_ix]; + /* Print out the percentage using int arithmatic to avoid float. */ + printf ("\n"); + print_prefix (filename, depth + 1, 0); + printf (VALUE_PADDING_PREFIX "%u.%02u%%: num counts=%u, min counter=" + "%" PRId64, + pct / 100, pct - (pct / 100 * 100), + ws_info->num_counters, + (int64_t)ws_info->min_counter); + } +}