[compiler-rt] r269576 - [profile] Eliminate dynamic memory allocation for vp writing
Xinliang David Li via llvm-commits
llvm-commits at lists.llvm.org
Sat May 14 13:12:43 PDT 2016
Author: davidxl
Date: Sat May 14 15:12:42 2016
New Revision: 269576
URL: http://llvm.org/viewvc/llvm-project?rev=269576&view=rev
Log:
[profile] Eliminate dynamic memory allocation for vp writing
This is part-3 of the effort to eliminate dependency on
libc allocator in instr profiler runtime. With this change,
the profile dumper is completely free of malloc/calloc.
Value profile instr API implementation is the only remaining
piece with calloc dependency.
Modified:
compiler-rt/trunk/lib/profile/InstrProfData.inc
compiler-rt/trunk/lib/profile/InstrProfilingFile.c
compiler-rt/trunk/lib/profile/InstrProfilingInternal.h
compiler-rt/trunk/lib/profile/InstrProfilingPort.h
compiler-rt/trunk/lib/profile/InstrProfilingValue.c
compiler-rt/trunk/lib/profile/InstrProfilingWriter.c
Modified: compiler-rt/trunk/lib/profile/InstrProfData.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfData.inc?rev=269576&r1=269575&r2=269576&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfData.inc (original)
+++ compiler-rt/trunk/lib/profile/InstrProfData.inc Sat May 14 15:12:42 2016
@@ -361,32 +361,11 @@ typedef struct ValueProfRecordClosure {
ValueProfData *(*AllocValueProfData)(size_t TotalSizeInBytes);
} ValueProfRecordClosure;
-/*
- * A wrapper struct that represents value profile runtime data.
- * Like InstrProfRecord class which is used by profiling host tools,
- * ValueProfRuntimeRecord also implements the abstract intefaces defined in
- * ValueProfRecordClosure so that the runtime data can be serialized using
- * shared C implementation. In this structure, NumValueSites and Nodes
- * members are the primary fields while other fields hold the derived
- * information for fast implementation of closure interfaces.
- */
-typedef struct ValueProfRuntimeRecord {
- /* Number of sites for each value profile kind. */
- const uint16_t *NumValueSites;
- /* An array of linked-list headers. The size of of the array is the
- * total number of value profile sites : sum(NumValueSites[*])). Each
- * linked-list stores the values profiled for a value profile site. */
- ValueProfNode **Nodes;
-
- /* Total number of value profile kinds which have at least one
- * value profile sites. */
- uint32_t NumValueKinds;
- ValueProfNode **NodesKind[IPVK_Last + 1];
-} ValueProfRuntimeRecord;
ValueProfRecord *getFirstValueProfRecord(ValueProfData *VPD);
ValueProfRecord *getValueProfRecordNext(ValueProfRecord *VPR);
InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *VPR);
+uint32_t getValueProfRecordHeaderSize(uint32_t NumValueSites);
#undef INSTR_PROF_VALUE_PROF_DATA
#endif /* INSTR_PROF_VALUE_PROF_DATA */
@@ -480,9 +459,6 @@ uint32_t getValueProfDataSize(ValueProfR
uint32_t Kind;
uint32_t TotalSize = sizeof(ValueProfData);
const void *Record = Closure->Record;
- uint32_t NumValueKinds = Closure->GetNumValueKinds(Record);
- if (NumValueKinds == 0)
- return TotalSize;
for (Kind = IPVK_First; Kind <= IPVK_Last; Kind++) {
uint32_t NumValueSites = Closure->GetNumValueSites(Record, Kind);
@@ -525,7 +501,7 @@ void serializeValueProfRecordFrom(ValueP
ValueProfData *serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
ValueProfData *DstData) {
uint32_t Kind;
- uint32_t TotalSize =
+ uint32_t TotalSize =
DstData ? DstData->TotalSize : getValueProfDataSize(Closure);
ValueProfData *VPD =
Modified: compiler-rt/trunk/lib/profile/InstrProfilingFile.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingFile.c?rev=269576&r1=269575&r2=269576&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingFile.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingFile.c Sat May 14 15:12:42 2016
@@ -50,7 +50,7 @@ static void setupIOBuffer() {
static int writeFile(FILE *File) {
FreeHook = &free;
setupIOBuffer();
- return lprofWriteData(fileWriter, File, lprofGatherValueProfData);
+ return lprofWriteData(fileWriter, File, lprofGetVPDataReader());
}
static int writeFileWithName(const char *OutputName) {
Modified: compiler-rt/trunk/lib/profile/InstrProfilingInternal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingInternal.h?rev=269576&r1=269575&r2=269576&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingInternal.h (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingInternal.h Sat May 14 15:12:42 2016
@@ -99,25 +99,57 @@ int lprofBufferIOFlush(ProfBufferIO *Buf
uint32_t lprofBufferWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs,
void **WriterCtx);
-typedef struct ValueProfData *(*VPGatherHookType)(
- const __llvm_profile_data *Data);
+struct ValueProfData;
+struct ValueProfRecord;
+struct InstrProfValueData;
+struct ValueProfNode;
+
+/*!
+ * The class that defines a set of methods to read value profile
+ * data for streaming/serialization from the instrumentation runtime.
+ */
+typedef struct VPDataReaderType {
+ uint32_t (*InitRTRecord)(const __llvm_profile_data *Data,
+ uint8_t *SiteCountArray[]);
+ /* Function pointer to getValueProfRecordHeader method. */
+ uint32_t (*GetValueProfRecordHeaderSize)(uint32_t NumSites);
+ /* Function pointer to getFristValueProfRecord method. */
+ struct ValueProfRecord *(*GetFirstValueProfRecord)(struct ValueProfData *);
+ /* Return the number of value data for site \p Site. */
+ uint32_t (*GetNumValueDataForSite)(uint32_t VK, uint32_t Site);
+ /* Return the total size of the value profile data of the
+ * current function. */
+ uint32_t (*GetValueProfDataSize)(void);
+ /*!
+ * Read the next \p N value data for site \p Site and store the data
+ * in \p Dst. \p StartNode is the first value node to start with if
+ * it is not null. The function returns the pointer to the value
+ * node pointer to be used as the \p StartNode of the next batch reading.
+ * If there is nothing left, it returns NULL.
+ */
+ struct ValueProfNode *(*GetValueData)(uint32_t ValueKind, uint32_t Site,
+ struct InstrProfValueData *Dst,
+ struct ValueProfNode *StartNode,
+ uint32_t N);
+} VPDataReaderType;
+
int lprofWriteData(WriterCallback Writer, void *WriterCtx,
- VPGatherHookType VPDataGatherer);
+ VPDataReaderType *VPDataReader);
int lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx,
const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd,
const uint64_t *CountersBegin,
const uint64_t *CountersEnd,
- VPGatherHookType VPDataGatherer, const char *NamesBegin,
+ VPDataReaderType *VPDataReader, const char *NamesBegin,
const char *NamesEnd);
-/* Gather value profile data from \c Data and return it. */
-struct ValueProfData *lprofGatherValueProfData(const __llvm_profile_data *Data);
/* Merge value profile data pointed to by SrcValueProfData into
* in-memory profile counters pointed by to DstData. */
void lprofMergeValueProfData(struct ValueProfData *SrcValueProfData,
__llvm_profile_data *DstData);
+VPDataReaderType *lprofGetVPDataReader();
+
COMPILER_RT_VISIBILITY extern char *(*GetEnvHook)(const char *);
COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *);
COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer;
Modified: compiler-rt/trunk/lib/profile/InstrProfilingPort.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingPort.h?rev=269576&r1=269575&r2=269576&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingPort.h (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingPort.h Sat May 14 15:12:42 2016
@@ -25,11 +25,14 @@
#define COMPILER_RT_MAX_HOSTLEN 128
#ifdef _MSC_VER
#define COMPILER_RT_GETHOSTNAME(Name, Len) gethostname(Name, Len)
+#define COMPILER_RT_ALLOCA _alloca
#elif defined(__PS4__)
#define COMPILER_RT_GETHOSTNAME(Name, Len) (-1)
+#define COMPILER_RT_ALLOCA alloca
#else
#define COMPILER_RT_GETHOSTNAME(Name, Len) lprofGetHostName(Name, Len)
#define COMPILER_RT_HAS_UNAME 1
+#define COMPILER_RT_ALLOCA alloca
#endif
#if COMPILER_RT_HAS_ATOMICS == 1
Modified: compiler-rt/trunk/lib/profile/InstrProfilingValue.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingValue.c?rev=269576&r1=269575&r2=269576&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingValue.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingValue.c Sat May 14 15:12:42 2016
@@ -117,135 +117,108 @@ __llvm_profile_instrument_target(uint64_
}
}
-ValueProfData *allocValueProfDataRT(size_t TotalSizeInBytes) {
- return (ValueProfData *)calloc(TotalSizeInBytes, 1);
-}
-
/*
- * The value profiler runtime library stores the value profile data
- * for a given function in \c NumValueSites and \c Nodes structures.
- * \c ValueProfRuntimeRecord class is used to encapsulate the runtime
- * profile data and provides fast interfaces to retrieve the profile
- * information. This interface is used to initialize the runtime record
- * and pre-compute the information needed for efficient implementation
- * of callbacks required by ValueProfRecordClosure class.
+ * A wrapper struct that represents value profile runtime data.
+ * Like InstrProfRecord class which is used by profiling host tools,
+ * ValueProfRuntimeRecord also implements the abstract intefaces defined in
+ * ValueProfRecordClosure so that the runtime data can be serialized using
+ * shared C implementation.
*/
-static int
-initializeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord,
- const uint16_t *NumValueSites,
- ValueProfNode **Nodes) {
- unsigned I, S = 0, NumValueKinds = 0;
- RuntimeRecord->NumValueSites = NumValueSites;
- RuntimeRecord->Nodes = Nodes;
- for (I = 0; I <= IPVK_Last; I++) {
- uint16_t N = NumValueSites[I];
- if (!N)
- continue;
- NumValueKinds++;
-
- RuntimeRecord->NodesKind[I] = Nodes ? &Nodes[S] : INSTR_PROF_NULLPTR;
- S += N;
- }
- RuntimeRecord->NumValueKinds = NumValueKinds;
- return 0;
-}
+typedef struct ValueProfRuntimeRecord {
+ const __llvm_profile_data *Data;
+ ValueProfNode **NodesKind[IPVK_Last + 1];
+ uint8_t **SiteCountArray;
+} ValueProfRuntimeRecord;
-static void
-finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord) {}
+/* ValueProfRecordClosure Interface implementation. */
-/* ValueProfRecordClosure Interface implementation for
- * ValueProfDataRuntimeRecord. */
-static uint32_t getNumValueKindsRT(const void *R) {
- return ((const ValueProfRuntimeRecord *)R)->NumValueKinds;
+static uint32_t getNumValueSitesRT(const void *R, uint32_t VK) {
+ return ((const ValueProfRuntimeRecord *)R)->Data->NumValueSites[VK];
}
-static uint32_t getNumValueSitesRT(const void *R, uint32_t VK) {
- return ((const ValueProfRuntimeRecord *)R)->NumValueSites[VK];
+static uint32_t getNumValueDataRT(const void *R, uint32_t VK) {
+ uint32_t S = 0, I;
+ const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;
+ if (Record->SiteCountArray[VK] == INSTR_PROF_NULLPTR)
+ return 0;
+ for (I = 0; I < Record->Data->NumValueSites[VK]; I++)
+ S += Record->SiteCountArray[VK][I];
+ return S;
}
static uint32_t getNumValueDataForSiteRT(const void *R, uint32_t VK,
uint32_t S) {
- uint32_t C = 0;
const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;
- ValueProfNode *Site =
- Record->NodesKind[VK] ? Record->NodesKind[VK][S] : INSTR_PROF_NULLPTR;
- while (Site) {
- C++;
- Site = Site->Next;
- }
- if (C > UCHAR_MAX)
- C = UCHAR_MAX;
-
- return C;
+ return Record->SiteCountArray[VK][S];
}
-static uint32_t getNumValueDataRT(const void *R, uint32_t VK) {
- unsigned I, S = 0;
- const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;
- for (I = 0; I < Record->NumValueSites[VK]; I++)
- S += getNumValueDataForSiteRT(Record, VK, I);
- return S;
+static ValueProfRuntimeRecord RTRecord;
+static ValueProfRecordClosure RTRecordClosure = {
+ &RTRecord, INSTR_PROF_NULLPTR, /* GetNumValueKinds */
+ getNumValueSitesRT, getNumValueDataRT, getNumValueDataForSiteRT,
+ INSTR_PROF_NULLPTR, /* RemapValueData */
+ INSTR_PROF_NULLPTR, /* GetValueForSite, */
+ INSTR_PROF_NULLPTR /* AllocValueProfData */
+};
+
+static uint32_t
+initializeValueProfRuntimeRecord(const __llvm_profile_data *Data,
+ uint8_t *SiteCountArray[]) {
+ unsigned I, J, S = 0, NumValueKinds = 0;
+ ValueProfNode **Nodes = (ValueProfNode **)Data->Values;
+ RTRecord.Data = Data;
+ RTRecord.SiteCountArray = SiteCountArray;
+ for (I = 0; I <= IPVK_Last; I++) {
+ uint16_t N = Data->NumValueSites[I];
+ if (!N)
+ continue;
+
+ NumValueKinds++;
+
+ RTRecord.NodesKind[I] = Nodes ? &Nodes[S] : INSTR_PROF_NULLPTR;
+ for (J = 0; J < N; J++) {
+ /* Compute value count for each site. */
+ uint32_t C = 0;
+ ValueProfNode *Site =
+ Nodes ? RTRecord.NodesKind[I][J] : INSTR_PROF_NULLPTR;
+ while (Site) {
+ C++;
+ Site = Site->Next;
+ }
+ if (C > UCHAR_MAX)
+ C = UCHAR_MAX;
+ RTRecord.SiteCountArray[I][J] = C;
+ }
+ S += N;
+ }
+ return NumValueKinds;
}
-static void getValueForSiteRT(const void *R, InstrProfValueData *Dst,
- uint32_t VK, uint32_t S) {
- unsigned I, N = 0;
- const ValueProfRuntimeRecord *Record = (const ValueProfRuntimeRecord *)R;
- N = getNumValueDataForSiteRT(R, VK, S);
- if (N == 0)
- return;
- ValueProfNode *VNode = Record->NodesKind[VK][S];
+static ValueProfNode *getNextNValueData(uint32_t VK, uint32_t Site,
+ InstrProfValueData *Dst,
+ ValueProfNode *StartNode, uint32_t N) {
+ unsigned I;
+ ValueProfNode *VNode = StartNode ? StartNode : RTRecord.NodesKind[VK][Site];
for (I = 0; I < N; I++) {
Dst[I] = VNode->VData;
VNode = VNode->Next;
}
+ return VNode;
}
-static ValueProfRecordClosure RTRecordClosure = {
- INSTR_PROF_NULLPTR, getNumValueKindsRT, getNumValueSitesRT,
- getNumValueDataRT, getNumValueDataForSiteRT, INSTR_PROF_NULLPTR,
- getValueForSiteRT, allocValueProfDataRT};
-
-/*
- * Return a ValueProfData instance that stores the data collected
- * from runtime. If \c DstData is provided by the caller, the value
- * profile data will be store in *DstData and DstData is returned,
- * otherwise the method will allocate space for the value data and
- * return pointer to the newly allocated space.
- */
-static ValueProfData *
-serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record,
- ValueProfData *DstData) {
- RTRecordClosure.Record = Record;
- return serializeValueProfDataFrom(&RTRecordClosure, DstData);
+static uint32_t getValueProfDataSizeWrapper() {
+ return getValueProfDataSize(&RTRecordClosure);
}
-/*
- * Return the size of ValueProfData structure to store data
- * recorded in the runtime record.
- */
-static uint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record) {
- RTRecordClosure.Record = Record;
- return getValueProfDataSize(&RTRecordClosure);
+static uint32_t getNumValueDataForSiteWrapper(uint32_t VK, uint32_t S) {
+ return getNumValueDataForSiteRT(&RTRecord, VK, S);
}
-COMPILER_RT_VISIBILITY struct ValueProfData *
-lprofGatherValueProfData(const __llvm_profile_data *Data) {
- ValueProfData *VD = NULL;
- ValueProfRuntimeRecord R;
- if (initializeValueProfRuntimeRecord(&R, Data->NumValueSites, Data->Values))
- PROF_OOM_RETURN("Failed to write value profile data ");
-
- /* Compute the size of ValueProfData from this runtime record. */
- if (getNumValueKindsRT(&R) != 0) {
- uint32_t VS = getValueProfDataSizeRT(&R);
- VD = (ValueProfData *)calloc(VS, sizeof(uint8_t));
- if (!VD)
- PROF_OOM_RETURN("Failed to write value profile data ");
- VD->TotalSize = VS;
- serializeValueProfDataFromRT(&R, VD);
- }
- finalizeValueProfRuntimeRecord(&R);
+static VPDataReaderType TheVPDataReader = {
+ initializeValueProfRuntimeRecord, getValueProfRecordHeaderSize,
+ getFirstValueProfRecord, getNumValueDataForSiteWrapper,
+ getValueProfDataSizeWrapper, getNextNValueData};
- return VD;
+COMPILER_RT_VISIBILITY VPDataReaderType *lprofGetVPDataReader() {
+ return &TheVPDataReader;
}
Modified: compiler-rt/trunk/lib/profile/InstrProfilingWriter.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/profile/InstrProfilingWriter.c?rev=269576&r1=269575&r2=269576&view=diff
==============================================================================
--- compiler-rt/trunk/lib/profile/InstrProfilingWriter.c (original)
+++ compiler-rt/trunk/lib/profile/InstrProfilingWriter.c Sat May 14 15:12:42 2016
@@ -9,6 +9,11 @@
#include "InstrProfiling.h"
#include "InstrProfilingInternal.h"
+#ifdef _MSC_VER
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
#include <string.h>
#define INSTR_PROF_VALUE_PROF_DATA
@@ -18,6 +23,9 @@ COMPILER_RT_VISIBILITY void (*FreeHook)(
static ProfBufferIO TheBufferIO;
#define VP_BUFFER_SIZE 8 * 1024
static uint8_t BufferIOBuffer[VP_BUFFER_SIZE];
+static InstrProfValueData VPDataArray[16];
+static uint32_t VPDataArraySize = sizeof(VPDataArray) / sizeof(*VPDataArray);
+
COMPILER_RT_VISIBILITY uint8_t *DynamicBufferIOBuffer = 0;
COMPILER_RT_VISIBILITY uint32_t VPBufferSize = 0;
@@ -98,33 +106,116 @@ COMPILER_RT_VISIBILITY int lprofBufferIO
return 0;
}
+/* Write out value profile data for function specified with \c Data.
+ * The implementation does not use the method \c serializeValueProfData
+ * which depends on dynamic memory allocation. In this implementation,
+ * value profile data is written out to \c BufferIO piecemeal.
+ */
static int writeOneValueProfData(ProfBufferIO *BufferIO,
- VPGatherHookType VPDataGatherer,
+ VPDataReaderType *VPDataReader,
const __llvm_profile_data *Data) {
- ValueProfData *CurVData = VPDataGatherer(Data);
- if (!CurVData)
+ unsigned I, NumValueKinds = 0;
+ ValueProfData VPHeader;
+ uint8_t *SiteCountArray[IPVK_Last + 1];
+
+ for (I = 0; I <= IPVK_Last; I++) {
+ if (!Data->NumValueSites[I])
+ SiteCountArray[I] = 0;
+ else {
+ uint32_t Sz =
+ VPDataReader->GetValueProfRecordHeaderSize(Data->NumValueSites[I]) -
+ offsetof(ValueProfRecord, SiteCountArray);
+ /* Only use alloca for this small byte array to avoid excessive
+ * stack growth. */
+ SiteCountArray[I] = (uint8_t *)COMPILER_RT_ALLOCA(Sz);
+ memset(SiteCountArray[I], 0, Sz);
+ }
+ }
+
+ /* If NumValueKinds returned is 0, there is nothing to write, report
+ success and return. This should match the raw profile reader's behavior. */
+ if (!(NumValueKinds = VPDataReader->InitRTRecord(Data, SiteCountArray)))
return 0;
- if (lprofBufferIOWrite(BufferIO, (const uint8_t *)CurVData,
- CurVData->TotalSize) != 0)
+
+ /* First write the header structure. */
+ VPHeader.TotalSize = VPDataReader->GetValueProfDataSize();
+ VPHeader.NumValueKinds = NumValueKinds;
+ if (lprofBufferIOWrite(BufferIO, (const uint8_t *)&VPHeader,
+ sizeof(ValueProfData)))
+ return -1;
+
+ /* Make sure nothing else needs to be written before value profile
+ * records. */
+ if ((void *)VPDataReader->GetFirstValueProfRecord(&VPHeader) !=
+ (void *)(&VPHeader + 1))
return -1;
- FreeHook(CurVData);
+
+ /* Write out the value profile record for each value kind
+ * one by one. */
+ for (I = 0; I <= IPVK_Last; I++) {
+ uint32_t J;
+ ValueProfRecord RecordHeader;
+ /* The size of the value prof record header without counting the
+ * site count array .*/
+ uint32_t RecordHeaderSize = offsetof(ValueProfRecord, SiteCountArray);
+ uint32_t SiteCountArraySize;
+
+ if (!Data->NumValueSites[I])
+ continue;
+
+ /* Write out the record header. */
+ RecordHeader.Kind = I;
+ RecordHeader.NumValueSites = Data->NumValueSites[I];
+ if (lprofBufferIOWrite(BufferIO, (const uint8_t *)&RecordHeader,
+ RecordHeaderSize))
+ return -1;
+
+ /* Write out the site value count array including padding space. */
+ SiteCountArraySize =
+ VPDataReader->GetValueProfRecordHeaderSize(Data->NumValueSites[I]) -
+ RecordHeaderSize;
+ if (lprofBufferIOWrite(BufferIO, SiteCountArray[I], SiteCountArraySize))
+ return -1;
+
+ /* Write out the value profile data for each value site. */
+ for (J = 0; J < Data->NumValueSites[I]; J++) {
+ uint32_t NRead, NRemain;
+ ValueProfNode *NextStartNode = 0;
+ NRemain = VPDataReader->GetNumValueDataForSite(I, J);
+ if (!NRemain)
+ continue;
+ /* Read and write out value data in small chunks till it is done. */
+ do {
+ NRead = (NRemain > VPDataArraySize ? VPDataArraySize : NRemain);
+ NextStartNode =
+ VPDataReader->GetValueData(I, /* ValueKind */
+ J, /* Site */
+ &VPDataArray[0], NextStartNode, NRead);
+ if (lprofBufferIOWrite(BufferIO, (const uint8_t *)&VPDataArray[0],
+ NRead * sizeof(InstrProfValueData)))
+ return -1;
+ NRemain -= NRead;
+ } while (NRemain != 0);
+ }
+ }
+ /* All done report success. */
return 0;
}
static int writeValueProfData(WriterCallback Writer, void *WriterCtx,
- VPGatherHookType VPDataGatherer,
+ VPDataReaderType *VPDataReader,
const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd) {
ProfBufferIO *BufferIO;
const __llvm_profile_data *DI = 0;
- if (!VPDataGatherer)
+ if (!VPDataReader)
return 0;
BufferIO = lprofCreateBufferIO(Writer, WriterCtx);
for (DI = DataBegin; DI < DataEnd; DI++) {
- if (writeOneValueProfData(BufferIO, VPDataGatherer, DI))
+ if (writeOneValueProfData(BufferIO, VPDataReader, DI))
return -1;
}
@@ -137,7 +228,7 @@ static int writeValueProfData(WriterCall
COMPILER_RT_VISIBILITY int lprofWriteData(WriterCallback Writer,
void *WriterCtx,
- VPGatherHookType VPDataGatherer) {
+ VPDataReaderType *VPDataReader) {
/* Match logic in __llvm_profile_write_buffer(). */
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
@@ -146,7 +237,7 @@ COMPILER_RT_VISIBILITY int lprofWriteDat
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
return lprofWriteDataImpl(Writer, WriterCtx, DataBegin, DataEnd,
- CountersBegin, CountersEnd, VPDataGatherer,
+ CountersBegin, CountersEnd, VPDataReader,
NamesBegin, NamesEnd);
}
@@ -155,7 +246,7 @@ lprofWriteDataImpl(WriterCallback Writer
const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd,
const uint64_t *CountersBegin, const uint64_t *CountersEnd,
- VPGatherHookType VPDataGatherer, const char *NamesBegin,
+ VPDataReaderType *VPDataReader, const char *NamesBegin,
const char *NamesEnd) {
/* Calculate size of sections. */
@@ -186,6 +277,6 @@ lprofWriteDataImpl(WriterCallback Writer
if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx))
return -1;
- return writeValueProfData(Writer, WriterCtx, VPDataGatherer, DataBegin,
+ return writeValueProfData(Writer, WriterCtx, VPDataReader, DataBegin,
DataEnd);
}
More information about the llvm-commits
mailing list