diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h --- a/compiler-rt/lib/profile/InstrProfiling.h +++ b/compiler-rt/lib/profile/InstrProfiling.h @@ -10,6 +10,7 @@ #define PROFILE_INSTRPROFILING_H_ #include "InstrProfilingPort.h" +#include #define INSTR_PROF_VISIBILITY COMPILER_RT_VISIBILITY #include "InstrProfData.inc" @@ -125,7 +126,7 @@ /*! * \brief this is a wrapper interface to \c __llvm_profile_write_file. * After this interface is invoked, a arleady dumped flag will be set - * so that profile won't be dumped again during program exit. + * so that profile won't be dumped again during program exit. * Invocation of interface __llvm_profile_reset_counters will clear * the flag. This interface is designed to be used to collect profile * data from user selected hot regions. The use model is @@ -157,6 +158,8 @@ */ void __llvm_profile_set_filename(const char *Name); +void __llvm_profile_set_file_object(FILE *File); + /*! \brief Register to write instrumentation data to file at exit. */ int __llvm_profile_register_write_file_atexit(void); diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -37,7 +37,7 @@ /* From where is profile name specified. * The order the enumerators define their * precedence. Re-order them may lead to - * runtime behavior change. */ + * runtime behavior change. */ typedef enum ProfileNameSpecifier { PNS_unknown = 0, PNS_default, @@ -89,6 +89,17 @@ COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, 0, {0}, {0}, 0, 0, 0, PNS_unknown}; +static FILE *ProfileFile = NULL; +COMPILER_RT_VISIBILITY FILE *lprofGetProfileFile() { return ProfileFile; } + +COMPILER_RT_VISIBILITY void lprofSetProfileFile(FILE *File) { + ProfileFile = File; +} + +COMPILER_RT_VISIBILITY void __llvm_profile_set_file_object(FILE *File) { + lprofSetProfileFile(File); +} + static int getCurFilenameLength(); static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf); static unsigned doMerging() { return lprofCurFilename.MergePoolSize; } @@ -248,10 +259,14 @@ static int writeFile(const char *OutputName) { int RetVal; FILE *OutputFile; + FILE *ProfileFilePtr; int MergeDone = 0; VPMergeHook = &lprofMergeValueProfData; - if (!doMerging()) + ProfileFilePtr = lprofGetProfileFile(); + if (ProfileFilePtr != NULL) + OutputFile = ProfileFilePtr; + else if (!doMerging()) OutputFile = fopen(OutputName, "ab"); else OutputFile = openFileForMerging(OutputName, &MergeDone); @@ -591,7 +606,7 @@ EnvFilenamePat = getFilenamePatFromEnv(); if (EnvFilenamePat) { - /* Pass CopyFilenamePat = 1, to ensure that the filename would be valid + /* Pass CopyFilenamePat = 1, to ensure that the filename would be valid at the moment when __llvm_profile_write_file() gets executed. */ parseAndSetFilename(EnvFilenamePat, PNS_environment, 1); return; @@ -627,8 +642,7 @@ int PDeathSig = 0; if (lprofProfileDumped()) { - PROF_NOTE("Profile data not written to file: %s.\n", - "already written"); + PROF_NOTE("Profile data not written to file: %s.\n", "already written"); return 0; }