]> git.ipfire.org Git - thirdparty/gcc.git/blob - liboffloadmic/runtime/offload_table.h
5602f2bfc42f3123d93beea496c3b0ceaf1132b2
[thirdparty/gcc.git] / liboffloadmic / runtime / offload_table.h
1 /*
2 Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
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.
16
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.
28 */
29
30
31 /*! \file
32 \brief Function and Variable tables used by the runtime library
33 */
34
35 #ifndef OFFLOAD_TABLE_H_INCLUDED
36 #define OFFLOAD_TABLE_H_INCLUDED
37
38 #include "offload_util.h"
39
40 // Template representing double linked list of tables
41 template <typename T> class TableList {
42 public:
43 // table type
44 typedef T Table;
45
46 // List node
47 struct Node {
48 Table table;
49 Node* prev;
50 Node* next;
51 };
52
53 public:
54 explicit TableList(Node *node = 0) : m_head(node) {}
55
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;
61 }
62 m_head = node;
63
64 m_lock.unlock();
65 }
66
67 void remove_table(Node *node) {
68 if (node->next != 0) {
69 node->next->prev = node->prev;
70 }
71 if (node->prev != 0) {
72 node->prev->next = node->next;
73 }
74 if (m_head == node) {
75 m_head = node->next;
76 }
77 }
78
79 protected:
80 Node* m_head;
81 mutex_t m_lock;
82 };
83
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
96 };
97
98 // entries
99 const Entry *entries;
100
101 // max name length
102 int64_t max_name_len;
103 };
104
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)
110 {}
111
112 // add table to the list
113 void add_table(Node *node) {
114 // recalculate max function name length
115 m_max_name_len = -1;
116
117 // add table
118 TableList<Table>::add_table(node);
119 }
120
121 // find function address for the given name
122 const void* find_addr(const char *name);
123
124 // find function name for the given address
125 const char* find_name(const void *addr);
126
127 // max name length from all tables in the list
128 int64_t max_name_length(void);
129
130 // debug dump
131 void dump(void);
132
133 private:
134 // max name length within from all tables
135 int64_t m_max_name_len;
136 };
137
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
153
154 #if HOST_LIBRARY
155 uint64_t size;
156
157 #ifdef TARGET_WINNT
158 // padding to make entry size a power of 2
159 uint64_t padding;
160 #endif // TARGET_WINNT
161 #endif
162 };
163
164 // Table terminated by an entry with name == -1
165 const Entry *entries;
166 };
167
168 // List of var tables
169 class DLL_LOCAL VarList : public TableList<VarTable> {
170 public:
171 VarList() : TableList<Table>()
172 {}
173
174 // debug dump
175 void dump();
176
177 public:
178
179 Node * get_head() {
180 return m_head;
181 }
182
183 public:
184 // Entry representation in a copy buffer
185 struct BufEntry {
186 intptr_t name;
187 intptr_t addr;
188 };
189
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);
193
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);
197
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);
200 };
201
202 DLL_LOCAL extern FuncList __offload_entries;
203 DLL_LOCAL extern FuncList __offload_funcs;
204 DLL_LOCAL extern VarList __offload_vars;
205
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"
210
211 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
212 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
213
214 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
215 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
216
217 #define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
218
219 #pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
220
221 #else // TARGET_WINNT
222
223 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
224 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
225
226 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
227 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
228
229 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
230 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
231 #endif // TARGET_WINNT
232
233 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
234 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
235
236 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
237 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
238
239 #pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
240 #pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
241
242
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
248 );
249
250 extern "C" void __offload_unregister_tables(
251 FuncList::Node *entry_table,
252 FuncList::Node *func_table,
253 VarList::Node *var_table
254 );
255
256
257 #ifdef MYO_SUPPORT
258
259 #include <myotypes.h>
260 #include <myoimpl.h>
261 #include <myo.h>
262
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
268
269 // Host and Target-side MYO shared variable table entry layout
270 typedef MyoiSharedVarEntry SharedTableEntry;
271
272 #if HOST_LIBRARY
273
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;
287
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;
297
298 #else // HOST_LIBRARY
299
300 // Target-side MYO function table entry layout
301 typedef MyoiTargetSharedFptrEntry FptrTableEntry;
302
303 // Target-side MYO init routine table entry layout
304 struct InitTableEntry {
305 void (*func)(void);
306 };
307
308 #endif // HOST_LIBRARY
309
310 #ifdef TARGET_WINNT
311
312 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
313 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
314
315 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a"
316 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z"
317
318 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a"
319 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z"
320
321 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
322 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
323
324 #else // TARGET_WINNT
325
326 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
327 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
328
329 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable."
330 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable."
331
332 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable."
333 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable."
334
335 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
336 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
337
338 #endif // TARGET_WINNT
339
340 #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
341 #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
342
343 #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write)
344 #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write)
345
346 #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write)
347 #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write)
348
349 #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
350 #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
351
352 // List of MYO shared variable tables
353 struct MYOVarTable {
354 typedef SharedTableEntry Entry;
355 const Entry *entries;
356 };
357
358 class MYOVarTableList : public TableList<MYOVarTable> {
359 public:
360 MYOVarTableList() : TableList<Table>()
361 {}
362
363 // add table to the list
364 void add_table(Node *node) {
365 // add table
366 TableList<Table>::add_table(node);
367 }
368
369 // debug dump
370 void dump(void);
371
372 // check if any shared variables
373 bool is_empty();
374
375 // process the table contents for ordinary variables
376 void process();
377
378 // process the table contents for vtable objects
379 void process_vtable();
380 };
381
382 // List of MYO shared function tables
383 struct MYOFuncTable {
384 typedef FptrTableEntry Entry;
385 const Entry *entries;
386 };
387
388 class MYOFuncTableList : public TableList<MYOFuncTable> {
389 public:
390 MYOFuncTableList() : TableList<Table>()
391 {}
392
393 // add table to the list
394 void add_table(Node *node) {
395 // add table
396 TableList<Table>::add_table(node);
397 }
398
399 // debug dump
400 void dump(void);
401
402 // check if any shared functions
403 bool is_empty();
404
405 // process the table contents
406 void process();
407 };
408
409 // List of MYO shared variable initialization routine tables
410 struct MYOInitTable {
411 typedef InitTableEntry Entry;
412 const Entry *entries;
413 };
414
415 class MYOInitTableList : public TableList<MYOInitTable> {
416 public:
417 MYOInitTableList() : TableList<Table>()
418 {}
419
420 // add table to the list
421 void add_table(Node *node) {
422 // add table
423 TableList<Table>::add_table(node);
424 }
425
426 // debug dump
427 void dump(void);
428
429 // check if any init routines
430 bool is_empty();
431
432 // process the table contents
433 void process();
434 };
435
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;
440
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
446 );
447
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
453 );
454
455 #endif // MYO_SUPPORT
456
457 #endif // OFFLOAD_TABLE_H_INCLUDED