| 1 | /*===- InstrProfiling.h- Support library for PGO instrumentation ----------===*\ |
| 2 | |* |
| 3 | |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | |* See https://llvm.org/LICENSE.txt for license information. |
| 5 | |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | |* |
| 7 | \*===----------------------------------------------------------------------===*/ |
| 8 | |
| 9 | #ifndef PROFILE_INSTRPROFILING_INTERNALH_ |
| 10 | #define PROFILE_INSTRPROFILING_INTERNALH_ |
| 11 | |
| 12 | #include <stddef.h> |
| 13 | |
| 14 | #include "InstrProfiling.h" |
| 15 | |
| 16 | /*! |
| 17 | * \brief Write instrumentation data to the given buffer, given explicit |
| 18 | * pointers to the live data in memory. This function is probably not what you |
| 19 | * want. Use __llvm_profile_get_size_for_buffer instead. Use this function if |
| 20 | * your program has a custom memory layout. |
| 21 | */ |
| 22 | uint64_t __llvm_profile_get_size_for_buffer_internal( |
| 23 | const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, |
| 24 | const char *CountersBegin, const char *CountersEnd, const char *BitmapBegin, |
| 25 | const char *BitmapEnd, const char *NamesBegin, const char *NamesEnd, |
| 26 | const VTableProfData *VTableBegin, const VTableProfData *VTableEnd, |
| 27 | const char *VNamesBegin, const char *VNamesEnd); |
| 28 | |
| 29 | /*! |
| 30 | * \brief Write instrumentation data to the given buffer, given explicit |
| 31 | * pointers to the live data in memory. This function is probably not what you |
| 32 | * want. Use __llvm_profile_write_buffer instead. Use this function if your |
| 33 | * program has a custom memory layout. |
| 34 | * |
| 35 | * \pre \c Buffer is the start of a buffer at least as big as \a |
| 36 | * __llvm_profile_get_size_for_buffer_internal(). |
| 37 | */ |
| 38 | int __llvm_profile_write_buffer_internal( |
| 39 | char *Buffer, const __llvm_profile_data *DataBegin, |
| 40 | const __llvm_profile_data *DataEnd, const char *CountersBegin, |
| 41 | const char *CountersEnd, const char *BitmapBegin, const char *BitmapEnd, |
| 42 | const char *NamesBegin, const char *NamesEnd); |
| 43 | |
| 44 | /*! |
| 45 | * The data structure describing the data to be written by the |
| 46 | * low level writer callback function. |
| 47 | * |
| 48 | * If \ref ProfDataIOVec.Data is null, and \ref ProfDataIOVec.UseZeroPadding is |
| 49 | * 0, the write is skipped (the writer simply advances ElmSize*NumElm bytes). |
| 50 | * |
| 51 | * If \ref ProfDataIOVec.Data is null, and \ref ProfDataIOVec.UseZeroPadding is |
| 52 | * nonzero, ElmSize*NumElm zero bytes are written. |
| 53 | */ |
| 54 | typedef struct ProfDataIOVec { |
| 55 | const void *Data; |
| 56 | size_t ElmSize; |
| 57 | size_t NumElm; |
| 58 | int UseZeroPadding; |
| 59 | } ProfDataIOVec; |
| 60 | |
| 61 | struct ProfDataWriter; |
| 62 | typedef uint32_t (*WriterCallback)(struct ProfDataWriter *This, ProfDataIOVec *, |
| 63 | uint32_t NumIOVecs); |
| 64 | |
| 65 | typedef struct ProfDataWriter { |
| 66 | WriterCallback Write; |
| 67 | void *WriterCtx; |
| 68 | } ProfDataWriter; |
| 69 | |
| 70 | /*! |
| 71 | * The data structure for buffered IO of profile data. |
| 72 | */ |
| 73 | typedef struct ProfBufferIO { |
| 74 | ProfDataWriter *FileWriter; |
| 75 | uint32_t OwnFileWriter; |
| 76 | /* The start of the buffer. */ |
| 77 | uint8_t *BufferStart; |
| 78 | /* Total size of the buffer. */ |
| 79 | uint32_t BufferSz; |
| 80 | /* Current byte offset from the start of the buffer. */ |
| 81 | uint32_t CurOffset; |
| 82 | } ProfBufferIO; |
| 83 | |
| 84 | /* The creator interface used by testing. */ |
| 85 | ProfBufferIO *lprofCreateBufferIOInternal(void *File, uint32_t BufferSz); |
| 86 | |
| 87 | /*! |
| 88 | * This is the interface to create a handle for buffered IO. |
| 89 | */ |
| 90 | ProfBufferIO *lprofCreateBufferIO(ProfDataWriter *FileWriter); |
| 91 | |
| 92 | /*! |
| 93 | * The interface to destroy the bufferIO handle and reclaim |
| 94 | * the memory. |
| 95 | */ |
| 96 | void lprofDeleteBufferIO(ProfBufferIO *BufferIO); |
| 97 | |
| 98 | /*! |
| 99 | * This is the interface to write \c Data of \c Size bytes through |
| 100 | * \c BufferIO. Returns 0 if successful, otherwise return -1. |
| 101 | */ |
| 102 | int lprofBufferIOWrite(ProfBufferIO *BufferIO, const uint8_t *Data, |
| 103 | uint32_t Size); |
| 104 | /*! |
| 105 | * The interface to flush the remaining data in the buffer. |
| 106 | * through the low level writer callback. |
| 107 | */ |
| 108 | int lprofBufferIOFlush(ProfBufferIO *BufferIO); |
| 109 | |
| 110 | /* The low level interface to write data into a buffer. It is used as the |
| 111 | * callback by other high level writer methods such as buffered IO writer |
| 112 | * and profile data writer. */ |
| 113 | uint32_t lprofBufferWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs, |
| 114 | uint32_t NumIOVecs); |
| 115 | void initBufferWriter(ProfDataWriter *BufferWriter, char *Buffer); |
| 116 | |
| 117 | struct ValueProfData; |
| 118 | struct ValueProfRecord; |
| 119 | struct InstrProfValueData; |
| 120 | struct ValueProfNode; |
| 121 | |
| 122 | /*! |
| 123 | * The class that defines a set of methods to read value profile |
| 124 | * data for streaming/serialization from the instrumentation runtime. |
| 125 | */ |
| 126 | typedef struct VPDataReaderType { |
| 127 | uint32_t (*InitRTRecord)(const __llvm_profile_data *Data, |
| 128 | uint8_t *SiteCountArray[]); |
| 129 | /* Function pointer to getValueProfRecordHeader method. */ |
| 130 | uint32_t (*)(uint32_t NumSites); |
| 131 | /* Function pointer to getFirstValueProfRecord method. */ |
| 132 | struct ValueProfRecord *(*GetFirstValueProfRecord)(struct ValueProfData *); |
| 133 | /* Return the number of value data for site \p Site. */ |
| 134 | uint32_t (*GetNumValueDataForSite)(uint32_t VK, uint32_t Site); |
| 135 | /* Return the total size of the value profile data of the |
| 136 | * current function. */ |
| 137 | uint32_t (*GetValueProfDataSize)(void); |
| 138 | /*! |
| 139 | * Read the next \p N value data for site \p Site and store the data |
| 140 | * in \p Dst. \p StartNode is the first value node to start with if |
| 141 | * it is not null. The function returns the pointer to the value |
| 142 | * node pointer to be used as the \p StartNode of the next batch reading. |
| 143 | * If there is nothing left, it returns NULL. |
| 144 | */ |
| 145 | struct ValueProfNode *(*GetValueData)(uint32_t ValueKind, uint32_t Site, |
| 146 | struct InstrProfValueData *Dst, |
| 147 | struct ValueProfNode *StartNode, |
| 148 | uint32_t N); |
| 149 | } VPDataReaderType; |
| 150 | |
| 151 | /* Write profile data to destination. If SkipNameDataWrite is set to 1, |
| 152 | the name data is already in destination, we just skip over it. */ |
| 153 | int lprofWriteData(ProfDataWriter *Writer, VPDataReaderType *VPDataReader, |
| 154 | int SkipNameDataWrite); |
| 155 | int lprofWriteDataImpl(ProfDataWriter *Writer, |
| 156 | const __llvm_profile_data *DataBegin, |
| 157 | const __llvm_profile_data *DataEnd, |
| 158 | const char *CountersBegin, const char *CountersEnd, |
| 159 | const char *BitmapBegin, const char *BitmapEnd, |
| 160 | VPDataReaderType *VPDataReader, const char *NamesBegin, |
| 161 | const char *NamesEnd, const VTableProfData *VTableBegin, |
| 162 | const VTableProfData *VTableEnd, const char *VNamesBegin, |
| 163 | const char *VNamesEnd, int SkipNameDataWrite, |
| 164 | uint64_t Version); |
| 165 | |
| 166 | /* Merge value profile data pointed to by SrcValueProfData into |
| 167 | * in-memory profile counters pointed by to DstData. */ |
| 168 | void lprofMergeValueProfData(struct ValueProfData *SrcValueProfData, |
| 169 | __llvm_profile_data *DstData); |
| 170 | |
| 171 | VPDataReaderType *lprofGetVPDataReader(void); |
| 172 | |
| 173 | /* Internal interface used by test to reset the max number of |
| 174 | * tracked values per value site to be \p MaxVals. |
| 175 | */ |
| 176 | void lprofSetMaxValsPerSite(uint32_t MaxVals); |
| 177 | void lprofSetupValueProfiler(void); |
| 178 | |
| 179 | /* Return the profile header 'signature' value associated with the current |
| 180 | * executable or shared library. The signature value can be used to for |
| 181 | * a profile name that is unique to this load module so that it does not |
| 182 | * collide with profiles from other binaries. It also allows shared libraries |
| 183 | * to dump merged profile data into its own profile file. */ |
| 184 | uint64_t lprofGetLoadModuleSignature(void); |
| 185 | |
| 186 | /* |
| 187 | * Return non zero value if the profile data has already been |
| 188 | * dumped to the file. |
| 189 | */ |
| 190 | unsigned lprofProfileDumped(void); |
| 191 | void lprofSetProfileDumped(unsigned); |
| 192 | |
| 193 | COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *); |
| 194 | COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer; |
| 195 | COMPILER_RT_VISIBILITY extern uint32_t VPBufferSize; |
| 196 | COMPILER_RT_VISIBILITY extern uint32_t VPMaxNumValsPerSite; |
| 197 | /* Pointer to the start of static value counters to be allocted. */ |
| 198 | COMPILER_RT_VISIBILITY extern ValueProfNode *CurrentVNode; |
| 199 | COMPILER_RT_VISIBILITY extern ValueProfNode *EndVNode; |
| 200 | extern void (*VPMergeHook)(struct ValueProfData *, __llvm_profile_data *); |
| 201 | |
| 202 | /* |
| 203 | * Write binary ids into profiles if writer is given. |
| 204 | * Return -1 if an error occurs, otherwise, return total size of binary ids. |
| 205 | */ |
| 206 | int __llvm_write_binary_ids(ProfDataWriter *Writer); |
| 207 | |
| 208 | /* |
| 209 | * Write binary id length and then its data, because binary id does not |
| 210 | * have a fixed length. |
| 211 | */ |
| 212 | int lprofWriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen, |
| 213 | const uint8_t *BinaryIdData, |
| 214 | uint64_t BinaryIdPadding); |
| 215 | |
| 216 | #endif |
| 217 | |