This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 4/7] GCOV: add -j argument (human readable format).


Human readable format is quite useful in my opinion. There's example:

        -:    1:unsigned
   14.00K:    2:loop (unsigned n, int value)
        -:    3:{
   21.00M:    4:  for (unsigned i = 0; i < n - 1; i++)
        -:    5:  {
   20.99M:    6:    value += i;
        -:    7:  }
        -:    8:
   14.00K:    9:  return value;
        -:   10:}
        -:   11:
        1:   12:int main(int argc)
        -:   13:{
        1:   14:  unsigned sum = 0;
    7.00K:   15:  for (unsigned i = 0; i < 7 * 1000; i++)
        -:   16:  {
    7.00K:   17:    sum += loop (1000, sum);
    7.00K:   18:    sum += loop (2000, sum);
        -:   19:  }
        -:   20:
        1:   21:  return 0;
        -:   22:}

Question is do we want to do it by default, or a new option is fine?
Note that all external tools using gcov should use intermediate format
which is obviously unchanged.

gcc/ChangeLog:

2017-10-23  Martin Liska  <mliska@suse.cz>

	* 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.

gcc/testsuite/ChangeLog:

2017-10-23  Martin Liska  <mliska@suse.cz>

	* g++.dg/gcov/loop.C: New test.
	* lib/gcov.exp: Support human readable format for counts.
---
 gcc/doc/gcov.texi                |  5 +++++
 gcc/gcov.c                       | 43 ++++++++++++++++++++++++++++++++++++++--
 gcc/testsuite/g++.dg/gcov/loop.C | 27 +++++++++++++++++++++++++
 gcc/testsuite/lib/gcov.exp       |  2 +-
 4 files changed, 74 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/gcov/loop.C

diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 4029ccb0a93..9d955827706 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-numbers}]
      [@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-numbers
+Write counts in human readable format (like 24.64K).
+
 @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 f9334f96eb3..8ba63f002d8 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -393,6 +393,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;
@@ -710,6 +714,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-numbers             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");
@@ -752,6 +757,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-numbers",	    no_argument,       NULL, 'j' },
   { "no-output",            no_argument,       NULL, 'n' },
   { "long-file-names",      no_argument,       NULL, 'l' },
   { "function-summaries",   no_argument,       NULL, 'f' },
@@ -775,7 +781,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)
@@ -798,6 +804,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;
@@ -1938,6 +1947,36 @@ 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];
+  float v = count;
+  const char *units[] = {"", "K", "M", "G", "Y", "P", "E", "Z"};
+
+  if (count < 1000 || !flag_human_readable_numbers)
+    {
+      sprintf (buffer, "%" PRId64, count);
+      return buffer;
+    }
+
+  for (unsigned i = 0; i < sizeof (units); i++)
+    {
+      if (v < 1000.0f)
+	{
+	  sprintf (buffer, "%3.2f%s", v, units[i]);
+	  return buffer;
+	}
+
+      v /= 1000.0f;
+    }
+
+  gcc_unreachable ();
+}
+
 /* 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
@@ -1985,7 +2024,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/g++.dg/gcov/loop.C b/gcc/testsuite/g++.dg/gcov/loop.C
new file mode 100644
index 00000000000..a9d404e7e11
--- /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(14.00K) */
+{
+  for (unsigned i = 0; i < n - 1; i++)
+  {
+    value += i;				  /* count(20.99M) */
+  }
+
+  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(7.00K) */
+  }
+
+  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 18adc71351a..38f0db09afc 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\\-#=\\.KMGYPEZ]+)\\)(.*)" \
 		"$line" all is n shouldbe rest] {
 	    if [regexp "^ *{(.*)}" $rest all xfailed] {
 		switch [dg-process-target $xfailed] {
-- 
2.14.2



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]