Author: Vedant Kumar Date: 2020-09-25T09:39:40-07:00 New Revision: 62c372770d2e87f3e882a20d43c6814e6c4fe0f5
URL: https://github.com/llvm/llvm-project/commit/62c372770d2e87f3e882a20d43c6814e6c4fe0f5 DIFF: https://github.com/llvm/llvm-project/commit/62c372770d2e87f3e882a20d43c6814e6c4fe0f5.diff LOG: [profile] Add %t LLVM_PROFILE_FILE option to substitute $TMPDIR Add support for expanding the %t filename specifier in LLVM_PROFILE_FILE to the TMPDIR environment variable. This is supported on all platforms. On Darwin, TMPDIR is used to specify a temporary application-specific scratch directory. When testing apps on remote devices, it can be challenging for the host device to determine the correct TMPDIR, so it's helpful to have the runtime do this work. rdar://68524185 Differential Revision: https://reviews.llvm.org/D87332 Added: compiler-rt/test/profile/instrprof-tmpdir.c Modified: clang/docs/SourceBasedCodeCoverage.rst compiler-rt/lib/profile/InstrProfilingFile.c Removed: ################################################################################ diff --git a/clang/docs/SourceBasedCodeCoverage.rst b/clang/docs/SourceBasedCodeCoverage.rst index 0e9c364fbf6b..f5b3d05262e9 100644 --- a/clang/docs/SourceBasedCodeCoverage.rst +++ b/clang/docs/SourceBasedCodeCoverage.rst @@ -79,6 +79,9 @@ directory structure will be created. Additionally, the following special * "%h" expands out to the hostname of the machine running the program. +* "%t" expands out to the value of the ``TMPDIR`` environment variable. On + Darwin, this is typically set to a temporary scratch directory. + * "%Nm" expands out to the instrumented binary's signature. When this pattern is specified, the runtime creates a pool of N raw profiles which are used for on-line profile merging. The runtime takes care of selecting a raw profile diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index 8c7bb0c25de1..b43f91794e28 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -72,6 +72,7 @@ typedef struct lprofFilename { unsigned OwnsFilenamePat; const char *ProfilePathPrefix; char PidChars[MAX_PID_SIZE]; + char *TmpDir; char Hostname[COMPILER_RT_MAX_HOSTLEN]; unsigned NumPids; unsigned NumHosts; @@ -86,8 +87,8 @@ typedef struct lprofFilename { ProfileNameSpecifier PNS; } lprofFilename; -static lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0}, - 0, 0, 0, PNS_unknown}; +static lprofFilename lprofCurFilename = {0, 0, 0, {0}, NULL, + {0}, 0, 0, 0, PNS_unknown}; static int ProfileMergeRequested = 0; static int isProfileMergeRequested() { return ProfileMergeRequested; } @@ -744,6 +745,14 @@ static int parseFilenamePattern(const char *FilenamePat, FilenamePat); return -1; } + } else if (FilenamePat[I] == 't') { + lprofCurFilename.TmpDir = getenv("TMPDIR"); + if (!lprofCurFilename.TmpDir) { + PROF_WARN("Unable to get the TMPDIR environment variable, referenced " + "in %s. Using the default path.", + FilenamePat); + return -1; + } } else if (FilenamePat[I] == 'c') { if (__llvm_profile_is_continuous_mode_enabled()) { PROF_WARN("%%c specifier can only be specified once in %s.\n", @@ -827,12 +836,13 @@ static int getCurFilenameLength() { return 0; if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts || - lprofCurFilename.MergePoolSize)) + lprofCurFilename.TmpDir || lprofCurFilename.MergePoolSize)) return strlen(lprofCurFilename.FilenamePat); Len = strlen(lprofCurFilename.FilenamePat) + lprofCurFilename.NumPids * (strlen(lprofCurFilename.PidChars) - 2) + - lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2); + lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2) + + (lprofCurFilename.TmpDir ? (strlen(lprofCurFilename.TmpDir) - 1) : 0); if (lprofCurFilename.MergePoolSize) Len += SIGLEN; return Len; @@ -844,14 +854,14 @@ static int getCurFilenameLength() { * current filename pattern string is directly returned, unless ForceUseBuf * is enabled. */ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { - int I, J, PidLength, HostNameLength, FilenamePatLength; + int I, J, PidLength, HostNameLength, TmpDirLength, FilenamePatLength; const char *FilenamePat = lprofCurFilename.FilenamePat; if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0]) return 0; if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts || - lprofCurFilename.MergePoolSize || + lprofCurFilename.TmpDir || lprofCurFilename.MergePoolSize || __llvm_profile_is_continuous_mode_enabled())) { if (!ForceUseBuf) return lprofCurFilename.FilenamePat; @@ -864,6 +874,7 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { PidLength = strlen(lprofCurFilename.PidChars); HostNameLength = strlen(lprofCurFilename.Hostname); + TmpDirLength = lprofCurFilename.TmpDir ? strlen(lprofCurFilename.TmpDir) : 0; /* Construct the new filename. */ for (I = 0, J = 0; FilenamePat[I]; ++I) if (FilenamePat[I] == '%') { @@ -873,6 +884,10 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { } else if (FilenamePat[I] == 'h') { memcpy(FilenameBuf + J, lprofCurFilename.Hostname, HostNameLength); J += HostNameLength; + } else if (FilenamePat[I] == 't') { + memcpy(FilenameBuf + J, lprofCurFilename.TmpDir, TmpDirLength); + FilenameBuf[J + TmpDirLength] = DIR_SEPARATOR; + J += TmpDirLength + 1; } else { if (!getMergePoolSize(FilenamePat, &I)) continue; diff --git a/compiler-rt/test/profile/instrprof-tmpdir.c b/compiler-rt/test/profile/instrprof-tmpdir.c new file mode 100644 index 000000000000..036313850ed6 --- /dev/null +++ b/compiler-rt/test/profile/instrprof-tmpdir.c @@ -0,0 +1,22 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: cd %t +// RUN: %clang_profgen -o %t/binary %s +// +// Check that a dir separator is appended after %t is subsituted. +// RUN: env TMPDIR="%t" LLVM_PROFILE_FILE="%%traw1.profraw" %run ./binary +// RUN: llvm-profdata show ./raw1.profraw | FileCheck %s -check-prefix TMPDIR +// +// Check that substitution works even if a redundant dir separator is added. +// RUN: env TMPDIR="%t" LLVM_PROFILE_FILE="%%t/raw2.profraw" %run ./binary +// RUN: llvm-profdata show ./raw2.profraw | FileCheck %s -check-prefix TMPDIR +// +// Check that we fall back to the default path if TMPDIR is missing. +// RUN: env -u TMPDIR LLVM_PROFILE_FILE="%%t/raw3.profraw" %run ./binary 2>&1 | FileCheck %s -check-prefix MISSING +// RUN: llvm-profdata show ./default.profraw | FileCheck %s -check-prefix TMPDIR + +// TMPDIR: Maximum function count: 1 + +// MISSING: Unable to get the TMPDIR environment variable, referenced in {{.*}}raw3.profraw. Using the default path. + +int main() { return 0; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits