Home | History | Annotate | Download | only in profile
      1 /*===- InstrProfilingWriter.c - Write instrumentation to a file or buffer -===*\
      2 |*
      3 |*                     The LLVM Compiler Infrastructure
      4 |*
      5 |* This file is distributed under the University of Illinois Open Source
      6 |* License. See LICENSE.TXT for details.
      7 |*
      8 \*===----------------------------------------------------------------------===*/
      9 
     10 #include "InstrProfiling.h"
     11 #include "InstrProfilingInternal.h"
     12 
     13 COMPILER_RT_VISIBILITY int llvmWriteProfData(WriterCallback Writer,
     14                                              void *WriterCtx,
     15                                              const uint8_t *ValueDataBegin,
     16                                              const uint64_t ValueDataSize) {
     17   /* Match logic in __llvm_profile_write_buffer(). */
     18   const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
     19   const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
     20   const uint64_t *CountersBegin = __llvm_profile_begin_counters();
     21   const uint64_t *CountersEnd = __llvm_profile_end_counters();
     22   const char *NamesBegin = __llvm_profile_begin_names();
     23   const char *NamesEnd = __llvm_profile_end_names();
     24   return llvmWriteProfDataImpl(Writer, WriterCtx, DataBegin, DataEnd,
     25                                CountersBegin, CountersEnd, ValueDataBegin,
     26                                ValueDataSize, NamesBegin, NamesEnd);
     27 }
     28 
     29 COMPILER_RT_VISIBILITY int llvmWriteProfDataImpl(
     30     WriterCallback Writer, void *WriterCtx,
     31     const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd,
     32     const uint64_t *CountersBegin, const uint64_t *CountersEnd,
     33     const uint8_t *ValueDataBegin, const uint64_t ValueDataSize,
     34     const char *NamesBegin, const char *NamesEnd) {
     35 
     36   /* Calculate size of sections. */
     37   const uint64_t DataSize = DataEnd - DataBegin;
     38   const uint64_t CountersSize = CountersEnd - CountersBegin;
     39   const uint64_t NamesSize = NamesEnd - NamesBegin;
     40   const uint64_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize);
     41 
     42   /* Enough zeroes for padding. */
     43   const char Zeroes[sizeof(uint64_t)] = {0};
     44 
     45   /* Create the header. */
     46   __llvm_profile_header Header;
     47 
     48   if (!DataSize)
     49     return 0;
     50 
     51   /* Initialize header struture.  */
     52 #define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init;
     53 #include "InstrProfData.inc"
     54 
     55   /* Write the data. */
     56   ProfDataIOVec IOVec[] = {
     57       {&Header, sizeof(__llvm_profile_header), 1},
     58       {DataBegin, sizeof(__llvm_profile_data), DataSize},
     59       {CountersBegin, sizeof(uint64_t), CountersSize},
     60       {NamesBegin, sizeof(char), NamesSize},
     61       {Zeroes, sizeof(char), Padding}};
     62   if (Writer(IOVec, sizeof(IOVec) / sizeof(*IOVec), &WriterCtx))
     63     return -1;
     64   if (ValueDataBegin) {
     65     ProfDataIOVec IOVec2[] = {{ValueDataBegin, sizeof(char), ValueDataSize}};
     66     if (Writer(IOVec2, sizeof(IOVec2) / sizeof(*IOVec2), &WriterCtx))
     67       return -1;
     68   }
     69   return 0;
     70 }
     71