Mercurial > hg > CbC > CbC_gcc
diff liboffloadmic/runtime/offload_table.h @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboffloadmic/runtime/offload_table.h Fri Oct 27 22:46:09 2017 +0900 @@ -0,0 +1,468 @@ +/* + Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/*! \file + \brief Function and Variable tables used by the runtime library +*/ + +#ifndef OFFLOAD_TABLE_H_INCLUDED +#define OFFLOAD_TABLE_H_INCLUDED + +#include "offload_util.h" + +#define OFFLOAD_VERSION_16 1600 +#define OFFLOAD_VERSION_17 1700 + +// Template representing double linked list of tables +template <typename T> class TableList { +public: + // table type + typedef T Table; + + // List node + struct Node { + Table table; + Node* prev; + Node* next; + }; + +public: + explicit TableList(Node *node = 0) : m_head(node) {} + + void add_table(Node *node) { + m_lock.lock(); + if (m_head != 0) { + node->next = m_head; + m_head->prev = node; + } + m_head = node; + + m_lock.unlock(); + } + + void remove_table(Node *node) { + if (node->next != 0) { + node->next->prev = node->prev; + } + if (node->prev != 0) { + node->prev->next = node->next; + } + if (m_head == node) { + m_head = node->next; + } + } + +protected: + Node* m_head; + mutex_t m_lock; +}; + +// Function lookup table. +struct FuncTable { + //! Function table entry + /*! This table contains functions created from offload regions. */ + /*! Each entry consists of a pointer to the function's "key" + and the function address. */ + /*! Each shared library or executable may contain one such table. */ + /*! The end of the table is marked with an entry whose name field + has value -1. */ + struct Entry { + const char* name; //!< Name of the function + void* func; //!< Address of the function + }; + + // entries + const Entry *entries; + + // max name length + int64_t max_name_len; +}; + +// Function table +class DLL_LOCAL FuncList : public TableList<FuncTable> { +public: + explicit FuncList(Node *node = 0) : TableList<Table>(node), + m_max_name_len(-1) + {} + + // add table to the list + void add_table(Node *node) { + // recalculate max function name length + m_max_name_len = -1; + + // add table + TableList<Table>::add_table(node); + } + + // find function address for the given name + const void* find_addr(const char *name); + + // find function name for the given address + const char* find_name(const void *addr); + + // max name length from all tables in the list + int64_t max_name_length(void); + + // debug dump + void dump(void); + +private: + // max name length within from all tables + int64_t m_max_name_len; +}; + +#define VAR_ALLOC_TYPE uint64_t +#define OPENMP_IMPLICIT 1 // Compiler promoted openmp declare var + // due to implicit use without openmp declare +#define OPENMP_LINK 2 // Openmp link clause in openmp declare + +#define IS_OPENMP_IMPLICIT(var_alloc_type) (var_alloc_type & 1) +#define IS_OPENMP_LINK(var_alloc_type) (var_alloc_type & 2) +#define IS_OPENMP_IMPLICIT_OR_LINK(var_alloc_type) (var_alloc_type & 3) + +// Table entry for static variables +struct VarTable { + //! Variable table entry + /*! This table contains statically allocated variables marked with + __declspec(target(mic) or #pragma omp declare target. */ + /*! Each entry consists of a pointer to the variable's "key", + the variable address and its size in bytes. */ + /*! Because memory allocation is done from the host, + the MIC table does not need the size of the variable. */ + /*! Padding to make the table entry size a power of 2 is necessary + to avoid "holes" between table contributions from different object + files on Windows when debug information is specified with /Zi. */ + struct Entry { + const char* name; //!< Name of the variable + void* addr; //!< Address of the variable + +#if HOST_LIBRARY + VAR_ALLOC_TYPE var_alloc_type; + uint64_t size; +#endif + }; + + // Table terminated by an entry with name == -1 + const Entry *entries; +}; + +// List of var tables +class DLL_LOCAL VarList : public TableList<VarTable> { +public: + VarList() : TableList<Table>() + {} + + // debug dump + void dump(); + +public: + + Node * get_head() { + return m_head; + } + +public: + // Entry representation in a copy buffer + struct BufEntry { + intptr_t name; + intptr_t addr; + }; + + // Calculate the number of elements in the table and + // returns the size of buffer for the table + int64_t table_size(int64_t &nelems); + + // Copy table contents to given buffer. It is supposed to be large + // enough to hold all elements as string table. + void table_copy(void *buf, int64_t nelems); + + // Patch name offsets in a table after it's been copied to other side + static void table_patch_names(void *buf, int64_t nelems); +}; + +DLL_LOCAL extern FuncList __offload_entries; +DLL_LOCAL extern FuncList __offload_funcs; +DLL_LOCAL extern VarList __offload_vars; + +// Section names where the lookup tables are stored +#ifdef TARGET_WINNT +#define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a" +#define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z" + +#define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a" +#define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z" + +#define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a" +#define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z" + +#define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT" + +#pragma section(OFFLOAD_CRTINIT_SECTION_START, read) + +#else // TARGET_WINNT + +#define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable." +#define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable." + +#define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable." +#define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable." + +#define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable." +#define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable." +#endif // TARGET_WINNT + +#pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write) + +#pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write) + +#pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write) + + +// Set library version +extern "C" void __offload_set_version(int v); + +// register/unregister given tables +extern "C" void __offload_register_tables( + FuncList::Node *entry_table, + FuncList::Node *func_table, + VarList::Node *var_table +); + +extern "C" void __offload_unregister_tables( + FuncList::Node *entry_table, + FuncList::Node *func_table, + VarList::Node *var_table +); + + +#ifdef MYO_SUPPORT + +#include <myotypes.h> +#include <myoimpl.h> +#include <myo.h> + +#ifdef TARGET_WINNT +#define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1) +#else // TARGET_WINNT +#define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0) +#endif // TARGET_WINNT + +// Host and Target-side MYO shared variable table entry layout +typedef MyoiSharedVarEntry SharedTableEntry; + +#if HOST_LIBRARY + +// Host-side MYO function table entry layout +typedef struct { + //! Function Name + const char *funcName; + //! Function Address + void *funcAddr; + //! Local Thunk Address + void *localThunkAddr; +#ifdef TARGET_WINNT + // Dummy to pad up to 32 bytes + void *dummy; +#endif // TARGET_WINNT +} FptrTableEntry; + +// Host-side MYO init routine table entry layout +typedef struct { +#ifdef TARGET_WINNT + // Dummy to pad up to 16 bytes + // Function Name + const char *funcName; +#endif // TARGET_WINNT + void (*func)(MyoArena); +} InitTableEntry; + +#else // HOST_LIBRARY + +// Target-side MYO function table entry layout +typedef MyoiTargetSharedFptrEntry FptrTableEntry; + +// Target-side MYO init routine table entry layout +struct InitTableEntry { + void (*func)(void); +}; + +#endif // HOST_LIBRARY + +#ifdef TARGET_WINNT + +#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a" +#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z" + +#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a" +#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z" + +#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a" +#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z" + +#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a" +#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z" + +#else // TARGET_WINNT + +#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable." +#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable." + +#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable." +#define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable." + +#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable." +#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable." + +#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable." +#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable." + +#endif // TARGET_WINNT + +#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write) + +#pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write) + +#pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write) + +#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write) +#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write) + +// List of MYO shared variable tables +struct MYOVarTable { + typedef SharedTableEntry Entry; + const Entry *entries; +}; + +class MYOVarTableList : public TableList<MYOVarTable> { +public: + MYOVarTableList() : TableList<Table>() + {} + + // add table to the list + void add_table(Node *node) { + // add table + TableList<Table>::add_table(node); + } + + // debug dump + void dump(void); + + // check if any shared variables + bool is_empty(); + + // process the table contents for ordinary variables + void process(); + + // process the table contents for vtable objects + void process_vtable(); +}; + +// List of MYO shared function tables +struct MYOFuncTable { + typedef FptrTableEntry Entry; + const Entry *entries; +}; + +class MYOFuncTableList : public TableList<MYOFuncTable> { +public: + MYOFuncTableList() : TableList<Table>() + {} + + // add table to the list + void add_table(Node *node) { + // add table + TableList<Table>::add_table(node); + } + + // debug dump + void dump(void); + + // check if any shared functions + bool is_empty(); + + // process the table contents + void process(); +}; + +// List of MYO shared variable initialization routine tables +struct MYOInitTable { + typedef InitTableEntry Entry; + const Entry *entries; +}; + +class MYOInitTableList : public TableList<MYOInitTable> { +public: + MYOInitTableList() : TableList<Table>() + {} + + // add table to the list + void add_table(Node *node) { + // add table + TableList<Table>::add_table(node); + } + + // debug dump + void dump(void); + + // check if any init routines + bool is_empty(); + + // process the table contents + void process(); +}; + +extern MYOVarTableList __offload_myo_var_tables; +extern MYOVarTableList __offload_myo_vtable_tables; +extern MYOFuncTableList __offload_myo_func_tables; +extern MYOInitTableList __offload_myo_init_tables; + +extern "C" void __offload_myoRegisterTables1( + MYOInitTableList::Node *init_table, + MYOVarTableList::Node *shared_table, + MYOVarTableList::Node *shared_vtable, + MYOFuncTableList::Node *fptr_table +); + +extern "C" void __offload_myoRemoveTables( + MYOInitTableList::Node *init_table, + MYOVarTableList::Node *shared_table, + MYOVarTableList::Node *shared_vtable, + MYOFuncTableList::Node *fptr_table +); + +#endif // MYO_SUPPORT + +#endif // OFFLOAD_TABLE_H_INCLUDED