Introduce KMP_COMPILER_ICX macro to represent compilation with oneAPI compiler. Fixup flag detection and compiler ID detection in CMake. Older CMake's detect IntelLLVM as Clang. Fix compiler warnings. Fixup many of the tests to have non-empty parallel regions as they are elided by oneAPI compiler.
287 lines
10 KiB
C++
287 lines
10 KiB
C++
#include "kmp_config.h"
|
|
|
|
#if USE_DEBUGGER
|
|
/*
|
|
* kmp_debugger.cpp -- debugger 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 "kmp.h"
|
|
#include "kmp_lock.h"
|
|
#include "kmp_omp.h"
|
|
#include "kmp_str.h"
|
|
|
|
// NOTE: All variable names are known to the debugger, do not change!
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
|
|
} // extern "C"
|
|
#endif // __cplusplus
|
|
|
|
int __kmp_debugging = FALSE; // Boolean whether currently debugging OpenMP RTL.
|
|
|
|
#define offset_and_size_of(structure, field) \
|
|
{ offsetof(structure, field), sizeof(((structure *)NULL)->field) }
|
|
|
|
#define offset_and_size_not_available \
|
|
{ -1, -1 }
|
|
|
|
#define addr_and_size_of(var) \
|
|
{ (kmp_uint64)(&var), sizeof(var) }
|
|
|
|
#define nthr_buffer_size 1024
|
|
static kmp_int32 kmp_omp_nthr_info_buffer[nthr_buffer_size] = {
|
|
nthr_buffer_size * sizeof(kmp_int32)};
|
|
|
|
/* TODO: Check punctuation for various platforms here */
|
|
static char func_microtask[] = "__kmp_invoke_microtask";
|
|
static char func_fork[] = "__kmpc_fork_call";
|
|
static char func_fork_teams[] = "__kmpc_fork_teams";
|
|
|
|
// Various info about runtime structures: addresses, field offsets, sizes, etc.
|
|
kmp_omp_struct_info_t __kmp_omp_debug_struct_info = {
|
|
|
|
/* Change this only if you make a fundamental data structure change here */
|
|
KMP_OMP_VERSION,
|
|
|
|
/* sanity check. Only should be checked if versions are identical
|
|
* This is also used for backward compatibility to get the runtime
|
|
* structure size if it the runtime is older than the interface */
|
|
sizeof(kmp_omp_struct_info_t),
|
|
|
|
/* OpenMP RTL version info. */
|
|
addr_and_size_of(__kmp_version_major),
|
|
addr_and_size_of(__kmp_version_minor),
|
|
addr_and_size_of(__kmp_version_build),
|
|
addr_and_size_of(__kmp_openmp_version),
|
|
{(kmp_uint64)(__kmp_copyright) + KMP_VERSION_MAGIC_LEN,
|
|
0}, // Skip magic prefix.
|
|
|
|
/* Various globals. */
|
|
addr_and_size_of(__kmp_threads),
|
|
addr_and_size_of(__kmp_root),
|
|
addr_and_size_of(__kmp_threads_capacity),
|
|
#if KMP_USE_MONITOR
|
|
addr_and_size_of(__kmp_monitor),
|
|
#endif
|
|
#if !KMP_USE_DYNAMIC_LOCK
|
|
addr_and_size_of(__kmp_user_lock_table),
|
|
#endif
|
|
addr_and_size_of(func_microtask),
|
|
addr_and_size_of(func_fork),
|
|
addr_and_size_of(func_fork_teams),
|
|
addr_and_size_of(__kmp_team_counter),
|
|
addr_and_size_of(__kmp_task_counter),
|
|
addr_and_size_of(kmp_omp_nthr_info_buffer),
|
|
sizeof(void *),
|
|
OMP_LOCK_T_SIZE < sizeof(void *),
|
|
bs_last_barrier,
|
|
INITIAL_TASK_DEQUE_SIZE,
|
|
|
|
// thread structure information
|
|
sizeof(kmp_base_info_t),
|
|
offset_and_size_of(kmp_base_info_t, th_info),
|
|
offset_and_size_of(kmp_base_info_t, th_team),
|
|
offset_and_size_of(kmp_base_info_t, th_root),
|
|
offset_and_size_of(kmp_base_info_t, th_serial_team),
|
|
offset_and_size_of(kmp_base_info_t, th_ident),
|
|
offset_and_size_of(kmp_base_info_t, th_spin_here),
|
|
offset_and_size_of(kmp_base_info_t, th_next_waiting),
|
|
offset_and_size_of(kmp_base_info_t, th_task_team),
|
|
offset_and_size_of(kmp_base_info_t, th_current_task),
|
|
offset_and_size_of(kmp_base_info_t, th_task_state),
|
|
offset_and_size_of(kmp_base_info_t, th_bar),
|
|
offset_and_size_of(kmp_bstate_t, b_worker_arrived),
|
|
|
|
// teams information
|
|
offset_and_size_of(kmp_base_info_t, th_teams_microtask),
|
|
offset_and_size_of(kmp_base_info_t, th_teams_level),
|
|
offset_and_size_of(kmp_teams_size_t, nteams),
|
|
offset_and_size_of(kmp_teams_size_t, nth),
|
|
|
|
// kmp_desc structure (for info field above)
|
|
sizeof(kmp_desc_base_t),
|
|
offset_and_size_of(kmp_desc_base_t, ds_tid),
|
|
offset_and_size_of(kmp_desc_base_t, ds_gtid),
|
|
// On Windows* OS, ds_thread contains a thread /handle/, which is not usable,
|
|
// while thread /id/ is in ds_thread_id.
|
|
#if KMP_OS_WINDOWS
|
|
offset_and_size_of(kmp_desc_base_t, ds_thread_id),
|
|
#else
|
|
offset_and_size_of(kmp_desc_base_t, ds_thread),
|
|
#endif
|
|
|
|
// team structure information
|
|
sizeof(kmp_base_team_t),
|
|
offset_and_size_of(kmp_base_team_t, t_master_tid),
|
|
offset_and_size_of(kmp_base_team_t, t_ident),
|
|
offset_and_size_of(kmp_base_team_t, t_parent),
|
|
offset_and_size_of(kmp_base_team_t, t_nproc),
|
|
offset_and_size_of(kmp_base_team_t, t_threads),
|
|
offset_and_size_of(kmp_base_team_t, t_serialized),
|
|
offset_and_size_of(kmp_base_team_t, t_id),
|
|
offset_and_size_of(kmp_base_team_t, t_pkfn),
|
|
offset_and_size_of(kmp_base_team_t, t_task_team),
|
|
offset_and_size_of(kmp_base_team_t, t_implicit_task_taskdata),
|
|
offset_and_size_of(kmp_base_team_t, t_cancel_request),
|
|
offset_and_size_of(kmp_base_team_t, t_bar),
|
|
offset_and_size_of(kmp_balign_team_t, b_master_arrived),
|
|
offset_and_size_of(kmp_balign_team_t, b_team_arrived),
|
|
|
|
// root structure information
|
|
sizeof(kmp_base_root_t),
|
|
offset_and_size_of(kmp_base_root_t, r_root_team),
|
|
offset_and_size_of(kmp_base_root_t, r_hot_team),
|
|
offset_and_size_of(kmp_base_root_t, r_uber_thread),
|
|
offset_and_size_not_available,
|
|
|
|
// ident structure information
|
|
sizeof(ident_t),
|
|
offset_and_size_of(ident_t, psource),
|
|
offset_and_size_of(ident_t, flags),
|
|
|
|
// lock structure information
|
|
sizeof(kmp_base_queuing_lock_t),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, initialized),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, location),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, tail_id),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, head_id),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, next_ticket),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, now_serving),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, owner_id),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, depth_locked),
|
|
offset_and_size_of(kmp_base_queuing_lock_t, flags),
|
|
|
|
#if !KMP_USE_DYNAMIC_LOCK
|
|
/* Lock table. */
|
|
sizeof(kmp_lock_table_t),
|
|
offset_and_size_of(kmp_lock_table_t, used),
|
|
offset_and_size_of(kmp_lock_table_t, allocated),
|
|
offset_and_size_of(kmp_lock_table_t, table),
|
|
#endif
|
|
|
|
// Task team structure information.
|
|
sizeof(kmp_base_task_team_t),
|
|
offset_and_size_of(kmp_base_task_team_t, tt_threads_data),
|
|
offset_and_size_of(kmp_base_task_team_t, tt_found_tasks),
|
|
offset_and_size_of(kmp_base_task_team_t, tt_nproc),
|
|
offset_and_size_of(kmp_base_task_team_t, tt_unfinished_threads),
|
|
offset_and_size_of(kmp_base_task_team_t, tt_active),
|
|
|
|
// task_data_t.
|
|
sizeof(kmp_taskdata_t),
|
|
offset_and_size_of(kmp_taskdata_t, td_task_id),
|
|
offset_and_size_of(kmp_taskdata_t, td_flags),
|
|
offset_and_size_of(kmp_taskdata_t, td_team),
|
|
offset_and_size_of(kmp_taskdata_t, td_parent),
|
|
offset_and_size_of(kmp_taskdata_t, td_level),
|
|
offset_and_size_of(kmp_taskdata_t, td_ident),
|
|
offset_and_size_of(kmp_taskdata_t, td_allocated_child_tasks),
|
|
offset_and_size_of(kmp_taskdata_t, td_incomplete_child_tasks),
|
|
|
|
offset_and_size_of(kmp_taskdata_t, td_taskwait_ident),
|
|
offset_and_size_of(kmp_taskdata_t, td_taskwait_counter),
|
|
offset_and_size_of(kmp_taskdata_t, td_taskwait_thread),
|
|
|
|
offset_and_size_of(kmp_taskdata_t, td_taskgroup),
|
|
offset_and_size_of(kmp_taskgroup_t, count),
|
|
offset_and_size_of(kmp_taskgroup_t, cancel_request),
|
|
|
|
offset_and_size_of(kmp_taskdata_t, td_depnode),
|
|
offset_and_size_of(kmp_depnode_list_t, node),
|
|
offset_and_size_of(kmp_depnode_list_t, next),
|
|
offset_and_size_of(kmp_base_depnode_t, successors),
|
|
offset_and_size_of(kmp_base_depnode_t, task),
|
|
offset_and_size_of(kmp_base_depnode_t, npredecessors),
|
|
offset_and_size_of(kmp_base_depnode_t, nrefs),
|
|
offset_and_size_of(kmp_task_t, routine),
|
|
|
|
// thread_data_t.
|
|
sizeof(kmp_thread_data_t),
|
|
offset_and_size_of(kmp_base_thread_data_t, td_deque),
|
|
offset_and_size_of(kmp_base_thread_data_t, td_deque_size),
|
|
offset_and_size_of(kmp_base_thread_data_t, td_deque_head),
|
|
offset_and_size_of(kmp_base_thread_data_t, td_deque_tail),
|
|
offset_and_size_of(kmp_base_thread_data_t, td_deque_ntasks),
|
|
offset_and_size_of(kmp_base_thread_data_t, td_deque_last_stolen),
|
|
|
|
// The last field.
|
|
KMP_OMP_VERSION,
|
|
|
|
}; // __kmp_omp_debug_struct_info
|
|
|
|
#undef offset_and_size_of
|
|
#undef addr_and_size_of
|
|
|
|
/* Intel compiler on IA-32 architecture issues a warning "conversion
|
|
from "unsigned long long" to "char *" may lose significant bits"
|
|
when 64-bit value is assigned to 32-bit pointer. Use this function
|
|
to suppress the warning. */
|
|
static inline void *__kmp_convert_to_ptr(kmp_uint64 addr) {
|
|
#if KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 810) // conversion from "unsigned long long" to "char
|
|
// *" may lose significant bits
|
|
#pragma warning(disable : 1195) // conversion from integer to smaller pointer
|
|
#endif // KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
|
return (void *)addr;
|
|
#if KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
|
#pragma warning(pop)
|
|
#endif // KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
|
} // __kmp_convert_to_ptr
|
|
|
|
static int kmp_location_match(kmp_str_loc_t *loc, kmp_omp_nthr_item_t *item) {
|
|
|
|
int file_match = 0;
|
|
int func_match = 0;
|
|
int line_match = 0;
|
|
|
|
char *file = (char *)__kmp_convert_to_ptr(item->file);
|
|
char *func = (char *)__kmp_convert_to_ptr(item->func);
|
|
file_match = __kmp_str_fname_match(&loc->fname, file);
|
|
func_match =
|
|
item->func == 0 // If item->func is NULL, it allows any func name.
|
|
|| strcmp(func, "*") == 0 ||
|
|
(loc->func != NULL && strcmp(loc->func, func) == 0);
|
|
line_match =
|
|
item->begin <= loc->line &&
|
|
(item->end <= 0 ||
|
|
loc->line <= item->end); // if item->end <= 0, it means "end of file".
|
|
|
|
return (file_match && func_match && line_match);
|
|
|
|
} // kmp_location_match
|
|
|
|
int __kmp_omp_num_threads(ident_t const *ident) {
|
|
|
|
int num_threads = 0;
|
|
|
|
kmp_omp_nthr_info_t *info = (kmp_omp_nthr_info_t *)__kmp_convert_to_ptr(
|
|
__kmp_omp_debug_struct_info.nthr_info.addr);
|
|
if (info->num > 0 && info->array != 0) {
|
|
kmp_omp_nthr_item_t *items =
|
|
(kmp_omp_nthr_item_t *)__kmp_convert_to_ptr(info->array);
|
|
kmp_str_loc_t loc = __kmp_str_loc_init(ident->psource, true);
|
|
int i;
|
|
for (i = 0; i < info->num; ++i) {
|
|
if (kmp_location_match(&loc, &items[i])) {
|
|
num_threads = items[i].num_threads;
|
|
}
|
|
}
|
|
__kmp_str_loc_free(&loc);
|
|
}
|
|
|
|
return num_threads;
|
|
;
|
|
|
|
} // __kmp_omp_num_threads
|
|
#endif /* USE_DEBUGGER */
|