111
|
1 /*
|
|
2 Copyright (c) 2014-2016 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 #define OFFLOAD_VERSION_16 1600
|
|
41 #define OFFLOAD_VERSION_17 1700
|
|
42
|
|
43 // Template representing double linked list of tables
|
|
44 template <typename T> class TableList {
|
|
45 public:
|
|
46 // table type
|
|
47 typedef T Table;
|
|
48
|
|
49 // List node
|
|
50 struct Node {
|
|
51 Table table;
|
|
52 Node* prev;
|
|
53 Node* next;
|
|
54 };
|
|
55
|
|
56 public:
|
|
57 explicit TableList(Node *node = 0) : m_head(node) {}
|
|
58
|
|
59 void add_table(Node *node) {
|
|
60 m_lock.lock();
|
|
61 if (m_head != 0) {
|
|
62 node->next = m_head;
|
|
63 m_head->prev = node;
|
|
64 }
|
|
65 m_head = node;
|
|
66
|
|
67 m_lock.unlock();
|
|
68 }
|
|
69
|
|
70 void remove_table(Node *node) {
|
|
71 if (node->next != 0) {
|
|
72 node->next->prev = node->prev;
|
|
73 }
|
|
74 if (node->prev != 0) {
|
|
75 node->prev->next = node->next;
|
|
76 }
|
|
77 if (m_head == node) {
|
|
78 m_head = node->next;
|
|
79 }
|
|
80 }
|
|
81
|
|
82 protected:
|
|
83 Node* m_head;
|
|
84 mutex_t m_lock;
|
|
85 };
|
|
86
|
|
87 // Function lookup table.
|
|
88 struct FuncTable {
|
|
89 //! Function table entry
|
|
90 /*! This table contains functions created from offload regions. */
|
|
91 /*! Each entry consists of a pointer to the function's "key"
|
|
92 and the function address. */
|
|
93 /*! Each shared library or executable may contain one such table. */
|
|
94 /*! The end of the table is marked with an entry whose name field
|
|
95 has value -1. */
|
|
96 struct Entry {
|
|
97 const char* name; //!< Name of the function
|
|
98 void* func; //!< Address of the function
|
|
99 };
|
|
100
|
|
101 // entries
|
|
102 const Entry *entries;
|
|
103
|
|
104 // max name length
|
|
105 int64_t max_name_len;
|
|
106 };
|
|
107
|
|
108 // Function table
|
|
109 class DLL_LOCAL FuncList : public TableList<FuncTable> {
|
|
110 public:
|
|
111 explicit FuncList(Node *node = 0) : TableList<Table>(node),
|
|
112 m_max_name_len(-1)
|
|
113 {}
|
|
114
|
|
115 // add table to the list
|
|
116 void add_table(Node *node) {
|
|
117 // recalculate max function name length
|
|
118 m_max_name_len = -1;
|
|
119
|
|
120 // add table
|
|
121 TableList<Table>::add_table(node);
|
|
122 }
|
|
123
|
|
124 // find function address for the given name
|
|
125 const void* find_addr(const char *name);
|
|
126
|
|
127 // find function name for the given address
|
|
128 const char* find_name(const void *addr);
|
|
129
|
|
130 // max name length from all tables in the list
|
|
131 int64_t max_name_length(void);
|
|
132
|
|
133 // debug dump
|
|
134 void dump(void);
|
|
135
|
|
136 private:
|
|
137 // max name length within from all tables
|
|
138 int64_t m_max_name_len;
|
|
139 };
|
|
140
|
|
141 #define VAR_ALLOC_TYPE uint64_t
|
|
142 #define OPENMP_IMPLICIT 1 // Compiler promoted openmp declare var
|
|
143 // due to implicit use without openmp declare
|
|
144 #define OPENMP_LINK 2 // Openmp link clause in openmp declare
|
|
145
|
|
146 #define IS_OPENMP_IMPLICIT(var_alloc_type) (var_alloc_type & 1)
|
|
147 #define IS_OPENMP_LINK(var_alloc_type) (var_alloc_type & 2)
|
|
148 #define IS_OPENMP_IMPLICIT_OR_LINK(var_alloc_type) (var_alloc_type & 3)
|
|
149
|
|
150 // Table entry for static variables
|
|
151 struct VarTable {
|
|
152 //! Variable table entry
|
|
153 /*! This table contains statically allocated variables marked with
|
|
154 __declspec(target(mic) or #pragma omp declare target. */
|
|
155 /*! Each entry consists of a pointer to the variable's "key",
|
|
156 the variable address and its size in bytes. */
|
|
157 /*! Because memory allocation is done from the host,
|
|
158 the MIC table does not need the size of the variable. */
|
|
159 /*! Padding to make the table entry size a power of 2 is necessary
|
|
160 to avoid "holes" between table contributions from different object
|
|
161 files on Windows when debug information is specified with /Zi. */
|
|
162 struct Entry {
|
|
163 const char* name; //!< Name of the variable
|
|
164 void* addr; //!< Address of the variable
|
|
165
|
|
166 #if HOST_LIBRARY
|
|
167 VAR_ALLOC_TYPE var_alloc_type;
|
|
168 uint64_t size;
|
|
169 #endif
|
|
170 };
|
|
171
|
|
172 // Table terminated by an entry with name == -1
|
|
173 const Entry *entries;
|
|
174 };
|
|
175
|
|
176 // List of var tables
|
|
177 class DLL_LOCAL VarList : public TableList<VarTable> {
|
|
178 public:
|
|
179 VarList() : TableList<Table>()
|
|
180 {}
|
|
181
|
|
182 // debug dump
|
|
183 void dump();
|
|
184
|
|
185 public:
|
|
186
|
|
187 Node * get_head() {
|
|
188 return m_head;
|
|
189 }
|
|
190
|
|
191 public:
|
|
192 // Entry representation in a copy buffer
|
|
193 struct BufEntry {
|
|
194 intptr_t name;
|
|
195 intptr_t addr;
|
|
196 };
|
|
197
|
|
198 // Calculate the number of elements in the table and
|
|
199 // returns the size of buffer for the table
|
|
200 int64_t table_size(int64_t &nelems);
|
|
201
|
|
202 // Copy table contents to given buffer. It is supposed to be large
|
|
203 // enough to hold all elements as string table.
|
|
204 void table_copy(void *buf, int64_t nelems);
|
|
205
|
|
206 // Patch name offsets in a table after it's been copied to other side
|
|
207 static void table_patch_names(void *buf, int64_t nelems);
|
|
208 };
|
|
209
|
|
210 DLL_LOCAL extern FuncList __offload_entries;
|
|
211 DLL_LOCAL extern FuncList __offload_funcs;
|
|
212 DLL_LOCAL extern VarList __offload_vars;
|
|
213
|
|
214 // Section names where the lookup tables are stored
|
|
215 #ifdef TARGET_WINNT
|
|
216 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a"
|
|
217 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z"
|
|
218
|
|
219 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
|
|
220 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
|
|
221
|
|
222 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
|
|
223 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
|
|
224
|
|
225 #define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
|
|
226
|
|
227 #pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
|
|
228
|
|
229 #else // TARGET_WINNT
|
|
230
|
|
231 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
|
|
232 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
|
|
233
|
|
234 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
|
|
235 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
|
|
236
|
|
237 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
|
|
238 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
|
|
239 #endif // TARGET_WINNT
|
|
240
|
|
241 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
|
|
242 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
|
|
243
|
|
244 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
|
|
245 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
|
|
246
|
|
247 #pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
|
|
248 #pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
|
|
249
|
|
250
|
|
251 // Set library version
|
|
252 extern "C" void __offload_set_version(int v);
|
|
253
|
|
254 // register/unregister given tables
|
|
255 extern "C" void __offload_register_tables(
|
|
256 FuncList::Node *entry_table,
|
|
257 FuncList::Node *func_table,
|
|
258 VarList::Node *var_table
|
|
259 );
|
|
260
|
|
261 extern "C" void __offload_unregister_tables(
|
|
262 FuncList::Node *entry_table,
|
|
263 FuncList::Node *func_table,
|
|
264 VarList::Node *var_table
|
|
265 );
|
|
266
|
|
267
|
|
268 #ifdef MYO_SUPPORT
|
|
269
|
|
270 #include <myotypes.h>
|
|
271 #include <myoimpl.h>
|
|
272 #include <myo.h>
|
|
273
|
|
274 #ifdef TARGET_WINNT
|
|
275 #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1)
|
|
276 #else // TARGET_WINNT
|
|
277 #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0)
|
|
278 #endif // TARGET_WINNT
|
|
279
|
|
280 // Host and Target-side MYO shared variable table entry layout
|
|
281 typedef MyoiSharedVarEntry SharedTableEntry;
|
|
282
|
|
283 #if HOST_LIBRARY
|
|
284
|
|
285 // Host-side MYO function table entry layout
|
|
286 typedef struct {
|
|
287 //! Function Name
|
|
288 const char *funcName;
|
|
289 //! Function Address
|
|
290 void *funcAddr;
|
|
291 //! Local Thunk Address
|
|
292 void *localThunkAddr;
|
|
293 #ifdef TARGET_WINNT
|
|
294 // Dummy to pad up to 32 bytes
|
|
295 void *dummy;
|
|
296 #endif // TARGET_WINNT
|
|
297 } FptrTableEntry;
|
|
298
|
|
299 // Host-side MYO init routine table entry layout
|
|
300 typedef struct {
|
|
301 #ifdef TARGET_WINNT
|
|
302 // Dummy to pad up to 16 bytes
|
|
303 // Function Name
|
|
304 const char *funcName;
|
|
305 #endif // TARGET_WINNT
|
|
306 void (*func)(MyoArena);
|
|
307 } InitTableEntry;
|
|
308
|
|
309 #else // HOST_LIBRARY
|
|
310
|
|
311 // Target-side MYO function table entry layout
|
|
312 typedef MyoiTargetSharedFptrEntry FptrTableEntry;
|
|
313
|
|
314 // Target-side MYO init routine table entry layout
|
|
315 struct InitTableEntry {
|
|
316 void (*func)(void);
|
|
317 };
|
|
318
|
|
319 #endif // HOST_LIBRARY
|
|
320
|
|
321 #ifdef TARGET_WINNT
|
|
322
|
|
323 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
|
|
324 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
|
|
325
|
|
326 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a"
|
|
327 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z"
|
|
328
|
|
329 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a"
|
|
330 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z"
|
|
331
|
|
332 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
|
|
333 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
|
|
334
|
|
335 #else // TARGET_WINNT
|
|
336
|
|
337 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
|
|
338 #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
|
|
339
|
|
340 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable."
|
|
341 #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable."
|
|
342
|
|
343 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable."
|
|
344 #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable."
|
|
345
|
|
346 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
|
|
347 #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
|
|
348
|
|
349 #endif // TARGET_WINNT
|
|
350
|
|
351 #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
|
|
352 #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
|
|
353
|
|
354 #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write)
|
|
355 #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write)
|
|
356
|
|
357 #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write)
|
|
358 #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write)
|
|
359
|
|
360 #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
|
|
361 #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
|
|
362
|
|
363 // List of MYO shared variable tables
|
|
364 struct MYOVarTable {
|
|
365 typedef SharedTableEntry Entry;
|
|
366 const Entry *entries;
|
|
367 };
|
|
368
|
|
369 class MYOVarTableList : public TableList<MYOVarTable> {
|
|
370 public:
|
|
371 MYOVarTableList() : TableList<Table>()
|
|
372 {}
|
|
373
|
|
374 // add table to the list
|
|
375 void add_table(Node *node) {
|
|
376 // add table
|
|
377 TableList<Table>::add_table(node);
|
|
378 }
|
|
379
|
|
380 // debug dump
|
|
381 void dump(void);
|
|
382
|
|
383 // check if any shared variables
|
|
384 bool is_empty();
|
|
385
|
|
386 // process the table contents for ordinary variables
|
|
387 void process();
|
|
388
|
|
389 // process the table contents for vtable objects
|
|
390 void process_vtable();
|
|
391 };
|
|
392
|
|
393 // List of MYO shared function tables
|
|
394 struct MYOFuncTable {
|
|
395 typedef FptrTableEntry Entry;
|
|
396 const Entry *entries;
|
|
397 };
|
|
398
|
|
399 class MYOFuncTableList : public TableList<MYOFuncTable> {
|
|
400 public:
|
|
401 MYOFuncTableList() : TableList<Table>()
|
|
402 {}
|
|
403
|
|
404 // add table to the list
|
|
405 void add_table(Node *node) {
|
|
406 // add table
|
|
407 TableList<Table>::add_table(node);
|
|
408 }
|
|
409
|
|
410 // debug dump
|
|
411 void dump(void);
|
|
412
|
|
413 // check if any shared functions
|
|
414 bool is_empty();
|
|
415
|
|
416 // process the table contents
|
|
417 void process();
|
|
418 };
|
|
419
|
|
420 // List of MYO shared variable initialization routine tables
|
|
421 struct MYOInitTable {
|
|
422 typedef InitTableEntry Entry;
|
|
423 const Entry *entries;
|
|
424 };
|
|
425
|
|
426 class MYOInitTableList : public TableList<MYOInitTable> {
|
|
427 public:
|
|
428 MYOInitTableList() : TableList<Table>()
|
|
429 {}
|
|
430
|
|
431 // add table to the list
|
|
432 void add_table(Node *node) {
|
|
433 // add table
|
|
434 TableList<Table>::add_table(node);
|
|
435 }
|
|
436
|
|
437 // debug dump
|
|
438 void dump(void);
|
|
439
|
|
440 // check if any init routines
|
|
441 bool is_empty();
|
|
442
|
|
443 // process the table contents
|
|
444 void process();
|
|
445 };
|
|
446
|
|
447 extern MYOVarTableList __offload_myo_var_tables;
|
|
448 extern MYOVarTableList __offload_myo_vtable_tables;
|
|
449 extern MYOFuncTableList __offload_myo_func_tables;
|
|
450 extern MYOInitTableList __offload_myo_init_tables;
|
|
451
|
|
452 extern "C" void __offload_myoRegisterTables1(
|
|
453 MYOInitTableList::Node *init_table,
|
|
454 MYOVarTableList::Node *shared_table,
|
|
455 MYOVarTableList::Node *shared_vtable,
|
|
456 MYOFuncTableList::Node *fptr_table
|
|
457 );
|
|
458
|
|
459 extern "C" void __offload_myoRemoveTables(
|
|
460 MYOInitTableList::Node *init_table,
|
|
461 MYOVarTableList::Node *shared_table,
|
|
462 MYOVarTableList::Node *shared_vtable,
|
|
463 MYOFuncTableList::Node *fptr_table
|
|
464 );
|
|
465
|
|
466 #endif // MYO_SUPPORT
|
|
467
|
|
468 #endif // OFFLOAD_TABLE_H_INCLUDED
|