[Profile] implement interface to get profile path prefix

Differential Revision:  http://reviews.llvm.org/D22546

llvm-svn: 276083
This commit is contained in:
Xinliang David Li 2016-07-20 04:26:09 +00:00
parent a75736087d
commit eaf238d494
3 changed files with 88 additions and 1 deletions

View File

@ -148,6 +148,16 @@ int __llvm_profile_register_write_file_atexit(void);
/*! \brief Initialize file handling. */
void __llvm_profile_initialize_file(void);
/*!
* \brief Return path prefix (excluding the base filename) of the profile data.
* This is useful for users using \c -fprofile-generate=./path_prefix who do
* not care about the default raw profile name. It is also useful to collect
* more than more profile data files dumped in the same directory (Online
* merge mode is turned on for instrumented programs with shared libs).
* Side-effect: this API call will invoke malloc with dynamic memory allocation.
*/
const char *__llvm_profile_get_path_prefix();
/*! \brief Get the magic token for the file format. */
uint64_t __llvm_profile_get_magic(void);

View File

@ -63,6 +63,7 @@ static const char *getPNSStr(ProfileNameSpecifier PNS) {
typedef struct lprofFilename {
/* File name string possibly with %p or %h specifiers. */
const char *FilenamePat;
const char *ProfilePathPrefix;
char PidChars[MAX_PID_SIZE];
char Hostname[COMPILER_RT_MAX_HOSTLEN];
unsigned NumPids;
@ -78,7 +79,7 @@ typedef struct lprofFilename {
ProfileNameSpecifier PNS;
} lprofFilename;
lprofFilename lprofCurFilename = {0, {0}, {0}, 0, 0, 0, PNS_unknown};
lprofFilename lprofCurFilename = {0, 0, {0}, {0}, 0, 0, 0, PNS_unknown};
int getpid(void);
static int getCurFilenameLength();
@ -344,6 +345,12 @@ static void parseAndSetFilename(const char *FilenamePat,
getPNSStr(PNS));
}
/* Clean up cached prefix. */
if (lprofCurFilename.ProfilePathPrefix) {
free((void*)lprofCurFilename.ProfilePathPrefix);
lprofCurFilename.ProfilePathPrefix = NULL;
}
if (!lprofCurFilename.MergePoolSize)
truncateCurrentFile();
}
@ -425,6 +432,37 @@ static const char *getFilenamePatFromEnv(void) {
return Filename;
}
COMPILER_RT_VISIBILITY
const char *__llvm_profile_get_path_prefix(void) {
int Length;
char *FilenameBuf, *Prefix;
const char *Filename, *PrefixEnd;
if (lprofCurFilename.ProfilePathPrefix)
return lprofCurFilename.ProfilePathPrefix;
Length = getCurFilenameLength();
FilenameBuf = (char *)COMPILER_RT_ALLOCA(Length + 1);
Filename = getCurFilename(FilenameBuf);
if (!Filename)
return "\0";
PrefixEnd = lprofFindLastDirSeparator(Filename);
if (!PrefixEnd)
return "\0";
Length = PrefixEnd - Filename + 1;
Prefix = (char *)malloc(Length + 1);
if (!Prefix) {
PROF_ERR("Failed to %s\n", "allocate memory.");
return "\0";
}
memcpy(Prefix, Filename, Length);
Prefix[Length] = '\0';
lprofCurFilename.ProfilePathPrefix = Prefix;
return Prefix;
}
/* This method is invoked by the runtime initialization hook
* InstrProfilingRuntime.o if it is linked in. Both user specified
* profile path via -fprofile-instr-generate= and LLVM_PROFILE_FILE

View File

@ -0,0 +1,39 @@
// RUN: %clang_pgogen -O2 -o %t.0 %s
// RUN: %clang_pgogen=%t.d1 -O2 -o %t.1 %s
// RUN: %clang_pgogen=%t.d1/%t.d2 -O2 -o %t.2 %s
//
// RUN: %run %t.0 ""
// RUN: env LLVM_PROFILE_FILE=%t.d1/default.profraw %run %t.0 %t.d1/
// RUN: env LLVM_PROFILE_FILE=%t.d1/%t.d2/default.profraw %run %t.0 %t.d1/%t.d2/
// RUN: %run %t.1 %t.d1/
// RUN: %run %t.2 %t.d1/%t.d2/
// RUN: %run %t.2 %t.d1/%t.d2/ %t.d1/%t.d2/%t.d3/blah.profraw %t.d1/%t.d2/%t.d3/
#include <string.h>
const char *__llvm_profile_get_path_prefix();
void __llvm_profile_set_filanem(const char*);
int main(int argc, const char *argv[]) {
int i;
const char *expected;
const char *prefix;
if (argc < 2)
return 1;
expected = argv[1];
prefix = __llvm_profile_get_path_prefix();
if (strcmp(prefix, expected))
return 1;
if (argc == 4) {
__llvm_profile_set_filename(argv[2]);
prefix = __llvm_profile_get_path_prefix();
expected = argv[3];
if (strcmp(prefix, expected))
return 1;
}
return 0;
}