summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2017-06-28 16:46:06 +0000
committerXinliang David Li <davidxl@google.com>2017-06-28 16:46:06 +0000
commit59b78d964b68f9e8c4fe540e759ead35dc35e240 (patch)
treef93415824c26c221830f550eb4c3fefdfcd01d50
parent8ec8c48d6b22265de20c6d0d5f2e047946c7fd58 (diff)
[PGO] Reduce IO in profile dumping with merging
Differential Revision: http://reviews.llvm.org/D34709 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@306561 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/profile/InstrProfilingBuffer.c4
-rw-r--r--lib/profile/InstrProfilingFile.c30
-rw-r--r--lib/profile/InstrProfilingInternal.h8
-rw-r--r--lib/profile/InstrProfilingWriter.c22
4 files changed, 39 insertions, 25 deletions
diff --git a/lib/profile/InstrProfilingBuffer.c b/lib/profile/InstrProfilingBuffer.c
index 548f92205..a7e852f53 100644
--- a/lib/profile/InstrProfilingBuffer.c
+++ b/lib/profile/InstrProfilingBuffer.c
@@ -54,7 +54,7 @@ void initBufferWriter(ProfDataWriter *BufferWriter, char *Buffer) {
COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer(char *Buffer) {
ProfDataWriter BufferWriter;
initBufferWriter(&BufferWriter, Buffer);
- return lprofWriteData(&BufferWriter, 0);
+ return lprofWriteData(&BufferWriter, 0, 0);
}
COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
@@ -64,5 +64,5 @@ COMPILER_RT_VISIBILITY int __llvm_profile_write_buffer_internal(
ProfDataWriter BufferWriter;
initBufferWriter(&BufferWriter, Buffer);
return lprofWriteDataImpl(&BufferWriter, DataBegin, DataEnd, CountersBegin,
- CountersEnd, 0, NamesBegin, NamesEnd);
+ CountersEnd, 0, NamesBegin, NamesEnd, 0);
}
diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c
index f99f86d89..d038bb9cb 100644
--- a/lib/profile/InstrProfilingFile.c
+++ b/lib/profile/InstrProfilingFile.c
@@ -93,13 +93,17 @@ static unsigned doMerging() { return lprofCurFilename.MergePoolSize; }
/* Return 1 if there is an error, otherwise return 0. */
static uint32_t fileWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
uint32_t NumIOVecs) {
-
uint32_t I;
FILE *File = (FILE *)This->WriterCtx;
for (I = 0; I < NumIOVecs; I++) {
- if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) !=
- IOVecs[I].NumElm)
- return 1;
+ if (IOVecs[I].Data) {
+ if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) !=
+ IOVecs[I].NumElm)
+ return 1;
+ } else {
+ if (fseek(File, IOVecs[I].ElmSize * IOVecs[I].NumElm, SEEK_CUR) == -1)
+ return 1;
+ }
}
return 0;
}
@@ -133,9 +137,10 @@ static void setupIOBuffer() {
/* Read profile data in \c ProfileFile and merge with in-memory
profile counters. Returns -1 if there is fatal error, otheriwse
- 0 is returned.
+ 0 is returned. Returning 0 does not mean merge is actually
+ performed. If merge is actually done, *MergeDone is set to 1.
*/
-static int doProfileMerging(FILE *ProfileFile) {
+static int doProfileMerging(FILE *ProfileFile, int *MergeDone) {
uint64_t ProfileFileSize;
char *ProfileBuffer;
@@ -180,6 +185,8 @@ static int doProfileMerging(FILE *ProfileFile) {
__llvm_profile_merge_from_buffer(ProfileBuffer, ProfileFileSize);
(void)munmap(ProfileBuffer, ProfileFileSize);
+ *MergeDone = 1;
+
return 0;
}
@@ -201,7 +208,7 @@ static void createProfileDir(const char *Filename) {
* dumper. With profile merging enabled, each executable as well as any of
* its instrumented shared libraries dump profile data into their own data file.
*/
-static FILE *openFileForMerging(const char *ProfileFileName) {
+static FILE *openFileForMerging(const char *ProfileFileName, int *MergeDone) {
FILE *ProfileFile;
int rc;
@@ -210,8 +217,8 @@ static FILE *openFileForMerging(const char *ProfileFileName) {
if (!ProfileFile)
return NULL;
- rc = doProfileMerging(ProfileFile);
- if (rc || COMPILER_RT_FTRUNCATE(ProfileFile, 0L) ||
+ rc = doProfileMerging(ProfileFile, MergeDone);
+ if (rc || (!*MergeDone && COMPILER_RT_FTRUNCATE(ProfileFile, 0L)) ||
fseek(ProfileFile, 0L, SEEK_SET) == -1) {
PROF_ERR("Profile Merging of file %s failed: %s\n", ProfileFileName,
strerror(errno));
@@ -226,10 +233,11 @@ static int writeFile(const char *OutputName) {
int RetVal;
FILE *OutputFile;
+ int MergeDone = 0;
if (!doMerging())
OutputFile = fopen(OutputName, "ab");
else
- OutputFile = openFileForMerging(OutputName);
+ OutputFile = openFileForMerging(OutputName, &MergeDone);
if (!OutputFile)
return -1;
@@ -238,7 +246,7 @@ static int writeFile(const char *OutputName) {
setupIOBuffer();
ProfDataWriter fileWriter;
initFileWriter(&fileWriter, OutputFile);
- RetVal = lprofWriteData(&fileWriter, lprofGetVPDataReader());
+ RetVal = lprofWriteData(&fileWriter, lprofGetVPDataReader(), MergeDone);
fclose(OutputFile);
return RetVal;
diff --git a/lib/profile/InstrProfilingInternal.h b/lib/profile/InstrProfilingInternal.h
index ee710722a..36490ef7d 100644
--- a/lib/profile/InstrProfilingInternal.h
+++ b/lib/profile/InstrProfilingInternal.h
@@ -102,7 +102,6 @@ int lprofBufferIOFlush(ProfBufferIO *BufferIO);
* and profile data writer. */
uint32_t lprofBufferWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
uint32_t NumIOVecs);
-
void initBufferWriter(ProfDataWriter *BufferWriter, char *Buffer);
struct ValueProfData;
@@ -139,14 +138,17 @@ typedef struct VPDataReaderType {
uint32_t N);
} VPDataReaderType;
-int lprofWriteData(ProfDataWriter *Writer, VPDataReaderType *VPDataReader);
+/* Write profile data to destinitation. If SkipNameDataWrite is set to 1,
+ the name data is already in destintation, we just skip over it. */
+int lprofWriteData(ProfDataWriter *Writer, VPDataReaderType *VPDataReader,
+ int SkipNameDataWrite);
int lprofWriteDataImpl(ProfDataWriter *Writer,
const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd,
const uint64_t *CountersBegin,
const uint64_t *CountersEnd,
VPDataReaderType *VPDataReader, const char *NamesBegin,
- const char *NamesEnd);
+ const char *NamesEnd, int SkipNameDataWrite);
/* Merge value profile data pointed to by SrcValueProfData into
* in-memory profile counters pointed by to DstData. */
diff --git a/lib/profile/InstrProfilingWriter.c b/lib/profile/InstrProfilingWriter.c
index b6cefe049..d4c9b9bd6 100644
--- a/lib/profile/InstrProfilingWriter.c
+++ b/lib/profile/InstrProfilingWriter.c
@@ -38,7 +38,8 @@ COMPILER_RT_VISIBILITY uint32_t lprofBufferWriter(ProfDataWriter *This,
char **Buffer = (char **)&This->WriterCtx;
for (I = 0; I < NumIOVecs; I++) {
size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm;
- memcpy(*Buffer, IOVecs[I].Data, Length);
+ if (IOVecs[I].Data)
+ memcpy(*Buffer, IOVecs[I].Data, Length);
*Buffer += Length;
}
return 0;
@@ -231,7 +232,8 @@ static int writeValueProfData(ProfDataWriter *Writer,
}
COMPILER_RT_VISIBILITY int lprofWriteData(ProfDataWriter *Writer,
- VPDataReaderType *VPDataReader) {
+ VPDataReaderType *VPDataReader,
+ int SkipNameDataWrite) {
/* Match logic in __llvm_profile_write_buffer(). */
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
@@ -240,7 +242,8 @@ COMPILER_RT_VISIBILITY int lprofWriteData(ProfDataWriter *Writer,
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
return lprofWriteDataImpl(Writer, DataBegin, DataEnd, CountersBegin,
- CountersEnd, VPDataReader, NamesBegin, NamesEnd);
+ CountersEnd, VPDataReader, NamesBegin, NamesEnd,
+ SkipNameDataWrite);
}
COMPILER_RT_VISIBILITY int
@@ -248,7 +251,7 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd,
const uint64_t *CountersBegin, const uint64_t *CountersEnd,
VPDataReaderType *VPDataReader, const char *NamesBegin,
- const char *NamesEnd) {
+ const char *NamesEnd, int SkipNameDataWrite) {
/* Calculate size of sections. */
const uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
@@ -270,11 +273,12 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
#include "InstrProfData.inc"
/* Write the data. */
- ProfDataIOVec IOVec[] = {{&Header, sizeof(__llvm_profile_header), 1},
- {DataBegin, sizeof(__llvm_profile_data), DataSize},
- {CountersBegin, sizeof(uint64_t), CountersSize},
- {NamesBegin, sizeof(uint8_t), NamesSize},
- {Zeroes, sizeof(uint8_t), Padding}};
+ ProfDataIOVec IOVec[] = {
+ {&Header, sizeof(__llvm_profile_header), 1},
+ {DataBegin, sizeof(__llvm_profile_data), DataSize},
+ {CountersBegin, sizeof(uint64_t), CountersSize},
+ {SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize},
+ {Zeroes, sizeof(uint8_t), Padding}};
if (Writer->Write(Writer, IOVec, sizeof(IOVec) / sizeof(*IOVec)))
return -1;