diff options
author | Martin Liska <mliska@suse.cz> | 2018-11-12 22:01:38 +0100 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2018-11-12 21:01:38 +0000 |
commit | e18240ffe2b48af6e77018e5f4e797c4b57cae72 (patch) | |
tree | 47b3de5539d55bde0524f303bd78eed461e6601e /gcc/tree-profile.c | |
parent | e375da43d77a3b54185f26c6f474e3482185e7e4 (diff) | |
download | gcc-e18240ffe2b48af6e77018e5f4e797c4b57cae72.zip gcc-e18240ffe2b48af6e77018e5f4e797c4b57cae72.tar.gz gcc-e18240ffe2b48af6e77018e5f4e797c4b57cae72.tar.bz2 |
Instrument only selected files (PR gcov-profile/87442).
2018-11-12 Martin Liska <mliska@suse.cz>
PR gcov-profile/87442
* common.opt: Add -fprofile-filter-files and -fprofile-exclude-files
options.
* doc/invoke.texi: Document them.
* tree-profile.c (parse_profile_filter): New.
(parse_profile_file_filtering): Likewise.
(release_profile_file_filtering): Likewise.
(include_source_file_for_profile): Likewise.
(tree_profiling): Filter source files based on the
newly added options.
2018-11-12 Martin Liska <mliska@suse.cz>
PR gcov-profile/87442
* gcc.dg/profile-filtering-1.c: New test.
* gcc.dg/profile-filtering-2.c: New test.
From-SVN: r266037
Diffstat (limited to 'gcc/tree-profile.c')
-rw-r--r-- | gcc/tree-profile.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index d8f2a3b..4820442 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "langhooks.h" #include "stor-layout.h" +#include "xregex.h" static GTY(()) tree gcov_type_node; static GTY(()) tree tree_interval_profiler_fn; @@ -610,6 +611,82 @@ gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) gsi_insert_before (&gsi, call, GSI_NEW_STMT); } +static vec<regex_t> profile_filter_files; +static vec<regex_t> profile_exclude_files; + +/* Parse list of provided REGEX (separated with semi-collon) and + create expressions (of type regex_t) and save them into V vector. + If there is a regular expression parsing error, error message is + printed for FLAG_NAME. */ + +static void +parse_profile_filter (const char *regex, vec<regex_t> *v, + const char *flag_name) +{ + v->create (4); + if (regex != NULL) + { + char *str = xstrdup (regex); + for (char *p = strtok (str, ";"); p != NULL; p = strtok (NULL, ";")) + { + regex_t r; + if (regcomp (&r, p, REG_EXTENDED | REG_NOSUB) != 0) + { + error ("invalid regular expression '%s' in %<%s%>", + p, flag_name); + return; + } + + v->safe_push (r); + } + } +} + +/* Parse values of -fprofile-filter-files and -fprofile-exclude-files + options. */ + +static void +parse_profile_file_filtering () +{ + parse_profile_filter (flag_profile_filter_files, &profile_filter_files, + "-fprofile-filter-files"); + parse_profile_filter (flag_profile_exclude_files, &profile_exclude_files, + "-fprofile-exclude-files"); +} + +/* Parse vectors of regular expressions. */ + +static void +release_profile_file_filtering () +{ + profile_filter_files.release (); + profile_exclude_files.release (); +} + +/* Return true when FILENAME should be instrumented based on + -fprofile-filter-files and -fprofile-exclude-files options. */ + +static bool +include_source_file_for_profile (const char *filename) +{ + /* First check whether file is included in flag_profile_exclude_files. */ + for (unsigned i = 0; i < profile_exclude_files.length (); i++) + if (regexec (&profile_exclude_files[i], + filename, 0, NULL, 0) == REG_NOERROR) + return false; + + /* For non-empty flag_profile_filter_files include only files matching a + regex in the flag. */ + if (profile_filter_files.is_empty ()) + return true; + + for (unsigned i = 0; i < profile_filter_files.length (); i++) + if (regexec (&profile_filter_files[i], filename, 0, NULL, 0) == REG_NOERROR) + return true; + + return false; +} + #ifndef HAVE_sync_compare_and_swapsi #define HAVE_sync_compare_and_swapsi 0 #endif @@ -658,6 +735,7 @@ tree_profiling (void) gcc_assert (symtab->state == IPA_SSA); init_node_map (true); + parse_profile_file_filtering (); FOR_EACH_DEFINED_FUNCTION (node) { @@ -678,6 +756,10 @@ tree_profiling (void) && flag_test_coverage) continue; + const char *file = LOCATION_FILE (DECL_SOURCE_LOCATION (node->decl)); + if (!include_source_file_for_profile (file)) + continue; + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); if (dump_file) @@ -706,6 +788,8 @@ tree_profiling (void) pop_cfun (); } + release_profile_file_filtering (); + /* Drop pure/const flags from instrumented functions. */ if (profile_arc_flag || flag_test_coverage) FOR_EACH_DEFINED_FUNCTION (node) |