offload_table.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*
  2. Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions
  5. are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of Intel Corporation nor the names of its
  12. contributors may be used to endorse or promote products derived
  13. from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  18. HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  20. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. /*! \file
  27. \brief Function and Variable tables used by the runtime library
  28. */
  29. #ifndef OFFLOAD_TABLE_H_INCLUDED
  30. #define OFFLOAD_TABLE_H_INCLUDED
  31. #include "offload_util.h"
  32. #define OFFLOAD_VERSION_16 1600
  33. #define OFFLOAD_VERSION_17 1700
  34. // Template representing double linked list of tables
  35. template <typename T> class TableList {
  36. public:
  37. // table type
  38. typedef T Table;
  39. // List node
  40. struct Node {
  41. Table table;
  42. Node* prev;
  43. Node* next;
  44. };
  45. public:
  46. explicit TableList(Node *node = 0) : m_head(node) {}
  47. void add_table(Node *node) {
  48. m_lock.lock();
  49. if (m_head != 0) {
  50. node->next = m_head;
  51. m_head->prev = node;
  52. }
  53. m_head = node;
  54. m_lock.unlock();
  55. }
  56. void remove_table(Node *node) {
  57. if (node->next != 0) {
  58. node->next->prev = node->prev;
  59. }
  60. if (node->prev != 0) {
  61. node->prev->next = node->next;
  62. }
  63. if (m_head == node) {
  64. m_head = node->next;
  65. }
  66. }
  67. protected:
  68. Node* m_head;
  69. mutex_t m_lock;
  70. };
  71. // Function lookup table.
  72. struct FuncTable {
  73. //! Function table entry
  74. /*! This table contains functions created from offload regions. */
  75. /*! Each entry consists of a pointer to the function's "key"
  76. and the function address. */
  77. /*! Each shared library or executable may contain one such table. */
  78. /*! The end of the table is marked with an entry whose name field
  79. has value -1. */
  80. struct Entry {
  81. const char* name; //!< Name of the function
  82. void* func; //!< Address of the function
  83. };
  84. // entries
  85. const Entry *entries;
  86. // max name length
  87. int64_t max_name_len;
  88. };
  89. // Function table
  90. class DLL_LOCAL FuncList : public TableList<FuncTable> {
  91. public:
  92. explicit FuncList(Node *node = 0) : TableList<Table>(node),
  93. m_max_name_len(-1)
  94. {}
  95. // add table to the list
  96. void add_table(Node *node) {
  97. // recalculate max function name length
  98. m_max_name_len = -1;
  99. // add table
  100. TableList<Table>::add_table(node);
  101. }
  102. // find function address for the given name
  103. const void* find_addr(const char *name);
  104. // find function name for the given address
  105. const char* find_name(const void *addr);
  106. // max name length from all tables in the list
  107. int64_t max_name_length(void);
  108. // debug dump
  109. void dump(void);
  110. private:
  111. // max name length within from all tables
  112. int64_t m_max_name_len;
  113. };
  114. #define VAR_ALLOC_TYPE uint64_t
  115. #define OPENMP_IMPLICIT 1 // Compiler promoted openmp declare var
  116. // due to implicit use without openmp declare
  117. #define OPENMP_LINK 2 // Openmp link clause in openmp declare
  118. #define IS_OPENMP_IMPLICIT(var_alloc_type) (var_alloc_type & 1)
  119. #define IS_OPENMP_LINK(var_alloc_type) (var_alloc_type & 2)
  120. #define IS_OPENMP_IMPLICIT_OR_LINK(var_alloc_type) (var_alloc_type & 3)
  121. // Table entry for static variables
  122. struct VarTable {
  123. //! Variable table entry
  124. /*! This table contains statically allocated variables marked with
  125. __declspec(target(mic) or #pragma omp declare target. */
  126. /*! Each entry consists of a pointer to the variable's "key",
  127. the variable address and its size in bytes. */
  128. /*! Because memory allocation is done from the host,
  129. the MIC table does not need the size of the variable. */
  130. /*! Padding to make the table entry size a power of 2 is necessary
  131. to avoid "holes" between table contributions from different object
  132. files on Windows when debug information is specified with /Zi. */
  133. struct Entry {
  134. const char* name; //!< Name of the variable
  135. void* addr; //!< Address of the variable
  136. #if HOST_LIBRARY
  137. VAR_ALLOC_TYPE var_alloc_type;
  138. uint64_t size;
  139. #endif
  140. };
  141. // Table terminated by an entry with name == -1
  142. const Entry *entries;
  143. };
  144. // List of var tables
  145. class DLL_LOCAL VarList : public TableList<VarTable> {
  146. public:
  147. VarList() : TableList<Table>()
  148. {}
  149. // debug dump
  150. void dump();
  151. public:
  152. Node * get_head() {
  153. return m_head;
  154. }
  155. public:
  156. // Entry representation in a copy buffer
  157. struct BufEntry {
  158. intptr_t name;
  159. intptr_t addr;
  160. };
  161. // Calculate the number of elements in the table and
  162. // returns the size of buffer for the table
  163. int64_t table_size(int64_t &nelems);
  164. // Copy table contents to given buffer. It is supposed to be large
  165. // enough to hold all elements as string table.
  166. void table_copy(void *buf, int64_t nelems);
  167. // Patch name offsets in a table after it's been copied to other side
  168. static void table_patch_names(void *buf, int64_t nelems);
  169. };
  170. DLL_LOCAL extern FuncList __offload_entries;
  171. DLL_LOCAL extern FuncList __offload_funcs;
  172. DLL_LOCAL extern VarList __offload_vars;
  173. // Section names where the lookup tables are stored
  174. #ifdef TARGET_WINNT
  175. #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a"
  176. #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z"
  177. #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
  178. #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
  179. #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
  180. #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
  181. #define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
  182. #pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
  183. #else // TARGET_WINNT
  184. #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
  185. #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
  186. #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
  187. #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
  188. #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
  189. #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
  190. #endif // TARGET_WINNT
  191. #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
  192. #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
  193. #pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
  194. #pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
  195. #pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
  196. #pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
  197. // Set library version
  198. extern "C" void __offload_set_version(int v);
  199. // register/unregister given tables
  200. extern "C" void __offload_register_tables(
  201. FuncList::Node *entry_table,
  202. FuncList::Node *func_table,
  203. VarList::Node *var_table
  204. );
  205. extern "C" void __offload_unregister_tables(
  206. FuncList::Node *entry_table,
  207. FuncList::Node *func_table,
  208. VarList::Node *var_table
  209. );
  210. #ifdef MYO_SUPPORT
  211. #include <myotypes.h>
  212. #include <myoimpl.h>
  213. #include <myo.h>
  214. #ifdef TARGET_WINNT
  215. #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1)
  216. #else // TARGET_WINNT
  217. #define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0)
  218. #endif // TARGET_WINNT
  219. // Host and Target-side MYO shared variable table entry layout
  220. typedef MyoiSharedVarEntry SharedTableEntry;
  221. #if HOST_LIBRARY
  222. // Host-side MYO function table entry layout
  223. typedef struct {
  224. //! Function Name
  225. const char *funcName;
  226. //! Function Address
  227. void *funcAddr;
  228. //! Local Thunk Address
  229. void *localThunkAddr;
  230. #ifdef TARGET_WINNT
  231. // Dummy to pad up to 32 bytes
  232. void *dummy;
  233. #endif // TARGET_WINNT
  234. } FptrTableEntry;
  235. // Host-side MYO init routine table entry layout
  236. typedef struct {
  237. #ifdef TARGET_WINNT
  238. // Dummy to pad up to 16 bytes
  239. // Function Name
  240. const char *funcName;
  241. #endif // TARGET_WINNT
  242. void (*func)(MyoArena);
  243. } InitTableEntry;
  244. #else // HOST_LIBRARY
  245. // Target-side MYO function table entry layout
  246. typedef MyoiTargetSharedFptrEntry FptrTableEntry;
  247. // Target-side MYO init routine table entry layout
  248. struct InitTableEntry {
  249. void (*func)(void);
  250. };
  251. #endif // HOST_LIBRARY
  252. #ifdef TARGET_WINNT
  253. #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
  254. #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
  255. #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable$a"
  256. #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable$z"
  257. #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a"
  258. #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z"
  259. #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
  260. #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
  261. #else // TARGET_WINNT
  262. #define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
  263. #define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
  264. #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_START ".MyoSharedVTable."
  265. #define OFFLOAD_MYO_SHARED_VTABLE_SECTION_END ".MyoSharedVTable."
  266. #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable."
  267. #define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable."
  268. #define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
  269. #define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
  270. #endif // TARGET_WINNT
  271. #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
  272. #pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
  273. #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START, read, write)
  274. #pragma section(OFFLOAD_MYO_SHARED_VTABLE_SECTION_END, read, write)
  275. #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write)
  276. #pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write)
  277. #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
  278. #pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
  279. // List of MYO shared variable tables
  280. struct MYOVarTable {
  281. typedef SharedTableEntry Entry;
  282. const Entry *entries;
  283. };
  284. class MYOVarTableList : public TableList<MYOVarTable> {
  285. public:
  286. MYOVarTableList() : TableList<Table>()
  287. {}
  288. // add table to the list
  289. void add_table(Node *node) {
  290. // add table
  291. TableList<Table>::add_table(node);
  292. }
  293. // debug dump
  294. void dump(void);
  295. // check if any shared variables
  296. bool is_empty();
  297. // process the table contents for ordinary variables
  298. void process();
  299. // process the table contents for vtable objects
  300. void process_vtable();
  301. };
  302. // List of MYO shared function tables
  303. struct MYOFuncTable {
  304. typedef FptrTableEntry Entry;
  305. const Entry *entries;
  306. };
  307. class MYOFuncTableList : public TableList<MYOFuncTable> {
  308. public:
  309. MYOFuncTableList() : TableList<Table>()
  310. {}
  311. // add table to the list
  312. void add_table(Node *node) {
  313. // add table
  314. TableList<Table>::add_table(node);
  315. }
  316. // debug dump
  317. void dump(void);
  318. // check if any shared functions
  319. bool is_empty();
  320. // process the table contents
  321. void process();
  322. };
  323. // List of MYO shared variable initialization routine tables
  324. struct MYOInitTable {
  325. typedef InitTableEntry Entry;
  326. const Entry *entries;
  327. };
  328. class MYOInitTableList : public TableList<MYOInitTable> {
  329. public:
  330. MYOInitTableList() : TableList<Table>()
  331. {}
  332. // add table to the list
  333. void add_table(Node *node) {
  334. // add table
  335. TableList<Table>::add_table(node);
  336. }
  337. // debug dump
  338. void dump(void);
  339. // check if any init routines
  340. bool is_empty();
  341. // process the table contents
  342. void process();
  343. };
  344. extern MYOVarTableList __offload_myo_var_tables;
  345. extern MYOVarTableList __offload_myo_vtable_tables;
  346. extern MYOFuncTableList __offload_myo_func_tables;
  347. extern MYOInitTableList __offload_myo_init_tables;
  348. extern "C" void __offload_myoRegisterTables1(
  349. MYOInitTableList::Node *init_table,
  350. MYOVarTableList::Node *shared_table,
  351. MYOVarTableList::Node *shared_vtable,
  352. MYOFuncTableList::Node *fptr_table
  353. );
  354. extern "C" void __offload_myoRemoveTables(
  355. MYOInitTableList::Node *init_table,
  356. MYOVarTableList::Node *shared_table,
  357. MYOVarTableList::Node *shared_vtable,
  358. MYOFuncTableList::Node *fptr_table
  359. );
  360. #endif // MYO_SUPPORT
  361. #endif // OFFLOAD_TABLE_H_INCLUDED