public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
To: gcc-patches@gcc.gnu.org
Subject: [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand
Date: Thu, 31 Mar 2022 13:35:15 +0200	[thread overview]
Message-ID: <20220331113515.35764-13-sebastian.huber@embedded-brains.de> (raw)
In-Reply-To: <20220331113515.35764-1-sebastian.huber@embedded-brains.de>

gcc/

	* gcov-tool.cc (gcov_profile_merge_stream): Declare.
	(print_merge_stream_usage_message): New.
	(merge_stream_usage): Likewise.
	(do_merge_stream): Likewise.
	(print_usage): Call print_merge_stream_usage_message().
	(main): Call do_merge_stream() to execute merge-stream subcommand.

libgcc/

	* libgcov-util.c (consume_stream): New.
	(get_target_profiles_for_merge): Likewise.
	(gcov_profile_merge_stream): Likewise.
---
 gcc/gcov-tool.cc      | 76 ++++++++++++++++++++++++++++++++++++++++
 libgcc/libgcov-util.c | 80 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 156 insertions(+)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index d712715cf7e..d8572b184e9 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
 					     struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
   return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
 }
 
+/* Usage message for profile merge-stream.  */
+
+static void
+print_merge_stream_usage_message (int error_p)
+{
+  FILE *file = error_p ? stderr : stdout;
+
+  fnotice (file, "  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)\n"
+		 "                                        and coverage file contents\n");
+  fnotice (file, "    -v, --verbose                       Verbose mode\n");
+  fnotice (file, "    -w, --weight <w1,w2>                Set weights (float point values)\n");
+}
+
+static const struct option merge_stream_options[] =
+{
+  { "verbose",                no_argument,       NULL, 'v' },
+  { "weight",                 required_argument, NULL, 'w' },
+  { 0, 0, 0, 0 }
+};
+
+/* Print merge-stream usage and exit.  */
+
+static void ATTRIBUTE_NORETURN
+merge_stream_usage (void)
+{
+  fnotice (stderr, "Merge-stream subcomand usage:");
+  print_merge_stream_usage_message (true);
+  exit (FATAL_EXIT_CODE);
+}
+
+/* Driver for profile merge-stream sub-command.  */
+
+static int
+do_merge_stream (int argc, char **argv)
+{
+  int opt;
+  int w1 = 1, w2 = 1;
+  struct gcov_info *merged_profile;
+
+  optind = 0;
+  while ((opt = getopt_long (argc, argv, "vw:",
+			     merge_stream_options, NULL)) != -1)
+    {
+      switch (opt)
+	{
+	case 'v':
+	  verbose = true;
+	  gcov_set_verbose ();
+	  break;
+	case 'w':
+	  sscanf (optarg, "%d,%d", &w1, &w2);
+	  if (w1 < 0 || w2 < 0)
+	    fatal_error (input_location, "weights need to be non-negative");
+	  break;
+	default:
+	  merge_stream_usage ();
+	}
+    }
+
+  if (argc - optind > 1)
+    merge_stream_usage ();
+
+  merged_profile = gcov_profile_merge_stream (argv[optind], w1, w2);
+
+  if (merged_profile)
+    gcov_do_dump (merged_profile, 0, -1);
+  else if (verbose)
+    fnotice (stdout, "no profile files were merged\n");
+
+  return 0;
+}
+
 /* If N_VAL is no-zero, normalize the profile by setting the largest counter
    counter value to N_VAL and scale others counters proportionally.
    Otherwise, multiply the all counters by SCALE.  */
@@ -505,6 +578,7 @@ print_usage (int error_p)
   fnotice (file, "  -h, --help                            Print this help, then exit\n");
   fnotice (file, "  -v, --version                         Print version number, then exit\n");
   print_merge_usage_message (error_p);
+  print_merge_stream_usage_message (error_p);
   print_rewrite_usage_message (error_p);
   print_overlap_usage_message (error_p);
   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
@@ -594,6 +668,8 @@ main (int argc, char **argv)
 
   if (!strcmp (sub_command, "merge"))
     return do_merge (argc - optind, argv + optind);
+  else if (!strcmp (sub_command, "merge-stream"))
+    return do_merge_stream (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "rewrite"))
     return do_rewrite (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "overlap"))
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 622d5a9dc71..0fe60528b48 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -735,6 +735,86 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
   return tgt_profile;
 }
 
+struct gcov_info *
+consume_stream (const char *filename)
+{
+  read_profile_dir_init ();
+
+  while (true)
+    {
+      unsigned version;
+      const char *filename_of_info;
+      struct gcov_info *obj_info;
+
+      if (!gcov_magic (gcov_read_unsigned (), GCOV_FILENAME_MAGIC))
+	{
+	  if (gcov_is_error() != 2)
+	    fnotice (stderr, "%s:not a gcfn stream\n", filename);
+	  break;
+	}
+
+      version = gcov_read_unsigned ();
+      if (version != GCOV_VERSION)
+	{
+	  fnotice (stderr, "%s:incorrect gcov version %d vs %d \n",
+		   filename, version, GCOV_VERSION);
+	  break;
+	}
+
+      filename_of_info = gcov_read_string ();
+      if (!filename_of_info)
+	{
+	  fnotice (stderr, "%s:no filename in gcfn stream\n",
+		   filename);
+	  break;
+	}
+
+      obj_info = read_gcda_file (filename);
+      if (!obj_info)
+	break;
+
+      obj_info->filename = filename_of_info;
+    }
+
+  return gcov_info_head;
+}
+
+struct gcov_info *
+get_target_profiles_for_merge (struct gcov_info *src_profile)
+{
+  struct gcov_info *gi_ptr;
+
+  read_profile_dir_init ();
+
+  for (gi_ptr = src_profile; gi_ptr; gi_ptr = gi_ptr->next)
+    if (gcov_open (gi_ptr->filename, 1))
+      {
+	(void)read_gcda_file (gi_ptr->filename);
+	gcov_close ();
+      }
+
+  return gcov_info_head;
+}
+
+struct gcov_info *
+gcov_profile_merge_stream (const char *filename, int w1, int w2)
+{
+  struct gcov_info *tgt_profile;
+  struct gcov_info *src_profile;
+
+  if (!gcov_open (filename, 1))
+    {
+      fnotice (stderr, "%s:cannot open\n", filename);
+      return NULL;
+    }
+
+  src_profile = consume_stream (filename ? filename : "<stdin>");
+  gcov_close ();
+  tgt_profile = get_target_profiles_for_merge (src_profile);
+
+  return gcov_profile_merge (tgt_profile, src_profile, w1, w2);
+}
+
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
 
 /* Performing FN upon arc counters.  */
-- 
2.34.1


  parent reply	other threads:[~2022-03-31 11:35 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-31 11:35 [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 02/12] gcov: Add mode to all gcov_open() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 04/12] gcov: Make gcov_seek() static Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 06/12] gcov-tool: Support file input from stdin Sebastian Huber
2022-04-07  8:32   ` Martin Liška
2022-03-31 11:35 ` [RFC/gcov 07/12] gcov: Use xstrdup() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file() Sebastian Huber
2022-04-07  8:33   ` Martin Liška
2022-03-31 11:35 ` [RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file() Sebastian Huber
2022-03-31 11:35 ` [RFC/gcov 11/12] gcov: Record EOF error during read Sebastian Huber
2022-04-07  8:34   ` Martin Liška
2022-03-31 11:35 ` Sebastian Huber [this message]
2022-04-07  8:36   ` [RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand Martin Liška
2022-04-07  8:38 ` [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool Martin Liška
2022-04-07  9:05   ` Sebastian Huber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220331113515.35764-13-sebastian.huber@embedded-brains.de \
    --to=sebastian.huber@embedded-brains.de \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).