summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2016-03-03 18:54:46 +0000
committerXinliang David Li <davidxl@google.com>2016-03-03 18:54:46 +0000
commitb39df906a7c587a7709ed95b1708717a6446c388 (patch)
tree115f2c50ca9fe1eefd2faf04215d0361b4b89a01 /lib
parentece56f52345a0d53c440dda852e6e59ff7d4512b (diff)
[PGO] Add API for profile merge from buffer
Differential Revision: http://reviews.llvm.org/D17831 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@262644 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/profile/CMakeLists.txt2
-rw-r--r--lib/profile/InstrProfiling.h9
-rw-r--r--lib/profile/InstrProfilingInternal.h7
-rw-r--r--lib/profile/InstrProfilingMerge.c70
-rw-r--r--lib/profile/InstrProfilingMergeFile.c41
5 files changed, 128 insertions, 1 deletions
diff --git a/lib/profile/CMakeLists.txt b/lib/profile/CMakeLists.txt
index 17eb48a5b..0905ff3e6 100644
--- a/lib/profile/CMakeLists.txt
+++ b/lib/profile/CMakeLists.txt
@@ -30,6 +30,8 @@ set(PROFILE_SOURCES
InstrProfilingValue.c
InstrProfilingBuffer.c
InstrProfilingFile.c
+ InstrProfilingMerge.c
+ InstrProfilingMergeFile.c
InstrProfilingWriter.c
InstrProfilingPlatformDarwin.c
InstrProfilingPlatformLinux.c
diff --git a/lib/profile/InstrProfiling.h b/lib/profile/InstrProfiling.h
index fdb8a704f..fe6ec36e4 100644
--- a/lib/profile/InstrProfiling.h
+++ b/lib/profile/InstrProfiling.h
@@ -63,6 +63,15 @@ uint64_t *__llvm_profile_end_counters(void);
void __llvm_profile_reset_counters(void);
/*!
+ * \brief Read profile data form buffer and merge with
+ * in-process profile counters. The client is expected to
+ * have checked or already knows the profile data in the
+ * buffer matches the in-process counter structure before
+ * calling it.
+ */
+void __llvm_profile_merge_from_buffer(const char *Profile, uint64_t Size);
+
+/*!
* \brief Counts the number of times a target value is seen.
*
* Records the target value for the CounterIndex if not seen before. Otherwise,
diff --git a/lib/profile/InstrProfilingInternal.h b/lib/profile/InstrProfilingInternal.h
index 4aab78ea5..cd081ae3e 100644
--- a/lib/profile/InstrProfilingInternal.h
+++ b/lib/profile/InstrProfilingInternal.h
@@ -109,10 +109,15 @@ int llvmWriteProfDataImpl(WriterCallback Writer, void *WriterCtx,
struct ValueProfData **ValueDataBeginArray,
const uint64_t ValueDataSize, const char *NamesBegin,
const char *NamesEnd);
+/* Merge value profile data pointed to by SrcValueProfData into
+ * in-memory profile counters pointed by to DstData. */
+void mergeValueProfData(struct ValueProfData *SrcValueProfData,
+ __llvm_profile_data *DstData);
extern char *(*GetEnvHook)(const char *);
extern void (*FreeHook)(void *);
-extern void* (*CallocHook)(size_t, size_t);
+extern void *(*CallocHook)(size_t, size_t);
+extern void (*VPMergeHook)(struct ValueProfData *, __llvm_profile_data *);
extern uint32_t VPBufferSize;
#endif
diff --git a/lib/profile/InstrProfilingMerge.c b/lib/profile/InstrProfilingMerge.c
new file mode 100644
index 000000000..820efe357
--- /dev/null
+++ b/lib/profile/InstrProfilingMerge.c
@@ -0,0 +1,70 @@
+/*===- InstrProfilingMerge.c - Profile in-process Merging ---------------===*\
+|*
+|* The LLVM Compiler Infrastructure
+|*
+|* This file is distributed under the University of Illinois Open Source
+|* License. See LICENSE.TXT for details.
+|*
+|*===----------------------------------------------------------------------===*
+|* This file defines the API needed for in-process merging of profile data
+|* stored in memory buffer.
+\*===---------------------------------------------------------------------===*/
+
+#include "InstrProfiling.h"
+#include "InstrProfilingInternal.h"
+#include "InstrProfilingUtil.h"
+
+#define INSTR_PROF_VALUE_PROF_DATA
+#include "InstrProfData.inc"
+
+COMPILER_RT_WEAK void (*VPMergeHook)(ValueProfData *,
+ __llvm_profile_data *) = NULL;
+
+void __llvm_profile_merge_from_buffer(const char *ProfileData,
+ uint64_t ProfileSize) {
+ __llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData;
+ __llvm_profile_header *Header = (__llvm_profile_header *)ProfileData;
+ uint64_t *SrcCountersStart;
+ const char *SrcNameStart;
+ ValueProfData *SrcValueProfDataStart, *SrcValueProfData;
+
+ SrcDataStart =
+ (__llvm_profile_data *)(ProfileData + sizeof(__llvm_profile_header));
+ SrcDataEnd = SrcDataStart + Header->DataSize;
+ SrcCountersStart = (uint64_t *)SrcDataEnd;
+ SrcNameStart = (const char *)(SrcCountersStart + Header->CountersSize);
+ SrcValueProfDataStart =
+ (ValueProfData *)(SrcNameStart + Header->NamesSize +
+ __llvm_profile_get_num_padding_bytes(
+ Header->NamesSize));
+
+ for (SrcData = SrcDataStart,
+ DstData = (__llvm_profile_data *)__llvm_profile_begin_data(),
+ SrcValueProfData = SrcValueProfDataStart;
+ SrcData < SrcDataEnd; ++SrcData, ++DstData) {
+ uint64_t *SrcCounters;
+ uint64_t *DstCounters = (uint64_t *)DstData->CounterPtr;
+ unsigned I, NC, NVK = 0;
+
+ NC = SrcData->NumCounters;
+ SrcCounters = SrcCountersStart +
+ ((size_t)SrcData->CounterPtr - Header->CountersDelta) /
+ sizeof(uint64_t);
+ for (I = 0; I < NC; I++)
+ DstCounters[I] += SrcCounters[I];
+
+ /* Now merge value profile data. */
+ if (!VPMergeHook)
+ continue;
+
+ for (I = 0; I <= IPVK_Last; I++)
+ NVK += (SrcData->NumValueSites[I] != 0);
+
+ if (!NVK)
+ continue;
+
+ VPMergeHook(SrcValueProfData, DstData);
+ SrcValueProfData = (ValueProfData *)((char *)SrcValueProfData +
+ SrcValueProfData->TotalSize);
+ }
+}
diff --git a/lib/profile/InstrProfilingMergeFile.c b/lib/profile/InstrProfilingMergeFile.c
new file mode 100644
index 000000000..bfcca8fc9
--- /dev/null
+++ b/lib/profile/InstrProfilingMergeFile.c
@@ -0,0 +1,41 @@
+/*===- InstrProfilingMergeFile.c - Profile in-process Merging ------------===*\
+|*
+|* The LLVM Compiler Infrastructure
+|*
+|* This file is distributed under the University of Illinois Open Source
+|* License. See LICENSE.TXT for details.
+|*
+|*===----------------------------------------------------------------------===
+|* This file defines APIs needed to support in-process merging for profile data
+|* stored in files.
+\*===----------------------------------------------------------------------===*/
+
+#include "InstrProfiling.h"
+#include "InstrProfilingInternal.h"
+#include "InstrProfilingUtil.h"
+
+#define INSTR_PROF_VALUE_PROF_DATA
+#include "InstrProfData.inc"
+
+void (*VPMergeHook)(ValueProfData *,
+ __llvm_profile_data *) = &mergeValueProfData;
+
+/* Merge value profile data pointed to by SrcValueProfData into
+ * in-memory profile counters pointed by to DstData. */
+void mergeValueProfData(ValueProfData *SrcValueProfData,
+ __llvm_profile_data *DstData) {
+ unsigned I, S, V, C;
+ InstrProfValueData *VData;
+ ValueProfRecord *VR = getFirstValueProfRecord(SrcValueProfData);
+ for (I = 0; I < SrcValueProfData->NumValueKinds; I++) {
+ VData = getValueProfRecordValueData(VR);
+ for (S = 0; S < VR->NumValueSites; S++) {
+ uint8_t NV = VR->SiteCountArray[S];
+ for (V = 0; V < NV; V++) {
+ for (C = 0; C < VData[V].Count; C++)
+ __llvm_profile_instrument_target(VData[V].Value, DstData, S);
+ }
+ }
+ VR = getValueProfRecordNext(VR);
+ }
+}