Support variables in expansion of -fprofile-generate option (PR gcov-profile/47618).
authorMartin Liska <mliska@suse.cz>
Tue, 5 Jun 2018 12:10:22 +0000 (14:10 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 5 Jun 2018 12:10:22 +0000 (12:10 +0000)
2018-06-05  Martin Liska  <mliska@suse.cz>

PR gcov-profile/47618
* doc/invoke.texi: Document how -fprofile-dir format
        is extended.
2018-06-05  Martin Liska  <mliska@suse.cz>

PR gcov-profile/47618
* libgcov-driver-system.c (replace_filename_variables): New
        function.
(gcov_exit_open_gcda_file): Use it.

From-SVN: r261199

gcc/ChangeLog
gcc/doc/invoke.texi
libgcc/ChangeLog
libgcc/libgcov-driver-system.c

index 7f5f4e407d1ff7773a66e6071ec21e4f26e6977c..25ab6bded67904adf38b101132976ed953459672 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-05  Martin Liska  <mliska@suse.cz>
+
+       PR gcov-profile/47618
+       * doc/invoke.texi: Document how -fprofile-dir format
+        is extended.
+
 2018-06-05  Richard Biener  <rguenther@suse.de>
 
        * tree-cfgcleanup.c (cleanup_control_flow_pre): For edge
index 169dd440059c4f57f4e57c8fcd0ef9283e822320..3d767b64e856adf155bd77c68157618ba45bbcab 100644 (file)
@@ -11343,6 +11343,20 @@ and its related options.  Both absolute and relative paths can be used.
 By default, GCC uses the current directory as @var{path}, thus the
 profile data file appears in the same directory as the object file.
 
+When an executable is run in a massive parallel environment, it is recommended
+to save profile to different folders.  That can be done with variables
+in @var{path} that are exported during run-time:
+
+@table @gcctabopt
+
+@item %p
+process ID.
+
+@item %q@{VAR@}
+value of environment variable @var{VAR}
+
+@end table
+
 @item -fprofile-generate
 @itemx -fprofile-generate=@var{path}
 @opindex fprofile-generate
index f2297c0a369b1d5b3985d63770dd3fed532299e1..5389999cd8c52bf0096e88a4d780b5515c095a60 100644 (file)
@@ -1,3 +1,10 @@
+2018-06-05  Martin Liska  <mliska@suse.cz>
+
+       PR gcov-profile/47618
+       * libgcov-driver-system.c (replace_filename_variables): New
+        function.
+       (gcov_exit_open_gcda_file): Use it.
+
 2018-06-05  Martin Liska  <mliska@suse.cz>
 
        * libgcov-driver.c (gcov_compute_histogram): Remove usage
index bf125869dc08c64363156534a74c1b23e81e8f27..7f3de6317018853f04f1d8ab5ece2edfb57e1355 100644 (file)
@@ -136,6 +136,74 @@ create_file_directory (char *filename)
 #endif
 }
 
+/* Replace filename variables in FILENAME.  We currently support expansion:
+
+   %p - process ID
+   %q{ENV} - value of environment variable ENV
+   */
+
+static char *
+replace_filename_variables (char *filename)
+{
+  char buffer[16];
+  char empty[] = "";
+  for (char *p = filename; *p != '\0'; p++)
+    {
+      unsigned length = strlen (filename);
+      if (*p == '%' && *(p + 1) != '\0')
+       {
+         unsigned start = p - filename;
+         p++;
+         char *replacement = NULL;
+         switch (*p)
+           {
+           case 'p':
+             sprintf (buffer, "%d", getpid ());
+             replacement = buffer;
+             p++;
+             break;
+           case 'q':
+             if (*(p + 1) == '{')
+               {
+                 p += 2;
+                 char *e = strchr (p, '}');
+                 if (e)
+                   {
+                     *e = '\0';
+                     replacement = getenv (p);
+                     if (replacement == NULL)
+                       replacement = empty;
+                     p = e + 1;
+                   }
+                 else
+                   return filename;
+               }
+             break;
+           default:
+             return filename;
+           }
+
+         /* Concat beginning of the path, replacement and
+            ending of the path.  */
+         unsigned end = length - (p - filename);
+         unsigned repl_length = strlen (replacement);
+
+         char *buffer = (char *)xmalloc (start + end + repl_length + 1);
+         char *buffer_ptr = buffer;
+         buffer_ptr = (char *)mempcpy (buffer_ptr, filename, start);
+         buffer_ptr = (char *)mempcpy (buffer_ptr, replacement, repl_length);
+         buffer_ptr = (char *)mempcpy (buffer_ptr, p, end);
+         *buffer_ptr = '\0';
+
+         free (filename);
+         filename = buffer;
+         p = buffer + start + repl_length;
+       }
+    }
+
+  return filename;
+}
+
 static void
 allocate_filename_struct (struct gcov_filename *gf)
 {
@@ -224,6 +292,8 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
     }
   strcpy (dst, fname);
 
+  gf->filename = replace_filename_variables (gf->filename);
+
   if (!gcov_open (gf->filename))
     {
       /* Open failed likely due to missed directory.