summaryrefslogtreecommitdiff
path: root/lib/profile/InstrProfilingWriter.c
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2015-12-29 23:54:41 +0000
committerXinliang David Li <davidxl@google.com>2015-12-29 23:54:41 +0000
commit57de7fe3f0e83ea62c48e0a68f3e27e03dfa70fe (patch)
tree5558c8f462ca1eb2b7cc1c06e6673786ba963060 /lib/profile/InstrProfilingWriter.c
parentebd2b830835c3d06e12cbd9c630a9c0507a5fadc (diff)
downloadcompiler-rt-57de7fe3f0e83ea62c48e0a68f3e27e03dfa70fe.tar.gz
[PGO]: Refactor VP data writer
Extract the buffered filer writer code used by value profile writer and turn it into common/sharable buffered fileIO interfaces. Added a test case for the buffered file writer and rewrite the VP dumping using the new APIs. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@256604 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile/InstrProfilingWriter.c')
-rw-r--r--lib/profile/InstrProfilingWriter.c116
1 files changed, 69 insertions, 47 deletions
diff --git a/lib/profile/InstrProfilingWriter.c b/lib/profile/InstrProfilingWriter.c
index 6153a0050..a07bc538e 100644
--- a/lib/profile/InstrProfilingWriter.c
+++ b/lib/profile/InstrProfilingWriter.c
@@ -33,6 +33,64 @@ COMPILER_RT_VISIBILITY uint32_t llvmBufferWriter(ProfDataIOVec *IOVecs,
return 0;
}
+static void llvmInitBufferIO(ProfBufferIO *BufferIO, WriterCallback FileWriter,
+ void *File, uint8_t *Buffer, uint32_t BufferSz) {
+ BufferIO->File = File;
+ BufferIO->FileWriter = FileWriter;
+ BufferIO->BufferStart = Buffer;
+ BufferIO->BufferSz = BufferSz;
+ BufferIO->CurOffset = 0;
+}
+
+COMPILER_RT_VISIBILITY ProfBufferIO *
+llvmCreateBufferIO(WriterCallback FileWriter, void *File, uint32_t BufferSz) {
+ ProfBufferIO *BufferIO = (ProfBufferIO *)CallocHook(1, sizeof(ProfBufferIO));
+ uint8_t *Buffer = (uint8_t *)CallocHook(1, BufferSz);
+ if (!Buffer) {
+ FreeHook(BufferIO);
+ return 0;
+ }
+ llvmInitBufferIO(BufferIO, FileWriter, File, Buffer, BufferSz);
+ return BufferIO;
+}
+
+COMPILER_RT_VISIBILITY void llvmDeleteBufferIO(ProfBufferIO *BufferIO) {
+ FreeHook(BufferIO->BufferStart);
+ FreeHook(BufferIO);
+}
+
+COMPILER_RT_VISIBILITY int
+llvmBufferIOWrite(ProfBufferIO *BufferIO, const uint8_t *Data, uint32_t Size) {
+ /* Buffer is not large enough, it is time to flush. */
+ if (Size + BufferIO->CurOffset > BufferIO->BufferSz) {
+ if (llvmBufferIOFlush(BufferIO) != 0)
+ return -1;
+ }
+ /* Special case, bypass the buffer completely. */
+ ProfDataIOVec IO[] = {{Data, sizeof(uint8_t), Size}};
+ if (Size > BufferIO->BufferSz) {
+ if (BufferIO->FileWriter(IO, 1, &BufferIO->File))
+ return -1;
+ } else {
+ /* Write the data to buffer */
+ uint8_t *Buffer = BufferIO->BufferStart + BufferIO->CurOffset;
+ llvmBufferWriter(IO, 1, (void **)&Buffer);
+ BufferIO->CurOffset = Buffer - BufferIO->BufferStart;
+ }
+ return 0;
+}
+
+COMPILER_RT_VISIBILITY int llvmBufferIOFlush(ProfBufferIO *BufferIO) {
+ if (BufferIO->CurOffset) {
+ ProfDataIOVec IO[] = {
+ {BufferIO->BufferStart, sizeof(uint8_t), BufferIO->CurOffset}};
+ if (BufferIO->FileWriter(IO, 1, &BufferIO->File))
+ return -1;
+ BufferIO->CurOffset = 0;
+ }
+ return 0;
+}
+
COMPILER_RT_VISIBILITY int llvmWriteProfData(WriterCallback Writer,
void *WriterCtx,
ValueProfData **ValueDataArray,
@@ -53,64 +111,28 @@ COMPILER_RT_VISIBILITY int llvmWriteProfData(WriterCallback Writer,
static int writeValueProfData(WriterCallback Writer, void *WriterCtx,
ValueProfData **ValueDataBegin,
uint64_t NumVData) {
- ValueProfData **ValueDataArray = ValueDataBegin;
- char *BufferStart = 0, *Buffer;
- ValueProfData *CurVData;
+ ProfBufferIO *BufferIO;
uint32_t I = 0, BufferSz;
if (!ValueDataBegin)
return 0;
BufferSz = VPBufferSize ? VPBufferSize : VP_BUFFER_SIZE;
- BufferStart = (char *)CallocHook(BufferSz, sizeof(uint8_t));
- if (!BufferStart)
- return -1;
+ BufferIO = llvmCreateBufferIO(Writer, WriterCtx, BufferSz);
- uint32_t WriteSize = 0;
- Buffer = BufferStart;
- do {
- CurVData = ValueDataArray[I];
- if (!CurVData) {
- I++;
+ for (I = 0; I < NumVData; I++) {
+ ValueProfData *CurVData = ValueDataBegin[I];
+ if (!CurVData)
continue;
- }
-
- /* Buffer is full or not large enough, it is time to flush. */
- if (CurVData->TotalSize + WriteSize > BufferSz) {
- if (WriteSize) {
- ProfDataIOVec IO[] = {{BufferStart, sizeof(uint8_t), WriteSize}};
- if (Writer(IO, 1, &WriterCtx))
- return -1;
- WriteSize = 0;
- Buffer = BufferStart;
- }
- /* Special case, bypass the buffer completely. */
- if (CurVData->TotalSize > BufferSz) {
- ProfDataIOVec IO[] = {{CurVData, sizeof(uint8_t), CurVData->TotalSize}};
- if (Writer(IO, 1, &WriterCtx))
- return -1;
- FreeHook(ValueDataArray[I]);
- I++;
- }
- } else {
- /* Write the data to buffer */
- ProfDataIOVec IO[] = {{CurVData, sizeof(uint8_t), CurVData->TotalSize}};
- llvmBufferWriter(IO, 1, (void **)&Buffer);
- WriteSize += CurVData->TotalSize;
- FreeHook(ValueDataArray[I]);
- I++;
- }
- } while (I < NumVData);
-
- /* Final flush. */
- if (WriteSize) {
- ProfDataIOVec IO[] = {{BufferStart, sizeof(uint8_t), WriteSize}};
- if (Writer(IO, 1, &WriterCtx))
+ if (llvmBufferIOWrite(BufferIO, (const uint8_t *)CurVData,
+ CurVData->TotalSize) != 0)
return -1;
}
- FreeHook(ValueDataBegin);
- FreeHook(BufferStart);
+ if (llvmBufferIOFlush(BufferIO) != 0)
+ return -1;
+ llvmDeleteBufferIO(BufferIO);
+
return 0;
}