aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-profile.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2018-11-12 22:01:38 +0100
committerMartin Liska <marxin@gcc.gnu.org>2018-11-12 21:01:38 +0000
commite18240ffe2b48af6e77018e5f4e797c4b57cae72 (patch)
tree47b3de5539d55bde0524f303bd78eed461e6601e /gcc/tree-profile.c
parente375da43d77a3b54185f26c6f474e3482185e7e4 (diff)
downloadgcc-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.c84
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)