summaryrefslogtreecommitdiff
path: root/lib/profile
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2015-11-21 04:16:42 +0000
committerXinliang David Li <davidxl@google.com>2015-11-21 04:16:42 +0000
commitdc716a3d5e88be416c636040b6cddd1ff553cae4 (patch)
tree02cad76c993b75b0320221759e330bcf9220261f /lib/profile
parent9e2ce4289a937dac250356814069a6a82ec97a49 (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.c23
-rw-r--r--lib/profile/InstrProfilingFile.c17
-rw-r--r--lib/profile/InstrProfilingInternal.h14
-rw-r--r--lib/profile/InstrProfilingWriter.c34
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;
}