diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-03-30 16:53:29 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-04-28 20:46:50 +0200 |
commit | 210e32b60b9018e5db2d9741dc7aaa5d9b436999 (patch) | |
tree | 1ab37b8840ce2f34db3bbe36c9836da255e8dbac /libgcc | |
parent | ef9a53feae5701953da9161afef2aea0329ec8b2 (diff) | |
download | gcc-210e32b60b9018e5db2d9741dc7aaa5d9b436999.zip gcc-210e32b60b9018e5db2d9741dc7aaa5d9b436999.tar.gz gcc-210e32b60b9018e5db2d9741dc7aaa5d9b436999.tar.bz2 |
gcov-tool: Add merge-stream subcommand
gcc/
* doc/gcov-tool.texi: Document merge-stream subcommand.
* doc/invoke.texi (fprofile-info-section): Mention merge-stream
subcommand of gcov-tool.
* 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.
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/libgcov-util.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c index bf96f50..250dddd 100644 --- a/libgcc/libgcov-util.c +++ b/libgcc/libgcov-util.c @@ -735,6 +735,101 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile return tgt_profile; } +/* Deserialize gcov_info objects and associated filenames from the file + specified by FILENAME to create a profile list. When FILENAME is NULL, read + from stdin. Return the profile list. */ + +struct gcov_info * +deserialize_profiles (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; +} + +/* For each profile of the list specified by SRC_PROFILE, read the GCDA file of + the profile. If a GCDA file exists, add the profile to a list. Return the + profile list. */ + +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; +} + +/* Deserialize gcov_info objects and associated filenames from the file + specified by FILENAME to create a source profile list. When FILENAME is + NULL, read from stdin. Use the filenames of the source profile list to get + a target profile list. Merge the source profile list into the target + profile list using weights W1 and W2. Return the list of merged gcov_info + objects. Return NULL if the list is empty. */ + +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 = deserialize_profiles (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. */ |