mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			469 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			469 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|     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
 |