| /* |
| * ompd-specific.cpp -- OpenMP debug support |
| */ |
| |
| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ompd-specific.h" |
| |
| #if OMPD_SUPPORT |
| |
| /** |
| * Declaration of symbols to hold struct size and member offset information |
| */ |
| |
| #define ompd_declare_access(t, m) uint64_t ompd_access__##t##__##m; |
| OMPD_FOREACH_ACCESS(ompd_declare_access) |
| #undef ompd_declare_access |
| |
| #define ompd_declare_sizeof_member(t, m) uint64_t ompd_sizeof__##t##__##m; |
| OMPD_FOREACH_ACCESS(ompd_declare_sizeof_member) |
| #undef ompd_declare_sizeof_member |
| |
| #define ompd_declare_bitfield(t, m) uint64_t ompd_bitfield__##t##__##m; |
| OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) |
| #undef ompd_declare_bitfield |
| |
| #define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t; |
| OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) |
| #undef ompd_declare_sizeof |
| |
| volatile const char **ompd_dll_locations = NULL; |
| uint64_t ompd_state = 0; |
| |
| char *ompd_env_block = NULL; |
| ompd_size_t ompd_env_block_size = 0; |
| |
| void ompd_init() { |
| |
| static int ompd_initialized = 0; |
| |
| if (ompd_initialized) |
| return; |
| |
| /** |
| * Calculate member offsets for structs and unions |
| */ |
| |
| #define ompd_init_access(t, m) \ |
| ompd_access__##t##__##m = (uint64_t) & (((t *)0)->m); |
| OMPD_FOREACH_ACCESS(ompd_init_access) |
| #undef ompd_init_access |
| |
| /** |
| * Create bit mask for bitfield access |
| */ |
| |
| #define ompd_init_bitfield(t, m) \ |
| ompd_bitfield__##t##__##m = 0; \ |
| ((t *)(&ompd_bitfield__##t##__##m))->m = 1; |
| OMPD_FOREACH_BITFIELD(ompd_init_bitfield) |
| #undef ompd_init_bitfield |
| |
| /** |
| * Calculate type size information |
| */ |
| |
| #define ompd_init_sizeof_member(t, m) \ |
| ompd_sizeof__##t##__##m = sizeof(((t *)0)->m); |
| OMPD_FOREACH_ACCESS(ompd_init_sizeof_member) |
| #undef ompd_init_sizeof_member |
| |
| #define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t); |
| OMPD_FOREACH_SIZEOF(ompd_init_sizeof) |
| #undef ompd_init_sizeof |
| |
| char *libname = NULL; |
| |
| #if KMP_OS_UNIX |
| // Find the location of libomp.so thru dladdr and replace the libomp with |
| // libompd to get the full path of libompd |
| Dl_info dl_info; |
| int ret = dladdr((void *)ompd_init, &dl_info); |
| if (!ret) { |
| fprintf(stderr, "%s\n", dlerror()); |
| } |
| int lib_path_length; |
| if (strrchr(dl_info.dli_fname, '/')) { |
| lib_path_length = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname; |
| libname = |
| (char *)malloc(lib_path_length + 12 /*for '/libompd.so' and '\0'*/); |
| strncpy(libname, dl_info.dli_fname, lib_path_length); |
| memcpy(libname + lib_path_length, "/libompd.so\0", 12); |
| } |
| #endif |
| |
| const char *ompd_env_var = getenv("OMP_DEBUG"); |
| if (ompd_env_var && !strcmp(ompd_env_var, "enabled")) { |
| fprintf(stderr, "OMP_OMPD active\n"); |
| ompt_enabled.enabled = 1; |
| ompd_state |= OMPD_ENABLE_BP; |
| } |
| |
| ompd_initialized = 1; |
| ompd_dll_locations = (volatile const char **)malloc(3 * sizeof(const char *)); |
| ompd_dll_locations[0] = "libompd.so"; |
| ompd_dll_locations[1] = libname; |
| ompd_dll_locations[2] = NULL; |
| ompd_dll_locations_valid(); |
| } |
| |
| void __attribute__((noinline)) ompd_dll_locations_valid(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| |
| void ompd_bp_parallel_begin(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| void ompd_bp_parallel_end(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| void ompd_bp_task_begin(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| void ompd_bp_task_end(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| void ompd_bp_thread_begin(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| void ompd_bp_thread_end(void) { |
| /* naive way of implementing hard to opt-out empty function |
| we might want to use a separate object file? */ |
| asm(""); |
| } |
| |
| #endif /* OMPD_SUPPORT */ |