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
next prev 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).