xref: /openbsd-src/gnu/llvm/compiler-rt/lib/profile/InstrProfilingInternal.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick /*===- InstrProfiling.h- Support library for PGO instrumentation ----------===*\
23cab2bb3Spatrick |*
33cab2bb3Spatrick |* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick |* See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick |*
73cab2bb3Spatrick \*===----------------------------------------------------------------------===*/
83cab2bb3Spatrick 
93cab2bb3Spatrick #ifndef PROFILE_INSTRPROFILING_INTERNALH_
103cab2bb3Spatrick #define PROFILE_INSTRPROFILING_INTERNALH_
113cab2bb3Spatrick 
123cab2bb3Spatrick #include <stddef.h>
133cab2bb3Spatrick 
143cab2bb3Spatrick #include "InstrProfiling.h"
153cab2bb3Spatrick 
163cab2bb3Spatrick /*!
173cab2bb3Spatrick  * \brief Write instrumentation data to the given buffer, given explicit
183cab2bb3Spatrick  * pointers to the live data in memory.  This function is probably not what you
193cab2bb3Spatrick  * want.  Use __llvm_profile_get_size_for_buffer instead.  Use this function if
203cab2bb3Spatrick  * your program has a custom memory layout.
213cab2bb3Spatrick  */
223cab2bb3Spatrick uint64_t __llvm_profile_get_size_for_buffer_internal(
233cab2bb3Spatrick     const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,
24*810390e3Srobert     const char *CountersBegin, const char *CountersEnd, const char *NamesBegin,
25*810390e3Srobert     const char *NamesEnd);
263cab2bb3Spatrick 
273cab2bb3Spatrick /*!
283cab2bb3Spatrick  * \brief Write instrumentation data to the given buffer, given explicit
293cab2bb3Spatrick  * pointers to the live data in memory.  This function is probably not what you
303cab2bb3Spatrick  * want.  Use __llvm_profile_write_buffer instead.  Use this function if your
313cab2bb3Spatrick  * program has a custom memory layout.
323cab2bb3Spatrick  *
333cab2bb3Spatrick  * \pre \c Buffer is the start of a buffer at least as big as \a
343cab2bb3Spatrick  * __llvm_profile_get_size_for_buffer_internal().
353cab2bb3Spatrick  */
363cab2bb3Spatrick int __llvm_profile_write_buffer_internal(
373cab2bb3Spatrick     char *Buffer, const __llvm_profile_data *DataBegin,
38*810390e3Srobert     const __llvm_profile_data *DataEnd, const char *CountersBegin,
39*810390e3Srobert     const char *CountersEnd, const char *NamesBegin, const char *NamesEnd);
403cab2bb3Spatrick 
413cab2bb3Spatrick /*!
423cab2bb3Spatrick  * The data structure describing the data to be written by the
433cab2bb3Spatrick  * low level writer callback function.
443cab2bb3Spatrick  *
453cab2bb3Spatrick  * If \ref ProfDataIOVec.Data is null, and \ref ProfDataIOVec.UseZeroPadding is
463cab2bb3Spatrick  * 0, the write is skipped (the writer simply advances ElmSize*NumElm bytes).
473cab2bb3Spatrick  *
483cab2bb3Spatrick  * If \ref ProfDataIOVec.Data is null, and \ref ProfDataIOVec.UseZeroPadding is
493cab2bb3Spatrick  * nonzero, ElmSize*NumElm zero bytes are written.
503cab2bb3Spatrick  */
513cab2bb3Spatrick typedef struct ProfDataIOVec {
523cab2bb3Spatrick   const void *Data;
533cab2bb3Spatrick   size_t ElmSize;
543cab2bb3Spatrick   size_t NumElm;
553cab2bb3Spatrick   int UseZeroPadding;
563cab2bb3Spatrick } ProfDataIOVec;
573cab2bb3Spatrick 
583cab2bb3Spatrick struct ProfDataWriter;
593cab2bb3Spatrick typedef uint32_t (*WriterCallback)(struct ProfDataWriter *This, ProfDataIOVec *,
603cab2bb3Spatrick                                    uint32_t NumIOVecs);
613cab2bb3Spatrick 
623cab2bb3Spatrick typedef struct ProfDataWriter {
633cab2bb3Spatrick   WriterCallback Write;
643cab2bb3Spatrick   void *WriterCtx;
653cab2bb3Spatrick } ProfDataWriter;
663cab2bb3Spatrick 
673cab2bb3Spatrick /*!
683cab2bb3Spatrick  * The data structure for buffered IO of profile data.
693cab2bb3Spatrick  */
703cab2bb3Spatrick typedef struct ProfBufferIO {
713cab2bb3Spatrick   ProfDataWriter *FileWriter;
723cab2bb3Spatrick   uint32_t OwnFileWriter;
733cab2bb3Spatrick   /* The start of the buffer. */
743cab2bb3Spatrick   uint8_t *BufferStart;
753cab2bb3Spatrick   /* Total size of the buffer. */
763cab2bb3Spatrick   uint32_t BufferSz;
773cab2bb3Spatrick   /* Current byte offset from the start of the buffer. */
783cab2bb3Spatrick   uint32_t CurOffset;
793cab2bb3Spatrick } ProfBufferIO;
803cab2bb3Spatrick 
813cab2bb3Spatrick /* The creator interface used by testing.  */
823cab2bb3Spatrick ProfBufferIO *lprofCreateBufferIOInternal(void *File, uint32_t BufferSz);
833cab2bb3Spatrick 
843cab2bb3Spatrick /*!
853cab2bb3Spatrick  * This is the interface to create a handle for buffered IO.
863cab2bb3Spatrick  */
873cab2bb3Spatrick ProfBufferIO *lprofCreateBufferIO(ProfDataWriter *FileWriter);
883cab2bb3Spatrick 
893cab2bb3Spatrick /*!
903cab2bb3Spatrick  * The interface to destroy the bufferIO handle and reclaim
913cab2bb3Spatrick  * the memory.
923cab2bb3Spatrick  */
933cab2bb3Spatrick void lprofDeleteBufferIO(ProfBufferIO *BufferIO);
943cab2bb3Spatrick 
953cab2bb3Spatrick /*!
963cab2bb3Spatrick  * This is the interface to write \c Data of \c Size bytes through
973cab2bb3Spatrick  * \c BufferIO. Returns 0 if successful, otherwise return -1.
983cab2bb3Spatrick  */
993cab2bb3Spatrick int lprofBufferIOWrite(ProfBufferIO *BufferIO, const uint8_t *Data,
1003cab2bb3Spatrick                        uint32_t Size);
1013cab2bb3Spatrick /*!
1023cab2bb3Spatrick  * The interface to flush the remaining data in the buffer.
1033cab2bb3Spatrick  * through the low level writer callback.
1043cab2bb3Spatrick  */
1053cab2bb3Spatrick int lprofBufferIOFlush(ProfBufferIO *BufferIO);
1063cab2bb3Spatrick 
1073cab2bb3Spatrick /* The low level interface to write data into a buffer. It is used as the
1083cab2bb3Spatrick  * callback by other high level writer methods such as buffered IO writer
1093cab2bb3Spatrick  * and profile data writer.  */
1103cab2bb3Spatrick uint32_t lprofBufferWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
1113cab2bb3Spatrick                            uint32_t NumIOVecs);
1123cab2bb3Spatrick void initBufferWriter(ProfDataWriter *BufferWriter, char *Buffer);
1133cab2bb3Spatrick 
1143cab2bb3Spatrick struct ValueProfData;
1153cab2bb3Spatrick struct ValueProfRecord;
1163cab2bb3Spatrick struct InstrProfValueData;
1173cab2bb3Spatrick struct ValueProfNode;
1183cab2bb3Spatrick 
1193cab2bb3Spatrick /*!
1203cab2bb3Spatrick  * The class that defines a set of methods to read value profile
1213cab2bb3Spatrick  * data for streaming/serialization from the instrumentation runtime.
1223cab2bb3Spatrick  */
1233cab2bb3Spatrick typedef struct VPDataReaderType {
1243cab2bb3Spatrick   uint32_t (*InitRTRecord)(const __llvm_profile_data *Data,
1253cab2bb3Spatrick                            uint8_t *SiteCountArray[]);
1263cab2bb3Spatrick   /* Function pointer to getValueProfRecordHeader method. */
1273cab2bb3Spatrick   uint32_t (*GetValueProfRecordHeaderSize)(uint32_t NumSites);
1283cab2bb3Spatrick   /* Function pointer to getFristValueProfRecord method. */
1293cab2bb3Spatrick   struct ValueProfRecord *(*GetFirstValueProfRecord)(struct ValueProfData *);
1303cab2bb3Spatrick   /* Return the number of value data for site \p Site.  */
1313cab2bb3Spatrick   uint32_t (*GetNumValueDataForSite)(uint32_t VK, uint32_t Site);
1323cab2bb3Spatrick   /* Return the total size of the value profile data of the
1333cab2bb3Spatrick    * current function.  */
1343cab2bb3Spatrick   uint32_t (*GetValueProfDataSize)(void);
1353cab2bb3Spatrick   /*!
1363cab2bb3Spatrick    * Read the next \p N value data for site \p Site and store the data
1373cab2bb3Spatrick    * in \p Dst. \p StartNode is the first value node to start with if
1383cab2bb3Spatrick    * it is not null. The function returns the pointer to the value
1393cab2bb3Spatrick    * node pointer to be used as the \p StartNode of the next batch reading.
1403cab2bb3Spatrick    * If there is nothing left, it returns NULL.
1413cab2bb3Spatrick    */
1423cab2bb3Spatrick   struct ValueProfNode *(*GetValueData)(uint32_t ValueKind, uint32_t Site,
1433cab2bb3Spatrick                                         struct InstrProfValueData *Dst,
1443cab2bb3Spatrick                                         struct ValueProfNode *StartNode,
1453cab2bb3Spatrick                                         uint32_t N);
1463cab2bb3Spatrick } VPDataReaderType;
1473cab2bb3Spatrick 
148*810390e3Srobert /* Write profile data to destination. If SkipNameDataWrite is set to 1,
149*810390e3Srobert    the name data is already in destination, we just skip over it. */
1503cab2bb3Spatrick int lprofWriteData(ProfDataWriter *Writer, VPDataReaderType *VPDataReader,
1513cab2bb3Spatrick                    int SkipNameDataWrite);
1523cab2bb3Spatrick int lprofWriteDataImpl(ProfDataWriter *Writer,
1533cab2bb3Spatrick                        const __llvm_profile_data *DataBegin,
1543cab2bb3Spatrick                        const __llvm_profile_data *DataEnd,
155*810390e3Srobert                        const char *CountersBegin, const char *CountersEnd,
1563cab2bb3Spatrick                        VPDataReaderType *VPDataReader, const char *NamesBegin,
1573cab2bb3Spatrick                        const char *NamesEnd, int SkipNameDataWrite);
1583cab2bb3Spatrick 
1593cab2bb3Spatrick /* Merge value profile data pointed to by SrcValueProfData into
1603cab2bb3Spatrick  * in-memory profile counters pointed by to DstData.  */
1613cab2bb3Spatrick void lprofMergeValueProfData(struct ValueProfData *SrcValueProfData,
1623cab2bb3Spatrick                              __llvm_profile_data *DstData);
1633cab2bb3Spatrick 
1643cab2bb3Spatrick VPDataReaderType *lprofGetVPDataReader();
1653cab2bb3Spatrick 
1663cab2bb3Spatrick /* Internal interface used by test to reset the max number of
1673cab2bb3Spatrick  * tracked values per value site to be \p MaxVals.
1683cab2bb3Spatrick  */
1693cab2bb3Spatrick void lprofSetMaxValsPerSite(uint32_t MaxVals);
1703cab2bb3Spatrick void lprofSetupValueProfiler();
1713cab2bb3Spatrick 
1723cab2bb3Spatrick /* Return the profile header 'signature' value associated with the current
1733cab2bb3Spatrick  * executable or shared library. The signature value can be used to for
1743cab2bb3Spatrick  * a profile name that is unique to this load module so that it does not
1753cab2bb3Spatrick  * collide with profiles from other binaries. It also allows shared libraries
1763cab2bb3Spatrick  * to dump merged profile data into its own profile file. */
1773cab2bb3Spatrick uint64_t lprofGetLoadModuleSignature();
1783cab2bb3Spatrick 
1793cab2bb3Spatrick /*
1803cab2bb3Spatrick  * Return non zero value if the profile data has already been
1813cab2bb3Spatrick  * dumped to the file.
1823cab2bb3Spatrick  */
1831f9cb04fSpatrick unsigned lprofProfileDumped(void);
1841f9cb04fSpatrick void lprofSetProfileDumped(unsigned);
1851f9cb04fSpatrick 
1863cab2bb3Spatrick COMPILER_RT_VISIBILITY extern void (*FreeHook)(void *);
1873cab2bb3Spatrick COMPILER_RT_VISIBILITY extern uint8_t *DynamicBufferIOBuffer;
1883cab2bb3Spatrick COMPILER_RT_VISIBILITY extern uint32_t VPBufferSize;
1893cab2bb3Spatrick COMPILER_RT_VISIBILITY extern uint32_t VPMaxNumValsPerSite;
1903cab2bb3Spatrick /* Pointer to the start of static value counters to be allocted. */
1913cab2bb3Spatrick COMPILER_RT_VISIBILITY extern ValueProfNode *CurrentVNode;
1923cab2bb3Spatrick COMPILER_RT_VISIBILITY extern ValueProfNode *EndVNode;
1933cab2bb3Spatrick extern void (*VPMergeHook)(struct ValueProfData *, __llvm_profile_data *);
1943cab2bb3Spatrick 
195d89ec533Spatrick /*
196d89ec533Spatrick  * Write binary ids into profiles if writer is given.
197d89ec533Spatrick  * Return -1 if an error occurs, otherwise, return total size of binary ids.
198d89ec533Spatrick  */
199d89ec533Spatrick int __llvm_write_binary_ids(ProfDataWriter *Writer);
200d89ec533Spatrick 
2013cab2bb3Spatrick #endif
202