Support variables in expansion of -fprofile-generate option (PR gcov-profile/47618).

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
This commit is contained in:
Martin Liska 2018-06-05 14:10:22 +02:00 committed by Martin Liska
parent 066c4268db
commit 97a53d1d04
4 changed files with 97 additions and 0 deletions

View 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> 2018-06-05 Richard Biener <rguenther@suse.de>
* tree-cfgcleanup.c (cleanup_control_flow_pre): For edge * tree-cfgcleanup.c (cleanup_control_flow_pre): For edge

View 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 By default, GCC uses the current directory as @var{path}, thus the
profile data file appears in the same directory as the object file. 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 @item -fprofile-generate
@itemx -fprofile-generate=@var{path} @itemx -fprofile-generate=@var{path}
@opindex fprofile-generate @opindex fprofile-generate

View 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> 2018-06-05 Martin Liska <mliska@suse.cz>
* libgcov-driver.c (gcov_compute_histogram): Remove usage * libgcov-driver.c (gcov_compute_histogram): Remove usage

View File

@ -136,6 +136,74 @@ create_file_directory (char *filename)
#endif #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 static void
allocate_filename_struct (struct gcov_filename *gf) allocate_filename_struct (struct gcov_filename *gf)
{ {
@ -224,6 +292,8 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
} }
strcpy (dst, fname); strcpy (dst, fname);
gf->filename = replace_filename_variables (gf->filename);
if (!gcov_open (gf->filename)) if (!gcov_open (gf->filename))
{ {
/* Open failed likely due to missed directory. /* Open failed likely due to missed directory.