/ lib / profile / InstrProfilingPlatformOther.c
InstrProfilingPlatformOther.c
 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__) && !defined(__linux__) && !defined(__FreeBSD__)
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_begin_data(void) {
60    return DataFirst;
61  }
62  __attribute__((visibility("hidden")))
63  const __llvm_profile_data *__llvm_profile_end_data(void) {
64    return DataLast;
65  }
66  __attribute__((visibility("hidden")))
67  const char *__llvm_profile_begin_names(void) { return NamesFirst; }
68  __attribute__((visibility("hidden")))
69  const char *__llvm_profile_end_names(void) { return NamesLast; }
70  __attribute__((visibility("hidden")))
71  uint64_t *__llvm_profile_begin_counters(void) { return CountersFirst; }
72  __attribute__((visibility("hidden")))
73  uint64_t *__llvm_profile_end_counters(void) { return CountersLast; }
74  #endif