LLVM OpenMP* Runtime Library
ompd-specific.cpp
1 /*
2  * ompd-specific.cpp -- OpenMP debug support
3  */
4 
5 //===----------------------------------------------------------------------===//
6 //
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ompd-specific.h"
14 
15 #if OMPD_SUPPORT
16 
21 #define ompd_declare_access(t, m) uint64_t ompd_access__##t##__##m;
22 OMPD_FOREACH_ACCESS(ompd_declare_access)
23 #undef ompd_declare_access
24 
25 #define ompd_declare_sizeof_member(t, m) uint64_t ompd_sizeof__##t##__##m;
26 OMPD_FOREACH_ACCESS(ompd_declare_sizeof_member)
27 #undef ompd_declare_sizeof_member
28 
29 #define ompd_declare_bitfield(t, m) uint64_t ompd_bitfield__##t##__##m;
30 OMPD_FOREACH_BITFIELD(ompd_declare_bitfield)
31 #undef ompd_declare_bitfield
32 
33 #define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t;
34 OMPD_FOREACH_SIZEOF(ompd_declare_sizeof)
35 #undef ompd_declare_sizeof
36 
37 volatile const char **ompd_dll_locations = NULL;
38 uint64_t ompd_state = 0;
39 
40 char *ompd_env_block = NULL;
41 ompd_size_t ompd_env_block_size = 0;
42 
43 void ompd_init() {
44 
45  static int ompd_initialized = 0;
46 
47  if (ompd_initialized)
48  return;
49 
54 #define ompd_init_access(t, m) \
55  ompd_access__##t##__##m = (uint64_t) & (((t *)0)->m);
56  OMPD_FOREACH_ACCESS(ompd_init_access)
57 #undef ompd_init_access
58 
63 #define ompd_init_bitfield(t, m) \
64  ompd_bitfield__##t##__##m = 0; \
65  ((t *)(&ompd_bitfield__##t##__##m))->m = 1;
66  OMPD_FOREACH_BITFIELD(ompd_init_bitfield)
67 #undef ompd_init_bitfield
68 
73 #define ompd_init_sizeof_member(t, m) \
74  ompd_sizeof__##t##__##m = sizeof(((t *)0)->m);
75  OMPD_FOREACH_ACCESS(ompd_init_sizeof_member)
76 #undef ompd_init_sizeof_member
77 
78 #define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t);
79  OMPD_FOREACH_SIZEOF(ompd_init_sizeof)
80 #undef ompd_init_sizeof
81 
82  char *libname = NULL;
83 
84  const char *ompd_env_var = getenv("OMP_DEBUG");
85  int ompd_debug = ompd_env_var && !strcmp(ompd_env_var, "enabled");
86 
87 #if KMP_OS_UNIX
88  // Find the location of libomp.so thru dladdr and replace the libomp with
89  // libompd to get the full path of libompd
90  Dl_info dl_info;
91  int ret = dladdr((void *)ompd_init, &dl_info);
92  if (!ret) {
93  const char *err = dlerror();
94  if (ompd_debug || err)
95  fprintf(stderr,
96  "The OpenMP runtime could not determine the location of "
97  "libompd.so. If the debugger fails to load the library, make "
98  "sure to add the directory containing a compatible libompd.so "
99  "to your LD_LIBRARY_PATH%s%s\n",
100  err ? ": " : "", err ? err : "");
101  } else if (dl_info.dli_fname && strrchr(dl_info.dli_fname, '/')) {
102  int lib_path_length = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname;
103  libname =
104  (char *)malloc(lib_path_length + 12 /*for '/libompd.so' and '\0'*/);
105  strncpy(libname, dl_info.dli_fname, lib_path_length);
106  memcpy(libname + lib_path_length, "/libompd.so\0", 12);
107  }
108 #endif
109 
110  if (ompd_debug) {
111  fprintf(stderr, "OMP_OMPD active\n");
112  ompt_enabled.enabled = 1;
113  ompd_state |= OMPD_ENABLE_BP;
114  }
115 
116  ompd_initialized = 1;
117  ompd_dll_locations = (volatile const char **)malloc(3 * sizeof(const char *));
118  ompd_dll_locations[0] = "libompd.so";
119  ompd_dll_locations[1] = libname;
120  ompd_dll_locations[2] = NULL;
121  ompd_dll_locations_valid();
122 }
123 
124 void __attribute__((noinline)) ompd_dll_locations_valid(void) {
125  /* naive way of implementing hard to opt-out empty function
126  we might want to use a separate object file? */
127  asm("");
128 }
129 
130 void ompd_bp_parallel_begin(void) {
131  /* naive way of implementing hard to opt-out empty function
132  we might want to use a separate object file? */
133  asm("");
134 }
135 void ompd_bp_parallel_end(void) {
136  /* naive way of implementing hard to opt-out empty function
137  we might want to use a separate object file? */
138  asm("");
139 }
140 void ompd_bp_task_begin(void) {
141  /* naive way of implementing hard to opt-out empty function
142  we might want to use a separate object file? */
143  asm("");
144 }
145 void ompd_bp_task_end(void) {
146  /* naive way of implementing hard to opt-out empty function
147  we might want to use a separate object file? */
148  asm("");
149 }
150 void ompd_bp_thread_begin(void) {
151  /* naive way of implementing hard to opt-out empty function
152  we might want to use a separate object file? */
153  asm("");
154 }
155 void ompd_bp_thread_end(void) {
156  /* naive way of implementing hard to opt-out empty function
157  we might want to use a separate object file? */
158  asm("");
159 }
160 
161 #endif /* OMPD_SUPPORT */