forked from OSchip/llvm-project
This change is the first of 3 patches to add support for specifying
the profile output from the command line via -fprofile-instr-generate=<path>, where the specified output path/file will be overridden by the LLVM_PROFILE_FILE environment variable. Several changes are made to the runtime to support this: Add a new interface __llvm_profile_override_default_filename that will set the profile output filename, but allows LLVM_PROFILE_FILE to override. This is the interface used by the new option. Refactor the pid-expansion done for LLVM_PROFILE_FILE into a separate routine that can be shared by the various filename setting routines (so that the filename from the option can also use the "%p" syntax). Move the truncation into setFilename, and only truncate if there is a new filename specified (to maintain support for appending to the same profile file in the case of multiple shared objects built with profiling). Move the handling for a NULL filename passed to __llvm_profile_set_filename and __llvm_profile_override_default_filename into the new setFilenamePossiblyWithPid routine. This now correctly resets the output file to default.profraw instead of NULL. The handling for a null LLVM_PROFILE_FILE (which should not reset) is done by caller setFilenameFromEnvironment. Patch by Teresa Johnson. llvm-svn: 236055
This commit is contained in:
parent
0ba41a6841
commit
d641b53f93
|
@ -62,7 +62,9 @@ uint64_t *__llvm_profile_end_counters(void);
|
|||
*
|
||||
* Writes to the file with the last name given to \a __llvm_profile_set_filename(),
|
||||
* or if it hasn't been called, the \c LLVM_PROFILE_FILE environment variable,
|
||||
* or if that's not set, \c "default.profdata".
|
||||
* or if that's not set, the last name given to
|
||||
* \a __llvm_profile_override_default_filename(), or if that's not set,
|
||||
* \c "default.profdata".
|
||||
*/
|
||||
int __llvm_profile_write_file(void);
|
||||
|
||||
|
@ -77,6 +79,19 @@ int __llvm_profile_write_file(void);
|
|||
*/
|
||||
void __llvm_profile_set_filename(const char *Name);
|
||||
|
||||
/*!
|
||||
* \brief Set the filename for writing instrumentation data, unless the
|
||||
* \c LLVM_PROFILE_FILE environment variable was set.
|
||||
*
|
||||
* Unless overridden, sets the filename to be used for subsequent calls to
|
||||
* \a __llvm_profile_write_file().
|
||||
*
|
||||
* \c Name is not copied, so it must remain valid. Passing NULL resets the
|
||||
* filename logic to the default behaviour (unless the \c LLVM_PROFILE_FILE
|
||||
* was set in which case it has no effect).
|
||||
*/
|
||||
void __llvm_profile_override_default_filename(const char *Name);
|
||||
|
||||
/*! \brief Register to write instrumentation data to file at exit. */
|
||||
int __llvm_profile_register_write_file_atexit(void);
|
||||
|
||||
|
|
|
@ -76,14 +76,6 @@ static int writeFileWithName(const char *OutputName) {
|
|||
__attribute__((weak)) int __llvm_profile_OwnsFilename = 0;
|
||||
__attribute__((weak)) const char *__llvm_profile_CurrentFilename = NULL;
|
||||
|
||||
static void setFilename(const char *Filename, int OwnsFilename) {
|
||||
if (__llvm_profile_OwnsFilename)
|
||||
free(UNCONST(__llvm_profile_CurrentFilename));
|
||||
|
||||
__llvm_profile_CurrentFilename = Filename;
|
||||
__llvm_profile_OwnsFilename = OwnsFilename;
|
||||
}
|
||||
|
||||
static void truncateCurrentFile(void) {
|
||||
const char *Filename;
|
||||
FILE *File;
|
||||
|
@ -99,19 +91,36 @@ static void truncateCurrentFile(void) {
|
|||
fclose(File);
|
||||
}
|
||||
|
||||
static void setDefaultFilename(void) { setFilename("default.profraw", 0); }
|
||||
static void setFilename(const char *Filename, int OwnsFilename) {
|
||||
/* Check if this is a new filename and therefore needs truncation. */
|
||||
int NewFile = !__llvm_profile_CurrentFilename ||
|
||||
(Filename && strcmp(Filename, __llvm_profile_CurrentFilename));
|
||||
if (__llvm_profile_OwnsFilename)
|
||||
free(UNCONST(__llvm_profile_CurrentFilename));
|
||||
|
||||
__llvm_profile_CurrentFilename = Filename;
|
||||
__llvm_profile_OwnsFilename = OwnsFilename;
|
||||
|
||||
/* If not a new file, append to support profiling multiple shared objects. */
|
||||
if (NewFile)
|
||||
truncateCurrentFile();
|
||||
}
|
||||
|
||||
static void resetFilenameToDefault(void) { setFilename("default.profraw", 0); }
|
||||
|
||||
int getpid(void);
|
||||
static int setFilenameFromEnvironment(void) {
|
||||
const char *Filename = getenv("LLVM_PROFILE_FILE");
|
||||
static int setFilenamePossiblyWithPid(const char *Filename) {
|
||||
#define MAX_PID_SIZE 16
|
||||
char PidChars[MAX_PID_SIZE] = {0};
|
||||
int NumPids = 0, PidLength = 0;
|
||||
char *Allocated;
|
||||
int I, J;
|
||||
|
||||
if (!Filename || !Filename[0])
|
||||
return -1;
|
||||
/* Reset filename on NULL, except with env var which is checked by caller. */
|
||||
if (!Filename) {
|
||||
resetFilenameToDefault();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the filename for "%p", which indicates a pid-substitution. */
|
||||
for (I = 0; Filename[I]; ++I)
|
||||
|
@ -148,11 +157,20 @@ static int setFilenameFromEnvironment(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int setFilenameFromEnvironment(void) {
|
||||
const char *Filename = getenv("LLVM_PROFILE_FILE");
|
||||
|
||||
if (!Filename || !Filename[0])
|
||||
return -1;
|
||||
|
||||
return setFilenamePossiblyWithPid(Filename);
|
||||
}
|
||||
|
||||
static void setFilenameAutomatically(void) {
|
||||
if (!setFilenameFromEnvironment())
|
||||
return;
|
||||
|
||||
setDefaultFilename();
|
||||
resetFilenameToDefault();
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden")))
|
||||
|
@ -163,13 +181,20 @@ void __llvm_profile_initialize_file(void) {
|
|||
|
||||
/* Detect the filename and truncate. */
|
||||
setFilenameAutomatically();
|
||||
truncateCurrentFile();
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden")))
|
||||
void __llvm_profile_set_filename(const char *Filename) {
|
||||
setFilename(Filename, 0);
|
||||
truncateCurrentFile();
|
||||
setFilenamePossiblyWithPid(Filename);
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden")))
|
||||
void __llvm_profile_override_default_filename(const char *Filename) {
|
||||
/* If the env var is set, skip setting filename from argument. */
|
||||
const char *Env_Filename = getenv("LLVM_PROFILE_FILE");
|
||||
if (Env_Filename && Env_Filename[0])
|
||||
return;
|
||||
setFilenamePossiblyWithPid(Filename);
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden")))
|
||||
|
|
Loading…
Reference in New Issue