summaryrefslogtreecommitdiffstats
path: root/openmp/offload/src/offload_table.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'openmp/offload/src/offload_table.cpp')
-rw-r--r--openmp/offload/src/offload_table.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/openmp/offload/src/offload_table.cpp b/openmp/offload/src/offload_table.cpp
new file mode 100644
index 00000000000..cf165df9c2d
--- /dev/null
+++ b/openmp/offload/src/offload_table.cpp
@@ -0,0 +1,375 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.txt for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "offload_table.h"
+#include "offload_common.h"
+
+#if !HOST_LIBRARY
+// Predefined offload entries
+extern void omp_set_num_threads_lrb(void*);
+extern void omp_get_max_threads_lrb(void*);
+extern void omp_get_num_procs_lrb(void*);
+extern void omp_set_dynamic_lrb(void*);
+extern void omp_get_dynamic_lrb(void*);
+extern void omp_set_nested_lrb(void*);
+extern void omp_get_nested_lrb(void*);
+extern void omp_set_schedule_lrb(void*);
+extern void omp_get_schedule_lrb(void*);
+
+extern void omp_init_lock_lrb(void*);
+extern void omp_destroy_lock_lrb(void*);
+extern void omp_set_lock_lrb(void*);
+extern void omp_unset_lock_lrb(void*);
+extern void omp_test_lock_lrb(void*);
+
+extern void omp_init_nest_lock_lrb(void*);
+extern void omp_destroy_nest_lock_lrb(void*);
+extern void omp_set_nest_lock_lrb(void*);
+extern void omp_unset_nest_lock_lrb(void*);
+extern void omp_test_nest_lock_lrb(void*);
+
+extern void kmp_set_stacksize_lrb(void*);
+extern void kmp_get_stacksize_lrb(void*);
+extern void kmp_set_stacksize_s_lrb(void*);
+extern void kmp_get_stacksize_s_lrb(void*);
+extern void kmp_set_blocktime_lrb(void*);
+extern void kmp_get_blocktime_lrb(void*);
+extern void kmp_set_library_serial_lrb(void*);
+extern void kmp_set_library_turnaround_lrb(void*);
+extern void kmp_set_library_throughput_lrb(void*);
+extern void kmp_set_library_lrb(void*);
+extern void kmp_get_library_lrb(void*);
+extern void kmp_set_defaults_lrb(void*);
+
+extern void kmp_create_affinity_mask_lrb(void*);
+extern void kmp_destroy_affinity_mask_lrb(void*);
+extern void kmp_set_affinity_lrb(void*);
+extern void kmp_get_affinity_lrb(void*);
+extern void kmp_get_affinity_max_proc_lrb(void*);
+extern void kmp_set_affinity_mask_proc_lrb(void*);
+extern void kmp_unset_affinity_mask_proc_lrb(void*);
+extern void kmp_get_affinity_mask_proc_lrb(void*);
+
+// Predefined entries on the target side
+static FuncTable::Entry predefined_entries[] = {
+ "omp_set_num_threads_target",
+ (void*) &omp_set_num_threads_lrb,
+ "omp_get_max_threads_target",
+ (void*) &omp_get_max_threads_lrb,
+ "omp_get_num_procs_target",
+ (void*) &omp_get_num_procs_lrb,
+ "omp_set_dynamic_target",
+ (void*) &omp_set_dynamic_lrb,
+ "omp_get_dynamic_target",
+ (void*) &omp_get_dynamic_lrb,
+ "omp_set_nested_target",
+ (void*) &omp_set_nested_lrb,
+ "omp_get_nested_target",
+ (void*) &omp_get_nested_lrb,
+ "omp_set_schedule_target",
+ (void*) &omp_set_schedule_lrb,
+ "omp_get_schedule_target",
+ (void*) &omp_get_schedule_lrb,
+
+ "omp_init_lock_target",
+ (void*) &omp_init_lock_lrb,
+ "omp_destroy_lock_target",
+ (void*) &omp_destroy_lock_lrb,
+ "omp_set_lock_target",
+ (void*) &omp_set_lock_lrb,
+ "omp_unset_lock_target",
+ (void*) &omp_unset_lock_lrb,
+ "omp_test_lock_target",
+ (void*) &omp_test_lock_lrb,
+
+ "omp_init_nest_lock_target",
+ (void*) &omp_init_nest_lock_lrb,
+ "omp_destroy_nest_lock_target",
+ (void*) &omp_destroy_nest_lock_lrb,
+ "omp_set_nest_lock_target",
+ (void*) &omp_set_nest_lock_lrb,
+ "omp_unset_nest_lock_target",
+ (void*) &omp_unset_nest_lock_lrb,
+ "omp_test_nest_lock_target",
+ (void*) &omp_test_nest_lock_lrb,
+
+ "kmp_set_stacksize_target",
+ (void*) &kmp_set_stacksize_lrb,
+ "kmp_get_stacksize_target",
+ (void*) &kmp_get_stacksize_lrb,
+ "kmp_set_stacksize_s_target",
+ (void*) &kmp_set_stacksize_s_lrb,
+ "kmp_get_stacksize_s_target",
+ (void*) &kmp_get_stacksize_s_lrb,
+ "kmp_set_blocktime_target",
+ (void*) &kmp_set_blocktime_lrb,
+ "kmp_get_blocktime_target",
+ (void*) &kmp_get_blocktime_lrb,
+ "kmp_set_library_serial_target",
+ (void*) &kmp_set_library_serial_lrb,
+ "kmp_set_library_turnaround_target",
+ (void*) &kmp_set_library_turnaround_lrb,
+ "kmp_set_library_throughput_target",
+ (void*) &kmp_set_library_throughput_lrb,
+ "kmp_set_library_target",
+ (void*) &kmp_set_library_lrb,
+ "kmp_get_library_target",
+ (void*) &kmp_get_library_lrb,
+ "kmp_set_defaults_target",
+ (void*) &kmp_set_defaults_lrb,
+
+ "kmp_create_affinity_mask_target",
+ (void*) &kmp_create_affinity_mask_lrb,
+ "kmp_destroy_affinity_mask_target",
+ (void*) &kmp_destroy_affinity_mask_lrb,
+ "kmp_set_affinity_target",
+ (void*) &kmp_set_affinity_lrb,
+ "kmp_get_affinity_target",
+ (void*) &kmp_get_affinity_lrb,
+ "kmp_get_affinity_max_proc_target",
+ (void*) &kmp_get_affinity_max_proc_lrb,
+ "kmp_set_affinity_mask_proc_target",
+ (void*) &kmp_set_affinity_mask_proc_lrb,
+ "kmp_unset_affinity_mask_proc_target",
+ (void*) &kmp_unset_affinity_mask_proc_lrb,
+ "kmp_get_affinity_mask_proc_target",
+ (void*) &kmp_get_affinity_mask_proc_lrb,
+
+ (const char*) -1,
+ (void*) -1
+};
+
+static FuncList::Node predefined_table = {
+ { predefined_entries, -1 },
+ 0, 0
+};
+
+// Entry table
+FuncList __offload_entries(&predefined_table);
+#else
+FuncList __offload_entries;
+#endif // !HOST_LIBRARY
+
+// Function table. No predefined entries.
+FuncList __offload_funcs;
+
+// Var table
+VarList __offload_vars;
+
+// Given the function name returns the associtated function pointer
+const void* FuncList::find_addr(const char *name)
+{
+ const void* func = 0;
+
+ m_lock.lock();
+
+ for (Node *n = m_head; n != 0; n = n->next) {
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->name != 0 && strcmp(e->name, name) == 0) {
+ func = e->func;
+ break;
+ }
+ }
+ }
+
+ m_lock.unlock();
+
+ return func;
+}
+
+// Given the function pointer returns the associtated function name
+const char* FuncList::find_name(const void *func)
+{
+ const char* name = 0;
+
+ m_lock.lock();
+
+ for (Node *n = m_head; n != 0; n = n->next) {
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->func == func) {
+ name = e->name;
+ break;
+ }
+ }
+ }
+
+ m_lock.unlock();
+
+ return name;
+}
+
+// Returns max name length from all tables
+int64_t FuncList::max_name_length(void)
+{
+ if (m_max_name_len < 0) {
+ m_lock.lock();
+
+ m_max_name_len = 0;
+ for (Node *n = m_head; n != 0; n = n->next) {
+ if (n->table.max_name_len < 0) {
+ n->table.max_name_len = 0;
+
+ // calculate max name length in a single table
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->name != 0) {
+ size_t len = strlen(e->name) + 1;
+ if (n->table.max_name_len < len) {
+ n->table.max_name_len = len;
+ }
+ }
+ }
+ }
+
+ // select max from all tables
+ if (m_max_name_len < n->table.max_name_len) {
+ m_max_name_len = n->table.max_name_len;
+ }
+ }
+
+ m_lock.unlock();
+ }
+ return m_max_name_len;
+}
+
+// Debugging dump
+void FuncList::dump(void)
+{
+ OFFLOAD_DEBUG_TRACE(2, "Function table:\n");
+
+ m_lock.lock();
+
+ for (Node *n = m_head; n != 0; n = n->next) {
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->name != 0) {
+ OFFLOAD_DEBUG_TRACE(2, "%p %s\n", e->func, e->name);
+ }
+ }
+ }
+
+ m_lock.unlock();
+}
+
+// Debugging dump
+void VarList::dump(void)
+{
+ OFFLOAD_DEBUG_TRACE(2, "Var table:\n");
+
+ m_lock.lock();
+
+ for (Node *n = m_head; n != 0; n = n->next) {
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->name != 0) {
+#if HOST_LIBRARY
+ OFFLOAD_DEBUG_TRACE(2, "%s %p %ld\n", e->name, e->addr,
+ e->size);
+#else // HOST_LIBRARY
+ OFFLOAD_DEBUG_TRACE(2, "%s %p\n", e->name, e->addr);
+#endif // HOST_LIBRARY
+ }
+ }
+ }
+
+ m_lock.unlock();
+}
+
+//
+int64_t VarList::table_size(int64_t &nelems)
+{
+ int64_t length = 0;
+
+ nelems = 0;
+
+ // calculate string table size and number of elements
+ for (Node *n = m_head; n != 0; n = n->next) {
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->name != 0) {
+ length += strlen(e->name) + 1;
+ nelems++;
+ }
+ }
+ }
+
+ return nelems * sizeof(BufEntry) + length;
+}
+
+// copy table to the gven buffer
+void VarList::table_copy(void *buf, int64_t nelems)
+{
+ BufEntry* elems = static_cast<BufEntry*>(buf);
+ char* names = reinterpret_cast<char*>(elems + nelems);
+
+ // copy entries to buffer
+ for (Node *n = m_head; n != 0; n = n->next) {
+ for (const Table::Entry *e = n->table.entries;
+ e->name != (const char*) -1; e++) {
+ if (e->name != 0) {
+ // name field contains offset to the name from the beginning
+ // of the buffer
+ elems->name = names - static_cast<char*>(buf);
+ elems->addr = reinterpret_cast<intptr_t>(e->addr);
+
+ // copy name to string table
+ const char *name = e->name;
+ while ((*names++ = *name++) != '\0');
+
+ elems++;
+ }
+ }
+ }
+}
+
+// patch name offsets in a buffer
+void VarList::table_patch_names(void *buf, int64_t nelems)
+{
+ BufEntry* elems = static_cast<BufEntry*>(buf);
+ for (int i = 0; i < nelems; i++) {
+ elems[i].name += reinterpret_cast<intptr_t>(buf);
+ }
+}
+
+// Adds given list element to the global lookup table list
+extern "C" void __offload_register_tables(
+ FuncList::Node *entry_table,
+ FuncList::Node *func_table,
+ VarList::Node *var_table
+)
+{
+ OFFLOAD_DEBUG_TRACE(2, "Registering offload function entry table %p\n",
+ entry_table);
+ __offload_entries.add_table(entry_table);
+
+ OFFLOAD_DEBUG_TRACE(2, "Registering function table %p\n", func_table);
+ __offload_funcs.add_table(func_table);
+
+ OFFLOAD_DEBUG_TRACE(2, "Registering var table %p\n", var_table);
+ __offload_vars.add_table(var_table);
+}
+
+// Removes given list element from the global lookup table list
+extern "C" void __offload_unregister_tables(
+ FuncList::Node *entry_table,
+ FuncList::Node *func_table,
+ VarList::Node *var_table
+)
+{
+ __offload_entries.remove_table(entry_table);
+
+ OFFLOAD_DEBUG_TRACE(2, "Unregistering function table %p\n", func_table);
+ __offload_funcs.remove_table(func_table);
+
+ OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table);
+ __offload_vars.remove_table(var_table);
+}
OpenPOWER on IntegriCloud