Home | History | Annotate | Download | only in profile
      1 /*===- InstrProfilingPlatformOther.c - Profile data default platform ------===*\
      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 
     12 #if !defined(__APPLE__)
     13 #include <stdlib.h>
     14 
     15 static const __llvm_profile_data *DataFirst = NULL;
     16 static const __llvm_profile_data *DataLast = NULL;
     17 static const char *NamesFirst = NULL;
     18 static const char *NamesLast = NULL;
     19 static uint64_t *CountersFirst = NULL;
     20 static uint64_t *CountersLast = NULL;
     21 
     22 /*!
     23  * \brief Register an instrumented function.
     24  *
     25  * Calls to this are emitted by clang with -fprofile-instr-generate.  Such
     26  * calls are only required (and only emitted) on targets where we haven't
     27  * implemented linker magic to find the bounds of the sections.
     28  */
     29 __attribute__((visibility("hidden")))
     30 void __llvm_profile_register_function(void *Data_) {
     31   /* TODO: Only emit this function if we can't use linker magic. */
     32   const __llvm_profile_data *Data = (__llvm_profile_data*)Data_;
     33   if (!DataFirst) {
     34     DataFirst = Data;
     35     DataLast = Data + 1;
     36     NamesFirst = Data->Name;
     37     NamesLast = Data->Name + Data->NameSize;
     38     CountersFirst = Data->Counters;
     39     CountersLast = Data->Counters + Data->NumCounters;
     40     return;
     41   }
     42 
     43 #define UPDATE_FIRST(First, New) \
     44   First = New < First ? New : First
     45   UPDATE_FIRST(DataFirst, Data);
     46   UPDATE_FIRST(NamesFirst, Data->Name);
     47   UPDATE_FIRST(CountersFirst, Data->Counters);
     48 #undef UPDATE_FIRST
     49 
     50 #define UPDATE_LAST(Last, New) \
     51   Last = New > Last ? New : Last
     52   UPDATE_LAST(DataLast, Data + 1);
     53   UPDATE_LAST(NamesLast, Data->Name + Data->NameSize);
     54   UPDATE_LAST(CountersLast, Data->Counters + Data->NumCounters);
     55 #undef UPDATE_LAST
     56 }
     57 
     58 __attribute__((visibility("hidden")))
     59 const __llvm_profile_data *__llvm_profile_data_begin(void) {
     60   return DataFirst;
     61 }
     62 __attribute__((visibility("hidden")))
     63 const __llvm_profile_data *__llvm_profile_data_end(void) {
     64   return DataLast;
     65 }
     66 __attribute__((visibility("hidden")))
     67 const char *__llvm_profile_names_begin(void) { return NamesFirst; }
     68 __attribute__((visibility("hidden")))
     69 const char *__llvm_profile_names_end(void) { return NamesLast; }
     70 __attribute__((visibility("hidden")))
     71 uint64_t *__llvm_profile_counters_begin(void) { return CountersFirst; }
     72 __attribute__((visibility("hidden")))
     73 uint64_t *__llvm_profile_counters_end(void) { return CountersLast; }
     74 #endif
     75