199 lines
6.8 KiB
Diff
199 lines
6.8 KiB
Diff
From 123f668cfe3b8ad1144e455351dcde1e94d82224 Mon Sep 17 00:00:00 2001
|
|
From: zhenyu--zhao_admin <zhaozhenyu17@huawei.com>
|
|
Date: Tue, 11 Jun 2024 19:03:07 +0800
|
|
Subject: [PATCH 1/1] add whitelist feature for OneProfile
|
|
|
|
---
|
|
gcc/gcov-tool.c | 21 ++++++++++++------
|
|
libgcc/libgcov-util.c | 50 +++++++++++++++++++++++++++++++++++++------
|
|
2 files changed, 59 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/gcc/gcov-tool.c b/gcc/gcov-tool.c
|
|
index f8f1cb5d2..9c33e5c49 100644
|
|
--- a/gcc/gcov-tool.c
|
|
+++ b/gcc/gcov-tool.c
|
|
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
#endif
|
|
#include <getopt.h>
|
|
|
|
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
|
|
+extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*,
|
|
+ int, int, char*);
|
|
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);
|
|
@@ -137,7 +138,8 @@ gcov_output_files (const char *out, struct gcov_info *profile)
|
|
Return 0 on success. */
|
|
|
|
static int
|
|
-profile_merge (const char *d1, const char *d2, const char *out, int w1, int w2)
|
|
+profile_merge (const char *d1, const char *d2, const char *out, int w1, int w2,
|
|
+ char* whitelistPath)
|
|
{
|
|
struct gcov_info *d1_profile;
|
|
struct gcov_info *d2_profile;
|
|
@@ -154,7 +156,7 @@ profile_merge (const char *d1, const char *d2, const char *out, int w1, int w2)
|
|
return 1;
|
|
|
|
/* The actual merge: we overwrite to d1_profile. */
|
|
- ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
|
|
+ ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2, whitelistPath);
|
|
|
|
if (ret)
|
|
return ret;
|
|
@@ -176,6 +178,7 @@ print_merge_usage_message (int error_p)
|
|
fnotice (file, " -o, --output <dir> Output directory\n");
|
|
fnotice (file, " -v, --verbose Verbose mode\n");
|
|
fnotice (file, " -w, --weight <w1,w2> Set weights (float point values)\n");
|
|
+ fnotice (file, " -p, --whitelistPath <dir> Only merge the function in the whiteList\n");
|
|
}
|
|
|
|
static const struct option merge_options[] =
|
|
@@ -183,7 +186,8 @@ static const struct option merge_options[] =
|
|
{ "verbose", no_argument, NULL, 'v' },
|
|
{ "output", required_argument, NULL, 'o' },
|
|
{ "weight", required_argument, NULL, 'w' },
|
|
- { 0, 0, 0, 0 }
|
|
+ { "WhitelistPath", required_argument, NULL, 'p' },
|
|
+ { 0, 0, 0, 0 },
|
|
};
|
|
|
|
/* Print merge usage and exit. */
|
|
@@ -204,9 +208,10 @@ do_merge (int argc, char **argv)
|
|
int opt;
|
|
const char *output_dir = 0;
|
|
int w1 = 1, w2 = 1;
|
|
+ char *path = 0;
|
|
|
|
optind = 0;
|
|
- while ((opt = getopt_long (argc, argv, "vo:w:", merge_options, NULL)) != -1)
|
|
+ while ((opt = getopt_long (argc, argv, "vo:w:p:", merge_options, NULL)) != -1)
|
|
{
|
|
switch (opt)
|
|
{
|
|
@@ -222,6 +227,9 @@ do_merge (int argc, char **argv)
|
|
if (w1 < 0 || w2 < 0)
|
|
fatal_error (input_location, "weights need to be non-negative");
|
|
break;
|
|
+ case 'p':
|
|
+ path = optarg;
|
|
+ break;
|
|
default:
|
|
merge_usage ();
|
|
}
|
|
@@ -233,7 +241,8 @@ do_merge (int argc, char **argv)
|
|
if (argc - optind != 2)
|
|
merge_usage ();
|
|
|
|
- return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
|
|
+ return profile_merge (argv[optind], argv[optind+1], output_dir,
|
|
+ w1, w2, path);
|
|
}
|
|
|
|
/* If N_VAL is no-zero, normalize the profile by setting the largest counter
|
|
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
|
|
index fff54c6a3..8978a30b3 100644
|
|
--- a/libgcc/libgcov-util.c
|
|
+++ b/libgcc/libgcov-util.c
|
|
@@ -516,6 +516,33 @@ merge_wrapper (gcov_merge_fn f, gcov_type *v1, gcov_unsigned_t n,
|
|
(*f) (v1, n);
|
|
}
|
|
|
|
+/* A helper function to merge function. It only merges the function in
|
|
+ * whitelist. */
|
|
+static int
|
|
+merge_whitelist (char *filePath, gcov_unsigned_t element)
|
|
+{
|
|
+ char functionIdent[20];
|
|
+ sprintf (functionIdent, "%u", element);
|
|
+ FILE *file = fopen (filePath, "r");
|
|
+ if (file == NULL)
|
|
+ {
|
|
+ fnotice (stderr, "Didn't get the whitelist we want. Please check the path.");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ char line[256];
|
|
+ while (fgets (line, sizeof (line), file))
|
|
+ {
|
|
+ if (strstr (line, functionIdent) != NULL)
|
|
+ {
|
|
+ fclose (file);
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ fclose (file);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Offline tool to manipulate profile data.
|
|
This tool targets on matched profiles. But it has some tolerance on
|
|
unmatched profiles.
|
|
@@ -533,7 +560,8 @@ merge_wrapper (gcov_merge_fn f, gcov_type *v1, gcov_unsigned_t n,
|
|
/* Add INFO2's counter to INFO1, multiplying by weight W. */
|
|
|
|
static int
|
|
-gcov_merge (struct gcov_info *info1, struct gcov_info *info2, int w)
|
|
+gcov_merge (struct gcov_info *info1, struct gcov_info *info2, int w,
|
|
+ char* filePath)
|
|
{
|
|
unsigned f_ix;
|
|
unsigned n_functions = info1->n_functions;
|
|
@@ -551,7 +579,17 @@ gcov_merge (struct gcov_info *info1, struct gcov_info *info2, int w)
|
|
continue;
|
|
if (!gfi_ptr2 || gfi_ptr2->key != info2)
|
|
continue;
|
|
-
|
|
+
|
|
+ /* Use whitelist feature here. */
|
|
+ if (gfi_ptr1 && filePath != 0)
|
|
+ {
|
|
+ int res = merge_whitelist (filePath, gfi_ptr1->ident);
|
|
+ if (!res)
|
|
+ {
|
|
+ /* Don't merge this function here. */
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
if (gfi_ptr1->cfg_checksum != gfi_ptr2->cfg_checksum)
|
|
{
|
|
fnotice (stderr, "in %s, cfg_checksum mismatch, skipping\n",
|
|
@@ -622,7 +660,7 @@ find_match_gcov_info (struct gcov_info **array, int size,
|
|
|
|
int
|
|
gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile,
|
|
- int w1, int w2)
|
|
+ int w1, int w2, char* WhitelistPath)
|
|
{
|
|
struct gcov_info *gi_ptr;
|
|
struct gcov_info **tgt_infos;
|
|
@@ -652,7 +690,7 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
|
|
if (w1 > 1)
|
|
{
|
|
for (i = 0; i < tgt_cnt; i++)
|
|
- gcov_merge (tgt_infos[i], tgt_infos[i], w1-1);
|
|
+ gcov_merge (tgt_infos[i], tgt_infos[i], w1-1, WhitelistPath);
|
|
}
|
|
|
|
/* Second pass, add src_profile to the tgt_profile. */
|
|
@@ -666,14 +704,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info *src_profile
|
|
in_src_not_tgt[unmatch_info_cnt++] = gi_ptr;
|
|
continue;
|
|
}
|
|
- gcov_merge (gi_ptr1, gi_ptr, w2);
|
|
+ gcov_merge (gi_ptr1, gi_ptr, w2, WhitelistPath);
|
|
}
|
|
|
|
/* For modules in src but not in tgt. We adjust the counter and append. */
|
|
for (i = 0; i < unmatch_info_cnt; i++)
|
|
{
|
|
gi_ptr = in_src_not_tgt[i];
|
|
- gcov_merge (gi_ptr, gi_ptr, w2 - 1);
|
|
+ gcov_merge (gi_ptr, gi_ptr, w2 - 1, WhitelistPath);
|
|
gi_ptr->next = NULL;
|
|
tgt_tail->next = gi_ptr;
|
|
tgt_tail = gi_ptr;
|
|
--
|
|
2.33.0
|
|
|