1*7c3d14c8STreehugger Robot /*===- InstrProfiling.h- Support library for PGO instrumentation ----------===*\ 2*7c3d14c8STreehugger Robot |* 3*7c3d14c8STreehugger Robot |* The LLVM Compiler Infrastructure 4*7c3d14c8STreehugger Robot |* 5*7c3d14c8STreehugger Robot |* This file is distributed under the University of Illinois Open Source 6*7c3d14c8STreehugger Robot |* License. See LICENSE.TXT for details. 7*7c3d14c8STreehugger Robot |* 8*7c3d14c8STreehugger Robot \*===----------------------------------------------------------------------===*/ 9*7c3d14c8STreehugger Robot 10*7c3d14c8STreehugger Robot #ifndef PROFILE_INSTRPROFILING_INTERNALH_ 11*7c3d14c8STreehugger Robot #define PROFILE_INSTRPROFILING_INTERNALH_ 12*7c3d14c8STreehugger Robot 13*7c3d14c8STreehugger Robot #include "InstrProfiling.h" 14*7c3d14c8STreehugger Robot #include "stddef.h" 15*7c3d14c8STreehugger Robot 16*7c3d14c8STreehugger Robot /*! 17*7c3d14c8STreehugger Robot * \brief Write instrumentation data to the given buffer, given explicit 18*7c3d14c8STreehugger Robot * pointers to the live data in memory. This function is probably not what you 19*7c3d14c8STreehugger Robot * want. Use __llvm_profile_get_size_for_buffer instead. Use this function if 20*7c3d14c8STreehugger Robot * your program has a custom memory layout. 21*7c3d14c8STreehugger Robot */ 22*7c3d14c8STreehugger Robot uint64_t __llvm_profile_get_size_for_buffer_internal( 23*7c3d14c8STreehugger Robot const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, 24*7c3d14c8STreehugger Robot const uint64_t *CountersBegin, const uint64_t *CountersEnd, 25*7c3d14c8STreehugger Robot const char *NamesBegin, const char *NamesEnd); 26*7c3d14c8STreehugger Robot 27*7c3d14c8STreehugger Robot /*! 28*7c3d14c8STreehugger Robot * \brief Write instrumentation data to the given buffer, given explicit 29*7c3d14c8STreehugger Robot * pointers to the live data in memory. This function is probably not what you 30*7c3d14c8STreehugger Robot * want. Use __llvm_profile_write_buffer instead. Use this function if your 31*7c3d14c8STreehugger Robot * program has a custom memory layout. 32*7c3d14c8STreehugger Robot * 33*7c3d14c8STreehugger Robot * \pre \c Buffer is the start of a buffer at least as big as \a 34*7c3d14c8STreehugger Robot * __llvm_profile_get_size_for_buffer_internal(). 35*7c3d14c8STreehugger Robot */ 36*7c3d14c8STreehugger Robot int __llvm_profile_write_buffer_internal( 37*7c3d14c8STreehugger Robot char *Buffer, const __llvm_profile_data *DataBegin, 38*7c3d14c8STreehugger Robot const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin, 39*7c3d14c8STreehugger Robot const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd); 40*7c3d14c8STreehugger Robot 41*7c3d14c8STreehugger Robot /*! 42*7c3d14c8STreehugger Robot * The data structure describing the data to be written by the 43*7c3d14c8STreehugger Robot * low level writer callback function. 44*7c3d14c8STreehugger Robot */ 45*7c3d14c8STreehugger Robot typedef struct ProfDataIOVec { 46*7c3d14c8STreehugger Robot const void *Data; 47*7c3d14c8STreehugger Robot size_t ElmSize; 48*7c3d14c8STreehugger Robot size_t NumElm; 49*7c3d14c8STreehugger Robot } ProfDataIOVec; 50*7c3d14c8STreehugger Robot 51*7c3d14c8STreehugger Robot typedef uint32_t (*WriterCallback)(ProfDataIOVec *, uint32_t NumIOVecs, 52*7c3d14c8STreehugger Robot void **WriterCtx); 53*7c3d14c8STreehugger Robot 54*7c3d14c8STreehugger Robot /*! 55*7c3d14c8STreehugger Robot * The data structure for buffered IO of profile data. 56*7c3d14c8STreehugger Robot */ 57*7c3d14c8STreehugger Robot typedef struct ProfBufferIO { 58*7c3d14c8STreehugger Robot /* File handle. */ 59*7c3d14c8STreehugger Robot void *File; 60*7c3d14c8STreehugger Robot /* Low level IO callback. */ 61*7c3d14c8STreehugger Robot WriterCallback FileWriter; 62*7c3d14c8STreehugger Robot /* The start of the buffer. */ 63*7c3d14c8STreehugger Robot uint8_t *BufferStart; 64*7c3d14c8STreehugger Robot /* Total size of the buffer. */ 65*7c3d14c8STreehugger Robot uint32_t BufferSz; 66*7c3d14c8STreehugger Robot /* Current byte offset from the start of the buffer. */ 67*7c3d14c8STreehugger Robot uint32_t CurOffset; 68*7c3d14c8STreehugger Robot } ProfBufferIO; 69*7c3d14c8STreehugger Robot 70*7c3d14c8STreehugger Robot /* The creator interface used by testing. */ 71*7c3d14c8STreehugger Robot ProfBufferIO *lprofCreateBufferIOInternal(void *File, uint32_t BufferSz); 72*7c3d14c8STreehugger Robot 73*7c3d14c8STreehugger Robot /*! 74*7c3d14c8STreehugger Robot * This is the interface to create a handle for buffered IO. 75*7c3d14c8STreehugger Robot */ 76*7c3d14c8STreehugger Robot ProfBufferIO *lprofCreateBufferIO(WriterCallback FileWriter, void *File); 77*7c3d14c8STreehugger Robot 78*7c3d14c8STreehugger Robot /*! 79*7c3d14c8STreehugger Robot * The interface to destroy the bufferIO handle and reclaim 80*7c3d14c8STreehugger Robot * the memory. 81*7c3d14c8STreehugger Robot */ 82*7c3d14c8STreehugger Robot void lprofDeleteBufferIO(ProfBufferIO *BufferIO); 83*7c3d14c8STreehugger Robot 84*7c3d14c8STreehugger Robot /*! 85*7c3d14c8STreehugger Robot * This is the interface to write \c Data of \c Size bytes through 86*7c3d14c8STreehugger Robot * \c BufferIO. Returns 0 if successful, otherwise return -1. 87*7c3d14c8STreehugger Robot */ 88*7c3d14c8STreehugger Robot int lprofBufferIOWrite(ProfBufferIO *BufferIO, const uint8_t *Data, 89*7c3d14c8STreehugger Robot uint32_t Size); 90*7c3d14c8STreehugger Robot /*! 91*7c3d14c8STreehugger Robot * The interface to flush the remaining data in the buffer. 92*7c3d14c8STreehugger Robot * through the low level writer callback. 93*7c3d14c8STreehugger Robot */ 94*7c3d14c8STreehugger Robot int lprofBufferIOFlush(ProfBufferIO *BufferIO); 95*7c3d14c8STreehugger Robot 96*7c3d14c8STreehugger Robot /* The low level interface to write data into a buffer. It is used as the 97*7c3d14c8STreehugger Robot * callback by other high level writer methods such as buffered IO writer 98*7c3d14c8STreehugger Robot * and profile data writer. */ 99*7c3d14c8STreehugger Robot uint32_t lprofBufferWriter(ProfDataIOVec *IOVecs, uint32_t NumIOVecs, 100*7c3d14c8STreehugger Robot void **WriterCtx); 101*7c3d14c8STreehugger Robot 102*7c3d14c8STreehugger Robot struct ValueProfData; 103*7c3d14c8STreehugger Robot struct ValueProfRecord; 104*7c3d14c8STreehugger Robot struct InstrProfValueData; 105*7c3d14c8STreehugger Robot struct ValueProfNode; 106*7c3d14c8STreehugger Robot 107*7c3d14c8STreehugger Robot /*! 108*7c3d14c8STreehugger Robot * The class that defines a set of methods to read value profile 109*7c3d14c8STreehugger Robot * data for streaming/serialization from the instrumentation runtime. 110*7c3d14c8STreehugger Robot */ 111*7c3d14c8STreehugger Robot typedef struct VPDataReaderType { 112*7c3d14c8STreehugger Robot uint32_t (*InitRTRecord)(const __llvm_profile_data *Data, 113*7c3d14c8STreehugger Robot uint8_t *SiteCountArray[]); 114*7c3d14c8STreehugger Robot /* Function pointer to getValueProfRecordHeader method. */ 115*7c3d14c8STreehugger Robot uint32_t (*GetValueProfRecordHeaderSize)(uint32_t NumSites); 116*7c3d14c8STreehugger Robot /* Function pointer to getFristValueProfRecord method. */ 117*7c3d14c8STreehugger Robot struct ValueProfRecord *(*GetFirstValueProfRecord)(struct ValueProfData *); 118*7c3d14c8STreehugger Robot /* Return the number of value data for site \p Site. */ 119*7c3d14c8STreehugger Robot uint32_t (*GetNumValueDataForSite)(uint32_t VK, uint32_t Site); 120*7c3d14c8STreehugger Robot /* Return the total size of the value profile data of the 121*7c3d14c8STreehugger Robot * current function. */ 122*7c3d14c8STreehugger Robot uint32_t (*GetValueProfDataSize)(void); 123*7c3d14c8STreehugger Robot /*! 124*7c3d14c8STreehugger Robot * Read the next \p N value data for site \p Site and store the data 125*7c3d14c8STreehugger Robot * in \p Dst. \p StartNode is the first value node to start with if 126*7c3d14c8STreehugger Robot * it is not null. The function returns the pointer to the value 127*7c3d14c8STreehugger Robot * node pointer to be used as the \p StartNode of the next batch reading. 128*7c3d14c8STreehugger Robot * If there is nothing left, it returns NULL. 129*7c3d14c8STreehugger Robot */ 130*7c3d14c8STreehugger Robot struct ValueProfNode *(*GetValueData)(uint32_t ValueKind, uint32_t Site, 131*7c3d14c8STreehugger Robot struct InstrProfValueData *Dst, 132*7c3d14c8STreehugger Robot struct ValueProfNode *StartNode, 133*7c3d14c8STreehugger Robot uint32_t N); 134*7c3d14c8STreehugger Robot } VPDataReaderType; 135*7c3d14c8STreehugger Robot 136*7c3d14c8STreehugger Robot int lprofWriteData(WriterCallback Writer, void *WriterCtx, 137*7c3d14c8STreehugger Robot VPDataReaderType *VPDataReader); 138*7c3d14c8STreehugger Robot int lprofWriteDataImpl(WriterCallback Writer, void *WriterCtx, 139*7c3d14c8STreehugger Robot const __llvm_profile_data *DataBegin, 140*7c3d14c8STreehugger Robot const __llvm_profile_data *DataEnd, 141*7c3d14c8STreehugger Robot const uint64_t *CountersBegin, 142*7c3d14c8STreehugger Robot const uint64_t *CountersEnd, 143*7c3d14c8STreehugger Robot VPDataReaderType *VPDataReader, const char *NamesBegin, 144*7c3d14c8STreehugger Robot const char *NamesEnd); 145*7c3d14c8STreehugger Robot 146*7c3d14c8STreehugger Robot /* Merge value profile data pointed to by SrcValueProfData into 147*7c3d14c8STreehugger Robot * in-memory profile counters pointed by to DstData. */ 148*7c3d14c8STreehugger Robot void lprofMergeValueProfData(struct ValueProfData *SrcValueProfData, 149*7c3d14c8STreehugger Robot __llvm_profile_data *DstData); 150*7c3d14c8STreehugger Robot 151*7c3d14c8STreehugger Robot VPDataReaderType *lprofGetVPDataReader(); 152*7c3d14c8STreehugger Robot 153*7c3d14c8STreehugger Robot /* Internal interface used by test to reset the max number of 154*7c3d14c8STreehugger Robot * tracked values per value site to be \p MaxVals. 155*7c3d14c8STreehugger Robot */ 156*7c3d14c8STreehugger Robot void lprofSetMaxValsPerSite(uint32_t MaxVals); 157*7c3d14c8STreehugger Robot void lprofSetupValueProfiler(); 158*7c3d14c8STreehugger Robot 159*7c3d14c8STreehugger Robot /* Return the profile header 'signature' value associated with the current 160*7c3d14c8STreehugger Robot * executable or shared library. The signature value can be used to for 161*7c3d14c8STreehugger Robot * a profile name that is unique to this load module so that it does not 162*7c3d14c8STreehugger Robot * collide with profiles from other binaries. It also allows shared libraries 163*7c3d14c8STreehugger Robot * to dump merged profile data into its own profile file. */ 164*7c3d14c8STreehugger Robot uint64_t lprofGetLoadModuleSignature(); 165*7c3d14c8STreehugger Robot 166*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern char *(*GetEnvHook)(const char *); 167*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *); 168*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer; 169*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern uint32_t VPBufferSize; 170*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern uint32_t VPMaxNumValsPerSite; 171*7c3d14c8STreehugger Robot /* Pointer to the start of static value counters to be allocted. */ 172*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern ValueProfNode *CurrentVNode; 173*7c3d14c8STreehugger Robot COMPILER_RT_VISIBILITY extern ValueProfNode *EndVNode; 174*7c3d14c8STreehugger Robot extern void (*VPMergeHook)(struct ValueProfData *, __llvm_profile_data *); 175*7c3d14c8STreehugger Robot 176*7c3d14c8STreehugger Robot #endif 177