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