Instrument only selected files (PR gcov-profile/87442).
authorMartin Liska <mliska@suse.cz>
Mon, 12 Nov 2018 21:01:38 +0000 (22:01 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Mon, 12 Nov 2018 21:01:38 +0000 (21:01 +0000)
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

gcc/ChangeLog
gcc/common.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/profile-filtering-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/profile-filtering-2.c [new file with mode: 0644]
gcc/tree-profile.c

index 7c4307ef4aea2a242e491c87415a70dc6f4b5c7b..b4195db10328d2e52640ac30df8dbc9cacf47c36 100644 (file)
@@ -1,3 +1,16 @@
+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 target/87903
index 081a9428a323701e1c98c8398fabe78ae96c57e3..73065f5a1e282524b9ea1a1c74379dd0f0dce209 100644 (file)
@@ -2079,6 +2079,14 @@ fprofile-update=
 Common Joined RejectNegative Enum(profile_update) Var(flag_profile_update) Init(PROFILE_UPDATE_SINGLE)
 -fprofile-update=[single|atomic|prefer-atomic] Set the profile update method.
 
+fprofile-filter-files=
+Common Joined RejectNegative Var(flag_profile_filter_files)
+Instrument only functions from files where names match any regular expression (separated by a semi-colon).
+
+fprofile-exclude-files=
+Common Joined RejectNegative Var(flag_profile_exclude_files)
+Instrument only functions from files where names do not match all the regular expressions (separated by a semi-colon).
+
 Enum
 Name(profile_update) Type(enum profile_update) UnknownError(unknown profile update method %qs)
 
index 5eef746e7d1aaa5ce9ff7132b463921f993d2048..75e9556f092d1c924f6f1d4c06fa86a793b7f4fb 100644 (file)
@@ -484,6 +484,7 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-p  -pg  -fprofile-arcs  --coverage  -ftest-coverage @gol
 -fprofile-abs-path @gol
 -fprofile-dir=@var{path}  -fprofile-generate  -fprofile-generate=@var{path} @gol
+-fprofile-update=@var{method}  -fprofile-filter-files=@var{regex}  -fprofile-exclude-files=@var{regex} @gol
 -fsanitize=@var{style}  -fsanitize-recover  -fsanitize-recover=@var{style} @gol
 -fasan-shadow-offset=@var{number}  -fsanitize-sections=@var{s1},@var{s2},... @gol
 -fsanitize-undefined-trap-on-error  -fbounds-check @gol
@@ -11896,6 +11897,24 @@ when supported by a target, or to @samp{single} otherwise.  The GCC driver
 automatically selects @samp{prefer-atomic} when @option{-pthread}
 is present in the command line.
 
+@item -fprofile-filter-files=@var{regex}
+@opindex fprofile-filter-files
+
+Instrument only functions from files where names match
+any regular expression (separated by a semi-colon).
+
+For example, @option{-fprofile-filter-files=main.c;module.*.c} will instrument
+only @file{main.c} and all C files starting with 'module'.
+
+@item -fprofile-exclude-files=@var{regex}
+@opindex fprofile-exclude-files
+
+Instrument only functions from files where names do not match
+all the regular expressions (separated by a semi-colon).
+
+For example, @option{-fprofile-exclude-files=/usr/*} will prevent instrumentation
+of all files that are located in @file{/usr/} folder.
+
 @item -fsanitize=address
 @opindex fsanitize=address
 Enable AddressSanitizer, a fast memory error detector.
index f2a4baf3b00f14dc2c996fb410b0ade5254edee7..3bc031e70a7fba1368cd01be39a35ae8f2f63e73 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2018-11-12  Martin Sebor  <msebor@redhat.com>
 
        PR c/81824
diff --git a/gcc/testsuite/gcc.dg/profile-filtering-1.c b/gcc/testsuite/gcc.dg/profile-filtering-1.c
new file mode 100644 (file)
index 0000000..f123e24
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-require-profiling "-fprofile-generate" } */
+/* { dg-options "-O2 -fprofile-generate -fprofile-filter-files=.\*filtering-1.c -fdump-tree-optimized" } */
+
+extern void abort (void);
+
+int *p1;
+int *p2;
+int *p3;
+
+int ga = 100;
+
+int
+sub (int i, int j)
+{
+  int k;
+  int l;
+  int m;
+  int n;
+  p1 = &k;
+  p2 = &l;
+  p3 = &m;
+  k = 20;
+  l = 30;
+  m = 40;
+  n = i / j;
+  return n + ga;
+}
+
+int
+main(void)
+{
+  if (sub (99, 33) != 103)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "PROF_edge" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/profile-filtering-2.c b/gcc/testsuite/gcc.dg/profile-filtering-2.c
new file mode 100644 (file)
index 0000000..98bd3ae
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-require-profiling "-fprofile-generate" } */
+/* { dg-options "-O2 -fprofile-generate -fprofile-filter-files=.\*filtering-1.c -fprofile-exclude-files=.\* -fdump-tree-optimized" } */
+
+extern void abort (void);
+
+int *p1;
+int *p2;
+int *p3;
+
+int ga = 100;
+
+int
+sub (int i, int j)
+{
+  int k;
+  int l;
+  int m;
+  int n;
+  p1 = &k;
+  p2 = &l;
+  p3 = &m;
+  k = 20;
+  l = 30;
+  m = 40;
+  n = i / j;
+  return n + ga;
+}
+
+int
+main(void)
+{
+  if (sub (99, 33) != 103)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "PROF_edge" "optimized" } } */
index d8f2a3b1ba40b83d949a02afe57d51ce6645a48e..48204423eaf45ceeac5ba45c46cf018cda111d51 100644 (file)
@@ -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)