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 */
|