diff options
author | Xinliang David Li <davidxl@google.com> | 2015-11-21 04:16:42 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2015-11-21 04:16:42 +0000 |
commit | dc716a3d5e88be416c636040b6cddd1ff553cae4 (patch) | |
tree | 02cad76c993b75b0320221759e330bcf9220261f /lib/profile | |
parent | 9e2ce4289a937dac250356814069a6a82ec97a49 (diff) |
[PGO] Implement a more robust/readable Writer callback interface
(patch suggested by silvas)
With this patch, the IO information is wrapped in struct
ProfDataIOVec, and interface of writerCallback takes a vector
of IOVec and a pointer to writer context pointer.
Differential Revision: http://reviews.llvm.org/D14859
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@253764 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile')
-rw-r--r-- | lib/profile/InstrProfilingBuffer.c | 23 | ||||
-rw-r--r-- | lib/profile/InstrProfilingFile.c | 17 | ||||
-rw-r--r-- | lib/profile/InstrProfilingInternal.h | 14 | ||||
-rw-r--r-- | lib/profile/InstrProfilingWriter.c | 34 |
4 files changed, 54 insertions, 34 deletions
diff --git a/lib/profile/InstrProfilingBuffer.c b/lib/profile/InstrProfilingBuffer.c index dc5958ea5..130b30e7a 100644 --- a/lib/profile/InstrProfilingBuffer.c +++ b/lib/profile/InstrProfilingBuffer.c @@ -41,24 +41,31 @@ uint64_t __llvm_profile_get_size_for_buffer_internal( PROFILE_RANGE_SIZE(Counters) * sizeof(uint64_t) + NamesSize + Padding; } -static size_t bufferWriter(const void *Data, size_t ElmSize, size_t NumElm, - void **Buffer) { - size_t Length = ElmSize * NumElm; - memcpy(*Buffer, Data, Length); - *(char **)Buffer += Length; - return NumElm; +/* The buffer writer is reponsponsible in keeping writer state + * across the call. + */ +static uint32_t bufferWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, + void **WriterCtx) { + uint32_t I; + char **Buffer = (char **)WriterCtx; + for (I = 0; I < NumIOVecs; I++) { + size_t Length = IOVecs[I].ElmSize * IOVecs[I].NumElm; + memcpy(*Buffer, IOVecs[I].Data, Length); + *Buffer += Length; + } + return 0; } __attribute__((visibility("hidden"))) int __llvm_profile_write_buffer(char *Buffer) { - return llvmWriteProfData(Buffer, bufferWriter, 0, 0); + return llvmWriteProfData(bufferWriter, Buffer, 0, 0); } __attribute__((visibility("hidden"))) int __llvm_profile_write_buffer_internal( char *Buffer, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) { - return llvmWriteProfDataImpl(Buffer, bufferWriter, DataBegin, DataEnd, + return llvmWriteProfDataImpl(bufferWriter, Buffer, DataBegin, DataEnd, CountersBegin, CountersEnd, 0, 0, NamesBegin, NamesEnd); } diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c index 37d37292d..742df21d9 100644 --- a/lib/profile/InstrProfilingFile.c +++ b/lib/profile/InstrProfilingFile.c @@ -17,17 +17,24 @@ #define UNCONST(ptr) ((void *)(uintptr_t)(ptr)) -static size_t fileWriter(const void *Data, size_t ElmSize, size_t NumElm, - void **File) { - return fwrite(Data, ElmSize, NumElm, (FILE *)*File); +/* Return 1 if there is an error, otherwise return 0. */ +static uint32_t fileWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, + void **WriterCtx) { + uint32_t I; + FILE *File = (FILE *)*WriterCtx; + for (I = 0; I < NumIOVecs; I++) { + if (fwrite(IOVecs[I].Data, IOVecs[I].ElmSize, IOVecs[I].NumElm, File) != + IOVecs[I].NumElm) + return 1; + } + return 0; } -uint8_t *ValueDataBegin = NULL; static int writeFile(FILE *File) { uint8_t *ValueDataBegin = NULL; const uint64_t ValueDataSize = __llvm_profile_gather_value_data(&ValueDataBegin); - int r = llvmWriteProfData(File, fileWriter, ValueDataBegin, ValueDataSize); + int r = llvmWriteProfData(fileWriter, File, ValueDataBegin, ValueDataSize); free(ValueDataBegin); return r; } diff --git a/lib/profile/InstrProfilingInternal.h b/lib/profile/InstrProfilingInternal.h index 518e6a320..e912ce850 100644 --- a/lib/profile/InstrProfilingInternal.h +++ b/lib/profile/InstrProfilingInternal.h @@ -41,12 +41,18 @@ int __llvm_profile_write_buffer_internal( /*! * This is an internal function not intended to be used externally. */ -typedef size_t (*WriterCallback)(const void *Data, size_t ElmS, size_t NumElm, - void **BufferOrFile); -int llvmWriteProfData(void *WriterCtx, WriterCallback Writer, +typedef struct ProfDataIOVec { + const char *Data; + size_t ElmSize; + size_t NumElm; +} ProfDataIOVec; + +typedef uint32_t (*WriterCallback)(ProfDataIOVec *, uint32_t NumIOVecs, + void **WriterCtx); +int llvmWriteProfData(WriterCallback Writer, void *WriterCtx, const uint8_t *ValueDataBegin, const uint64_t ValueDataSize); -int llvmWriteProfDataImpl(void *WriterCtx, WriterCallback Writer, +int llvmWriteProfDataImpl(WriterCallback Writer, void *WriterCtx, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, diff --git a/lib/profile/InstrProfilingWriter.c b/lib/profile/InstrProfilingWriter.c index 31d72bf44..af0afc85a 100644 --- a/lib/profile/InstrProfilingWriter.c +++ b/lib/profile/InstrProfilingWriter.c @@ -11,7 +11,7 @@ #include "InstrProfilingInternal.h" __attribute__((visibility("hidden"))) int -llvmWriteProfData(void *WriterCtx, WriterCallback Writer, +llvmWriteProfData(WriterCallback Writer, void *WriterCtx, const uint8_t *ValueDataBegin, const uint64_t ValueDataSize) { /* Match logic in __llvm_profile_write_buffer(). */ const __llvm_profile_data *DataBegin = __llvm_profile_begin_data(); @@ -20,13 +20,13 @@ llvmWriteProfData(void *WriterCtx, WriterCallback Writer, const uint64_t *CountersEnd = __llvm_profile_end_counters(); const char *NamesBegin = __llvm_profile_begin_names(); const char *NamesEnd = __llvm_profile_end_names(); - return llvmWriteProfDataImpl(WriterCtx, Writer, DataBegin, DataEnd, + return llvmWriteProfDataImpl(Writer, WriterCtx, DataBegin, DataEnd, CountersBegin, CountersEnd, ValueDataBegin, ValueDataSize, NamesBegin, NamesEnd); } __attribute__((visibility("hidden"))) int llvmWriteProfDataImpl( - void *WriterCtx, WriterCallback Writer, + WriterCallback Writer, void *WriterCtx, const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, const uint64_t *CountersEnd, const uint8_t *ValueDataBegin, const uint64_t ValueDataSize, @@ -58,19 +58,19 @@ __attribute__((visibility("hidden"))) int llvmWriteProfDataImpl( Header.ValueDataSize = ValueDataSize; Header.ValueDataDelta = (uintptr_t)ValueDataBegin; -/* Write the data. */ -#define CHECK_write(Data, Size, Length, BuffOrFile) \ - do { \ - if (Writer(Data, Size, Length, &BuffOrFile) != Length) \ - return -1; \ - } while (0) - CHECK_write(&Header, sizeof(__llvm_profile_header), 1, WriterCtx); - CHECK_write(DataBegin, sizeof(__llvm_profile_data), DataSize, WriterCtx); - CHECK_write(CountersBegin, sizeof(uint64_t), CountersSize, WriterCtx); - CHECK_write(NamesBegin, sizeof(char), NamesSize, WriterCtx); - CHECK_write(Zeroes, sizeof(char), Padding, WriterCtx); - if (ValueDataBegin) - CHECK_write(ValueDataBegin, sizeof(char), ValueDataSize, WriterCtx); -#undef CHECK_write + /* Write the data. */ + ProfDataIOVec IOVec[] = { + {(const char *)&Header, sizeof(__llvm_profile_header), 1}, + {(const char *)DataBegin, sizeof(__llvm_profile_data), DataSize}, + {(const char *)CountersBegin, sizeof(uint64_t), CountersSize}, + {(const char *)NamesBegin, sizeof(char), NamesSize}, + {(const char *)Zeroes, sizeof(char), Padding}}; + if (Writer(IOVec, sizeof(IOVec) / sizeof(ProfDataIOVec), &WriterCtx)) + return -1; + if (ValueDataBegin) { + ProfDataIOVec IOVec[1] = {{ValueDataBegin, sizeof(char), ValueDataSize}}; + if (Writer(IOVec, 1, &WriterCtx)) + return -1; + } return 0; } |