diff options
author | Xinliang David Li <davidxl@google.com> | 2016-05-14 20:12:42 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2016-05-14 20:12:42 +0000 |
commit | 23a66e45ed7b8b6b6759b3b8b0dea32e9b481ee8 (patch) | |
tree | c526b6a06cda491df5b5132df1827b1402a0d5e9 | |
parent | 94854be9e1ab304312c39094b18c11b0536d5b1b (diff) | |
download | bcm5719-llvm-23a66e45ed7b8b6b6759b3b8b0dea32e9b481ee8.tar.gz bcm5719-llvm-23a66e45ed7b8b6b6759b3b8b0dea32e9b481ee8.zip |
[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.
llvm-svn: 269576
-rw-r--r-- | compiler-rt/lib/profile/InstrProfData.inc | 28 | ||||
-rw-r--r-- | compiler-rt/lib/profile/InstrProfilingFile.c | 2 | ||||
-rw-r--r-- | compiler-rt/lib/profile/InstrProfilingInternal.h | 44 | ||||
-rw-r--r-- | compiler-rt/lib/profile/InstrProfilingPort.h | 3 | ||||
-rw-r--r-- | compiler-rt/lib/profile/InstrProfilingValue.c | 183 | ||||
-rw-r--r-- | compiler-rt/lib/profile/InstrProfilingWriter.c | 117 |
6 files changed, 226 insertions, 151 deletions
diff --git a/compiler-rt/lib/profile/InstrProfData.inc b/compiler-rt/lib/profile/InstrProfData.inc index 77d44f15bed..4b748f973ae 100644 --- a/compiler-rt/lib/profile/InstrProfData.inc +++ b/compiler-rt/lib/profile/InstrProfData.inc @@ -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(ValueProfRecordClosure *Closure) { 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(ValueProfRecord *This, ValueProfData *serializeValueProfDataFrom(ValueProfRecordClosure *Closure, ValueProfData *DstData) { uint32_t Kind; - uint32_t TotalSize = + uint32_t TotalSize = DstData ? DstData->TotalSize : getValueProfDataSize(Closure); ValueProfData *VPD = diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index e2f68002e40..1e754017c53 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -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) { diff --git a/compiler-rt/lib/profile/InstrProfilingInternal.h b/compiler-rt/lib/profile/InstrProfilingInternal.h index 5f75baa3ad2..56d825101dc 100644 --- a/compiler-rt/lib/profile/InstrProfilingInternal.h +++ b/compiler-rt/lib/profile/InstrProfilingInternal.h @@ -99,25 +99,57 @@ int lprofBufferIOFlush(ProfBufferIO *BufferIO); 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; diff --git a/compiler-rt/lib/profile/InstrProfilingPort.h b/compiler-rt/lib/profile/InstrProfilingPort.h index 998e94dae2b..0f826cbc9cd 100644 --- a/compiler-rt/lib/profile/InstrProfilingPort.h +++ b/compiler-rt/lib/profile/InstrProfilingPort.h @@ -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 diff --git a/compiler-rt/lib/profile/InstrProfilingValue.c b/compiler-rt/lib/profile/InstrProfilingValue.c index 1253a6b2da6..a54bb1b13ae 100644 --- a/compiler-rt/lib/profile/InstrProfilingValue.c +++ b/compiler-rt/lib/profile/InstrProfilingValue.c @@ -117,135 +117,108 @@ __llvm_profile_instrument_target(uint64_t TargetValue, void *Data, } } -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++; +typedef struct ValueProfRuntimeRecord { + const __llvm_profile_data *Data; + ValueProfNode **NodesKind[IPVK_Last + 1]; + uint8_t **SiteCountArray; +} ValueProfRuntimeRecord; - RuntimeRecord->NodesKind[I] = Nodes ? &Nodes[S] : INSTR_PROF_NULLPTR; - S += N; - } - RuntimeRecord->NumValueKinds = NumValueKinds; - return 0; -} +/* ValueProfRecordClosure Interface implementation. */ -static void -finalizeValueProfRuntimeRecord(ValueProfRuntimeRecord *RuntimeRecord) {} - -/* 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; } diff --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c index 808ed62a156..30c1b785c72 100644 --- a/compiler-rt/lib/profile/InstrProfilingWriter.c +++ b/compiler-rt/lib/profile/InstrProfilingWriter.c @@ -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)(void *) = NULL; 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 lprofBufferIOFlush(ProfBufferIO *BufferIO) { 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(WriterCallback Writer, void *WriterCtx, 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 lprofWriteData(WriterCallback Writer, 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, 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) { /* Calculate size of sections. */ @@ -186,6 +277,6 @@ lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx, if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx)) return -1; - return writeValueProfData(Writer, WriterCtx, VPDataGatherer, DataBegin, + return writeValueProfData(Writer, WriterCtx, VPDataReader, DataBegin, DataEnd); } |