summaryrefslogtreecommitdiff
path: root/lib/profile/InstrProfilingFile.c
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2016-06-10 20:35:01 +0000
committerXinliang David Li <davidxl@google.com>2016-06-10 20:35:01 +0000
commit98339b23fb3ea2257076fe125cb7189a1498b0b2 (patch)
treef3ffd3e3ab68a8a53b3b5ee93b4bcc7b2fadcef9 /lib/profile/InstrProfilingFile.c
parent91c5e0ee10290fafc3420a4af7132ec92e8709c5 (diff)
[profile] cleanup file setting code
Differential Revision: http://reviews.llvm.org/D21219 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@272428 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile/InstrProfilingFile.c')
-rw-r--r--lib/profile/InstrProfilingFile.c88
1 files changed, 68 insertions, 20 deletions
diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c
index 880059a99..a7ec7a044 100644
--- a/lib/profile/InstrProfilingFile.c
+++ b/lib/profile/InstrProfilingFile.c
@@ -31,6 +31,33 @@
#endif
#endif
+/* From where is profile name specified.
+ * The order the enumerators define their
+ * precedence. Re-order them may lead to
+ * runtime behavior change. */
+typedef enum ProfileNameSpecifier {
+ PNS_unknown = 0,
+ PNS_default,
+ PNS_command_line,
+ PNS_environment,
+ PNS_runtime_api
+} ProfileNameSpecifier;
+
+static const char *getPNSStr(ProfileNameSpecifier PNS) {
+ switch (PNS) {
+ case PNS_default:
+ return "default setting";
+ case PNS_command_line:
+ return "command line";
+ case PNS_environment:
+ return "environment variable";
+ case PNS_runtime_api:
+ return "runtime API";
+ default:
+ return "Unknown";
+ }
+}
+
#define MAX_PID_SIZE 16
/* Data structure holding the result of parsed filename pattern. */
typedef struct lprofFilename {
@@ -48,9 +75,10 @@ typedef struct lprofFilename {
* 2 profile data files. %1m is equivalent to %m. Also %m specifier
* can only appear once at the end of the name pattern. */
unsigned MergePoolSize;
+ ProfileNameSpecifier PNS;
} lprofFilename;
-lprofFilename lprofCurFilename = {0, {0}, {0}, 0, 0, 0};
+lprofFilename lprofCurFilename = {0, {0}, {0}, 0, 0, 0, PNS_unknown};
int getpid(void);
static int getCurFilenameLength();
@@ -214,9 +242,11 @@ static void truncateCurrentFile(void) {
fclose(File);
}
+static const char *DefaultProfileName = "default.profraw";
static void resetFilenameToDefault(void) {
memset(&lprofCurFilename, 0, sizeof(lprofCurFilename));
- lprofCurFilename.FilenamePat = "default.profraw";
+ lprofCurFilename.FilenamePat = DefaultProfileName;
+ lprofCurFilename.PNS = PNS_default;
}
static int containsMergeSpecifier(const char *FilenamePat, int I) {
@@ -278,17 +308,44 @@ static int parseFilenamePattern(const char *FilenamePat) {
return 0;
}
-static void parseAndSetFilename(const char *FilenamePat) {
- int NewFile;
+static void parseAndSetFilename(const char *FilenamePat,
+ ProfileNameSpecifier PNS) {
+
const char *OldFilenamePat = lprofCurFilename.FilenamePat;
+ ProfileNameSpecifier OldPNS = lprofCurFilename.PNS;
+
+ if (PNS < OldPNS)
+ return;
+
+ if (!FilenamePat)
+ FilenamePat = DefaultProfileName;
+
+ /* When -fprofile-instr-generate=<path> is specified on the
+ * command line, each module will be instrumented with runtime
+ * init call to __llvm_profile_init function which calls
+ * __llvm_profile_override_default_filename. In most of the cases,
+ * the path will be identical, so bypass the parsing completely.
+ */
+ if (OldFilenamePat && !strcmp(OldFilenamePat, FilenamePat)) {
+ lprofCurFilename.PNS = PNS;
+ return;
+ }
+ /* When PNS >= OldPNS, the last one wins. */
if (!FilenamePat || parseFilenamePattern(FilenamePat))
resetFilenameToDefault();
+ lprofCurFilename.PNS = PNS;
+
+ if (!OldFilenamePat) {
+ PROF_NOTE("Set profile file path to \"%s\" via %s.\n",
+ lprofCurFilename.FilenamePat, getPNSStr(PNS));
+ } else {
+ PROF_NOTE("Override old profile path \"%s\" via %s to \"%s\" via %s.\n",
+ OldFilenamePat, getPNSStr(OldPNS), lprofCurFilename.FilenamePat,
+ getPNSStr(PNS));
+ }
- NewFile =
- !OldFilenamePat || (strcmp(OldFilenamePat, lprofCurFilename.FilenamePat));
-
- if (NewFile && !lprofCurFilename.MergePoolSize)
+ if (!lprofCurFilename.MergePoolSize)
truncateCurrentFile();
}
@@ -376,13 +433,9 @@ static const char *getFilenamePatFromEnv(void) {
COMPILER_RT_VISIBILITY
void __llvm_profile_initialize_file(void) {
const char *FilenamePat;
- /* Check if the filename has been initialized. */
- if (lprofCurFilename.FilenamePat)
- return;
- /* Detect the filename and truncate. */
FilenamePat = getFilenamePatFromEnv();
- parseAndSetFilename(FilenamePat);
+ parseAndSetFilename(FilenamePat, FilenamePat ? PNS_environment : PNS_default);
}
/* This API is directly called by the user application code. It has the
@@ -391,7 +444,7 @@ void __llvm_profile_initialize_file(void) {
*/
COMPILER_RT_VISIBILITY
void __llvm_profile_set_filename(const char *FilenamePat) {
- parseAndSetFilename(FilenamePat);
+ parseAndSetFilename(FilenamePat, PNS_runtime_api);
}
/*
@@ -402,12 +455,7 @@ void __llvm_profile_set_filename(const char *FilenamePat) {
*/
COMPILER_RT_VISIBILITY
void __llvm_profile_override_default_filename(const char *FilenamePat) {
- /* If the env var is set, skip setting filename from argument. */
- const char *Env_Filename = getFilenamePatFromEnv();
- if (Env_Filename)
- return;
-
- parseAndSetFilename(FilenamePat);
+ parseAndSetFilename(FilenamePat, PNS_command_line);
}
/* The public API for writing profile data into the file with name