1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*
* 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 */
|