From 29a4ef18ec053a15ccc224d4cc5c8860b03496b4 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 31 Oct 2017 16:31:25 +0100 Subject: [PATCH] GCOV: add -j argument (human readable format). 2017-10-31 Martin Liska * doc/gcov.texi: Document new option. * gcov.c (print_usage): Likewise print it. (process_args): Support the argument. (format_count): New function. (format_gcov): Use the function. 2017-10-31 Martin Liska * g++.dg/gcov/loop.C: New test. * lib/gcov.exp: Support human readable format for counts. From-SVN: r254269 --- gcc/ChangeLog | 8 ++++++++ gcc/doc/gcov.texi | 5 +++++ gcc/gcov.c | 40 ++++++++++++++++++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/gcov/loop.C | 27 +++++++++++++++++++++++++++ gcc/testsuite/lib/gcov.exp | 2 +- 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/gcov/loop.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec118a0..c396b10 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2017-10-31 Martin Liska + * doc/gcov.texi: Document new option. + * gcov.c (print_usage): Likewise print it. + (process_args): Support the argument. + (format_count): New function. + (format_gcov): Use the function. + +2017-10-31 Martin Liska + * gcov.c (struct name_map): do not use typedef. Define operator== and operator<. (name_search): Remove. diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index e186ac6..5c4ba8a 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -125,6 +125,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}] [@option{-d}|@option{--display-progress}] [@option{-f}|@option{--function-summaries}] [@option{-i}|@option{--intermediate-format}] + [@option{-j}|@option{--human-readable}] [@option{-k}|@option{--use-colors}] [@option{-l}|@option{--long-file-names}] [@option{-m}|@option{--demangled-names}] @@ -186,6 +187,10 @@ be used by @command{lcov} or other tools. The output is a single The format of the intermediate @file{.gcov} file is plain text with one entry per line +@item -j +@itemx --human-readable +Write counts in human readable format (like 24k). + @smallexample file:@var{source_file_name} function:@var{line_number},@var{execution_count},@var{function_name} diff --git a/gcc/gcov.c b/gcc/gcov.c index f1e7777..48bcdc0 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -431,6 +431,10 @@ static int flag_use_colors = 0; static int flag_all_blocks = 0; +/* Output human readable numbers. */ + +static int flag_human_readable_numbers = 0; + /* Output summary info for each function. */ static int flag_function_summary = 0; @@ -742,6 +746,7 @@ print_usage (int error_p) fnotice (file, " -f, --function-summaries Output summaries for each function\n"); fnotice (file, " -h, --help Print this help, then exit\n"); fnotice (file, " -i, --intermediate-format Output .gcov file in intermediate text format\n"); + fnotice (file, " -j, --human-readable Output human readable numbers\n"); fnotice (file, " -k, --use-colors Emit colored output\n"); fnotice (file, " -l, --long-file-names Use long output file names for included\n\ source files\n"); @@ -784,6 +789,7 @@ static const struct option options[] = { "branch-probabilities", no_argument, NULL, 'b' }, { "branch-counts", no_argument, NULL, 'c' }, { "intermediate-format", no_argument, NULL, 'i' }, + { "human-readable", no_argument, NULL, 'j' }, { "no-output", no_argument, NULL, 'n' }, { "long-file-names", no_argument, NULL, 'l' }, { "function-summaries", no_argument, NULL, 'f' }, @@ -807,7 +813,7 @@ process_args (int argc, char **argv) { int opt; - const char *opts = "abcdfhiklmno:prs:uvwx"; + const char *opts = "abcdfhijklmno:prs:uvwx"; while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1) { switch (opt) @@ -830,6 +836,9 @@ process_args (int argc, char **argv) case 'l': flag_long_names = 1; break; + case 'j': + flag_human_readable_numbers = 1; + break; case 'k': flag_use_colors = 1; break; @@ -1914,6 +1923,33 @@ add_branch_counts (coverage_t *coverage, const arc_t *arc) } } +/* Format COUNT, if flag_human_readable_numbers is set, return it human + readable format. */ + +static char const * +format_count (gcov_type count) +{ + static char buffer[64]; + const char *units = " kMGTPEZY"; + + if (count < 1000 || !flag_human_readable_numbers) + { + sprintf (buffer, "%" PRId64, count); + return buffer; + } + + unsigned i; + gcov_type divisor = 1; + for (i = 0; units[i+1]; i++, divisor *= 1000) + { + if (count + divisor / 2 < 1000 * divisor) + break; + } + gcov_type r = (count + divisor / 2) / divisor; + sprintf (buffer, "%" PRId64 "%c", r, units[i]); + return buffer; +} + /* Format a GCOV_TYPE integer as either a percent ratio, or absolute count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places. If DP is zero, no decimal point is printed. Only print 100% when @@ -1961,7 +1997,7 @@ format_gcov (gcov_type top, gcov_type bottom, int dp) } } else - sprintf (buffer, "%" PRId64, (int64_t)top); + return format_count (top); return buffer; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a1adb14..37c15f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2017-10-31 Martin Liska + * g++.dg/gcov/loop.C: New test. + * lib/gcov.exp: Support human readable format for counts. + +2017-10-31 Martin Liska + * g++.dg/gcov/ternary.C: New test. * g++.dg/gcov/gcov-threads-1.C (main): Update expected line count. diff --git a/gcc/testsuite/g++.dg/gcov/loop.C b/gcc/testsuite/g++.dg/gcov/loop.C new file mode 100644 index 0000000..7f3be55 --- /dev/null +++ b/gcc/testsuite/g++.dg/gcov/loop.C @@ -0,0 +1,27 @@ +/* { dg-options "-fprofile-arcs -ftest-coverage" } */ +/* { dg-do run { target native } } */ + +unsigned +loop (unsigned n, int value) /* count(14k) */ +{ + for (unsigned i = 0; i < n - 1; i++) + { + value += i; /* count(21M) */ + } + + return value; +} + +int main(int argc, char **argv) +{ + unsigned sum = 0; + for (unsigned i = 0; i < 7 * 1000; i++) + { + sum += loop (1000, sum); + sum += loop (2000, sum); /* count(7k) */ + } + + return 0; /* count(1) */ +} + +/* { dg-final { run-gcov branches { -abj loop.C } } } */ diff --git a/gcc/testsuite/lib/gcov.exp b/gcc/testsuite/lib/gcov.exp index 18adc71..ede01e7 100644 --- a/gcc/testsuite/lib/gcov.exp +++ b/gcc/testsuite/lib/gcov.exp @@ -59,7 +59,7 @@ proc verify-lines { testname testcase file } { while { [gets $fd line] >= 0 } { # We want to match both "-" and "#####" as count as well as numbers, # since we want to detect lines that shouldn't be marked as covered. - if [regexp "^ *(\[^:]*): *(\[0-9\\-#]+):.*count\\((\[0-9\\-#=]+)\\)(.*)" \ + if [regexp "^ *(\[^:]*): *(\[0-9\\-#]+):.*count\\((\[0-9\\-#=\\.kMGTPEZY]+)\\)(.*)" \ "$line" all is n shouldbe rest] { if [regexp "^ *{(.*)}" $rest all xfailed] { switch [dg-process-target $xfailed] { -- 2.7.4