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