Fortran] Use proper type for hidden is-present argument
[gcc.git] / liboffloadmic / runtime / offload_table.h
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