PR 68115/libfortran
[official-gcc.git] / liboffloadmic / runtime / offload_table.h
blob5602f2bfc42f3123d93beea496c3b0ceaf1132b2
1 /*
2 Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 /*! \file
32 \brief Function and Variable tables used by the runtime library
35 #ifndef OFFLOAD_TABLE_H_INCLUDED
36 #define OFFLOAD_TABLE_H_INCLUDED
38 #include "offload_util.h"
40 // Template representing double linked list of tables
41 template <typename T> class TableList {
42 public:
43 // table type
44 typedef T Table;
46 // List node
47 struct Node {
48 Table table;
49 Node* prev;
50 Node* next;
53 public:
54 explicit TableList(Node *node = 0) : m_head(node) {}
56 void add_table(Node *node) {
57 m_lock.lock();
58 if (m_head != 0) {
59 node->next = m_head;
60 m_head->prev = node;
62 m_head = node;
64 m_lock.unlock();
67 void remove_table(Node *node) {
68 if (node->next != 0) {
69 node->next->prev = node->prev;
71 if (node->prev != 0) {
72 node->prev->next = node->next;
74 if (m_head == node) {
75 m_head = node->next;
79 protected:
80 Node* m_head;
81 mutex_t m_lock;
84 // Function lookup table.
85 struct FuncTable {
86 //! Function table entry
87 /*! This table contains functions created from offload regions. */
88 /*! Each entry consists of a pointer to the function's "key"
89 and the function address. */
90 /*! Each shared library or executable may contain one such table. */
91 /*! The end of the table is marked with an entry whose name field
92 has value -1. */
93 struct Entry {
94 const char* name; //!< Name of the function
95 void* func; //!< Address of the function
98 // entries
99 const Entry *entries;
101 // max name length
102 int64_t max_name_len;
105 // Function table
106 class DLL_LOCAL FuncList : public TableList<FuncTable> {
107 public:
108 explicit FuncList(Node *node = 0) : TableList<Table>(node),
109 m_max_name_len(-1)
112 // add table to the list
113 void add_table(Node *node) {
114 // recalculate max function name length
115 m_max_name_len = -1;
117 // add table
118 TableList<Table>::add_table(node);
121 // find function address for the given name
122 const void* find_addr(const char *name);
124 // find function name for the given address
125 const char* find_name(const void *addr);
127 // max name length from all tables in the list
128 int64_t max_name_length(void);
130 // debug dump
131 void dump(void);
133 private:
134 // max name length within from all tables
135 int64_t m_max_name_len;
138 // Table entry for static variables
139 struct VarTable {
140 //! Variable table entry
141 /*! This table contains statically allocated variables marked with
142 __declspec(target(mic) or #pragma omp declare target. */
143 /*! Each entry consists of a pointer to the variable's "key",
144 the variable address and its size in bytes. */
145 /*! Because memory allocation is done from the host,
146 the MIC table does not need the size of the variable. */
147 /*! Padding to make the table entry size a power of 2 is necessary
148 to avoid "holes" between table contributions from different object
149 files on Windows when debug information is specified with /Zi. */
150 struct Entry {
151 const char* name; //!< Name of the variable
152 void* addr; //!< Address of the variable
154 #if HOST_LIBRARY
155 uint64_t size;
157 #ifdef TARGET_WINNT
158 // padding to make entry size a power of 2
159 uint64_t padding;
160 #endif // TARGET_WINNT
161 #endif
164 // Table terminated by an entry with name == -1
165 const Entry *entries;
168 // List of var tables
169 class DLL_LOCAL VarList : public TableList<VarTable> {
170 public:
171 VarList() : TableList<Table>()
174 // debug dump
175 void dump();
177 public:
179 Node * get_head() {
180 return m_head;
183 public:
184 // Entry representation in a copy buffer
185 struct BufEntry {
186 intptr_t name;
187 intptr_t addr;
190 // Calculate the number of elements in the table and
191 // returns the size of buffer for the table
192 int64_t table_size(int64_t &nelems);
194 // Copy table contents to given buffer. It is supposed to be large
195 // enough to hold all elements as string table.
196 void table_copy(void *buf, int64_t nelems);
198 // Patch name offsets in a table after it's been copied to other side
199 static void table_patch_names(void *buf, int64_t nelems);
202 DLL_LOCAL extern FuncList __offload_entries;
203 DLL_LOCAL extern FuncList __offload_funcs;
204 DLL_LOCAL extern VarList __offload_vars;
206 // Section names where the lookup tables are stored
207 #ifdef TARGET_WINNT
208 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a"
209 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z"
211 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
212 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
214 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
215 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
217 #define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
219 #pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
221 #else // TARGET_WINNT
223 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
224 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
226 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
227 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
229 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
230 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
231 #endif // TARGET_WINNT
233 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
234 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
236 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
237 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
239 #pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
240 #pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
243 // register/unregister given tables
244 extern "C" void __offload_register_tables(
245 FuncList::Node *entry_table,
246 FuncList::Node *func_table,
247 VarList::Node *var_table
250 extern "C" void __offload_unregister_tables(
251 FuncList::Node *entry_table,
252 FuncList::Node *func_table,
253 VarList::Node *var_table
257 #ifdef MYO_SUPPORT
259 #include <myotypes.h>
260 #include <myoimpl.h>
261 #include <myo.h>
263 #ifdef TARGET_WINNT
264 #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1)
265 #else // TARGET_WINNT
266 #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0)
267 #endif // TARGET_WINNT
269 // Host and Target-side MYO shared variable table entry layout
270 typedef MyoiSharedVarEntry SharedTableEntry;
272 #if HOST_LIBRARY
274 // Host-side MYO function table entry layout
275 typedef struct {
276 //! Function Name
277 const char *funcName;
278 //! Function Address
279 void *funcAddr;
280 //! Local Thunk Address
281 void *localThunkAddr;
282 #ifdef TARGET_WINNT
283 // Dummy to pad up to 32 bytes
284 void *dummy;
285 #endif // TARGET_WINNT
286 } FptrTableEntry;
288 // Host-side MYO init routine table entry layout
289 typedef struct {
290 #ifdef TARGET_WINNT
291 // Dummy to pad up to 16 bytes
292 // Function Name
293 const char *funcName;
294 #endif // TARGET_WINNT
295 void (*func)(MyoArena);
296 } InitTableEntry;
298 #else // HOST_LIBRARY
300 // Target-side MYO function table entry layout
301 typedef MyoiTargetSharedFptrEntry FptrTableEntry;
303 // Target-side MYO init routine table entry layout
304 struct InitTableEntry {
305 void (*func)(void);
308 #endif // HOST_LIBRARY
310 #ifdef TARGET_WINNT
312 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
313 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
315 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a"
316 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z"
318 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a"
319 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z"
321 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
322 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
324 #else // TARGET_WINNT
326 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
327 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
329 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable."
330 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable."
332 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable."
333 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable."
335 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
336 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
338 #endif // TARGET_WINNT
340 #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
341 #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
343 #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write)
344 #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write)
346 #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write)
347 #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write)
349 #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
350 #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
352 // List of MYO shared variable tables
353 struct MYOVarTable {
354 typedef SharedTableEntry Entry;
355 const Entry *entries;
358 class MYOVarTableList : public TableList<MYOVarTable> {
359 public:
360 MYOVarTableList() : TableList<Table>()
363 // add table to the list
364 void add_table(Node *node) {
365 // add table
366 TableList<Table>::add_table(node);
369 // debug dump
370 void dump(void);
372 // check if any shared variables
373 bool is_empty();
375 // process the table contents for ordinary variables
376 void process();
378 // process the table contents for vtable objects
379 void process_vtable();
382 // List of MYO shared function tables
383 struct MYOFuncTable {
384 typedef FptrTableEntry Entry;
385 const Entry *entries;
388 class MYOFuncTableList : public TableList<MYOFuncTable> {
389 public:
390 MYOFuncTableList() : TableList<Table>()
393 // add table to the list
394 void add_table(Node *node) {
395 // add table
396 TableList<Table>::add_table(node);
399 // debug dump
400 void dump(void);
402 // check if any shared functions
403 bool is_empty();
405 // process the table contents
406 void process();
409 // List of MYO shared variable initialization routine tables
410 struct MYOInitTable {
411 typedef InitTableEntry Entry;
412 const Entry *entries;
415 class MYOInitTableList : public TableList<MYOInitTable> {
416 public:
417 MYOInitTableList() : TableList<Table>()
420 // add table to the list
421 void add_table(Node *node) {
422 // add table
423 TableList<Table>::add_table(node);
426 // debug dump
427 void dump(void);
429 // check if any init routines
430 bool is_empty();
432 // process the table contents
433 void process();
436 extern MYOVarTableList __offload_myo_var_tables;
437 extern MYOVarTableList __offload_myo_vtable_tables;
438 extern MYOFuncTableList __offload_myo_func_tables;
439 extern MYOInitTableList __offload_myo_init_tables;
441 extern "C" void __offload_myoRegisterTables1(
442 MYOInitTableList::Node *init_table,
443 MYOVarTableList::Node *shared_table,
444 MYOVarTableList::Node *shared_vtable,
445 MYOFuncTableList::Node *fptr_table
448 extern "C" void __offload_myoRemoveTables(
449 MYOInitTableList::Node *init_table,
450 MYOVarTableList::Node *shared_table,
451 MYOVarTableList::Node *shared_vtable,
452 MYOFuncTableList::Node *fptr_table
455 #endif // MYO_SUPPORT
457 #endif // OFFLOAD_TABLE_H_INCLUDED