diff options
author | Xinliang David Li <davidxl@google.com> | 2016-03-03 18:54:46 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2016-03-03 18:54:46 +0000 |
commit | b39df906a7c587a7709ed95b1708717a6446c388 (patch) | |
tree | 115f2c50ca9fe1eefd2faf04215d0361b4b89a01 /lib | |
parent | ece56f52345a0d53c440dda852e6e59ff7d4512b (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.txt | 2 | ||||
-rw-r--r-- | lib/profile/InstrProfiling.h | 9 | ||||
-rw-r--r-- | lib/profile/InstrProfilingInternal.h | 7 | ||||
-rw-r--r-- | lib/profile/InstrProfilingMerge.c | 70 | ||||
-rw-r--r-- | lib/profile/InstrProfilingMergeFile.c | 41 |
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); + } +} |