]> git.ipfire.org Git - thirdparty/gcc.git/blob - liboffloadmic/runtime/ofldbegin.cpp
backport: Makefile.am (liboffloadmic_host_la_DEPENDENCIES): Remove libcoi_host and...
[thirdparty/gcc.git] / liboffloadmic / runtime / ofldbegin.cpp
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 #if HOST_LIBRARY
32 #include "offload_table.h"
33 #include "offload_myo_host.h"
34 #else
35 #include "compiler_if_target.h"
36 #include "offload_target.h"
37 #include "offload_myo_target.h"
38 #endif
39
40 // Initializes library and registers specified offload image.
41 // Don't use this declarations from offload_host.h as offload_table.h
42 // is used instead of it. Using offload_host.h contradicts with
43 // STL library compiled with VS2010.
44 extern "C" bool __offload_register_image(const void* image);
45 extern "C" void __offload_unregister_image(const void* image);
46 extern "C" bool __offload_target_image_is_executable(const void *image);
47
48 #ifdef TARGET_WINNT
49 #define ALLOCATE(name) __declspec(allocate(name))
50 #define DLL_LOCAL
51 #else // TARGET_WINNT
52 #define ALLOCATE(name) __attribute__((section(name)))
53 #define DLL_LOCAL __attribute__((visibility("hidden")))
54 #endif // TARGET_WINNT
55
56 #if HOST_LIBRARY
57 // the host program/shared library should always have __offload_target_image
58 // symbol defined. This symbol specifies the beginning of the target program
59 // image.
60 extern "C" DLL_LOCAL const void* __offload_target_image;
61 #else // HOST_LIBRARY
62 // Define a weak main which would be used on target side in case usere's
63 // source file containing main does not have offload code.
64 #pragma weak main
65 int main(void)
66 {
67 OFFLOAD_TARGET_MAIN();
68 return 0;
69 }
70
71 #pragma weak MAIN__
72 extern "C" int MAIN__(void)
73 {
74 OFFLOAD_TARGET_MAIN();
75 return 0;
76 }
77 #endif // HOST_LIBRARY
78
79 // offload section prolog
80 ALLOCATE(OFFLOAD_ENTRY_TABLE_SECTION_START)
81 #ifdef TARGET_WINNT
82 __declspec(align(sizeof(FuncTable::Entry)))
83 #endif // TARGET_WINNT
84 static FuncTable::Entry __offload_entry_table_start = { 0 };
85
86 // list element for the current module
87 static FuncList::Node __offload_entry_node = {
88 { &__offload_entry_table_start + 1, -1 },
89 0, 0
90 };
91
92 // offload fp section prolog
93 ALLOCATE(OFFLOAD_FUNC_TABLE_SECTION_START)
94 #ifdef TARGET_WINNT
95 __declspec(align(sizeof(FuncTable::Entry)))
96 #endif // TARGET_WINNT
97 static FuncTable::Entry __offload_func_table_start = { 0 };
98
99 // list element for the current module
100 static FuncList::Node __offload_func_node = {
101 { &__offload_func_table_start + 1, -1 },
102 0, 0
103 };
104
105 // offload fp section prolog
106 ALLOCATE(OFFLOAD_VAR_TABLE_SECTION_START)
107 #ifdef TARGET_WINNT
108 __declspec(align(sizeof(VarTable::Entry)))
109 #endif // TARGET_WINNT
110 static VarTable::Entry __offload_var_table_start = { 0 };
111
112 // list element for the current module
113 static VarList::Node __offload_var_node = {
114 { &__offload_var_table_start + 1 },
115 0, 0
116 };
117
118 #ifdef MYO_SUPPORT
119
120 // offload myo shared var section prolog
121 // first element is empty
122 ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_START)
123 #ifdef TARGET_WINNT
124 __declspec(align(sizeof(SharedTableEntry)))
125 #endif // TARGET_WINNT
126 static MYOVarTable::Entry __offload_myo_shared_var_start = { 0 };
127
128 // list element for the current module
129 // table entry pointer skips the empty first entry
130 static MYOVarTableList::Node __offload_myo_shared_var_node = {
131 { &__offload_myo_shared_var_start + 1 },
132 0, 0
133 };
134
135 // offload myo shared vtable section prolog
136 // first element is empty
137 ALLOCATE(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START)
138 #ifdef TARGET_WINNT
139 __declspec(align(sizeof(SharedTableEntry)))
140 #endif // TARGET_WINNT
141 static MYOVarTable::Entry __offload_myo_shared_vtable_start = { 0 };
142
143 // list element for the current module
144 // table entry pointer skips the empty first entry
145 static MYOVarTableList::Node __offload_myo_shared_vtable_node = {
146 { &__offload_myo_shared_vtable_start + 1 },
147 0, 0
148 };
149
150 // offload myo shared var init section prolog
151 // first element is empty
152 ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START)
153 #ifdef TARGET_WINNT
154 __declspec(align(sizeof(InitTableEntry)))
155 #endif // TARGET_WINNT
156 static MYOInitTable::Entry __offload_myo_init_table_start = { 0 };
157
158 // list element for the current module
159 // table entry pointer skips the empty first entry
160 static MYOInitTableList::Node __offload_myo_init_table_node = {
161 { &__offload_myo_init_table_start + 1 },
162 0, 0
163 };
164
165 // The functions and variables needed for a built-in
166 // remote function entry for vtable initialization on MIC
167
168 #if !HOST_LIBRARY
169 MyoError __offload_init_vtables(void)
170 {
171 SharedTableEntry *t_start;
172
173 //OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
174 t_start = &__offload_myo_shared_vtable_start + 1;
175 //OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, t_start);
176 while (t_start->varName != 0) {
177 //OFFLOAD_DEBUG_TRACE(4,
178 // "myo shared vtable \"%s\" &myo_ptr = %p myo_ptr = %p\n",
179 // t_start->varName,
180 // (void *)(t_start->sharedAddr),
181 // ((void **)(t_start->sharedAddr))[0]);
182 t_start++;
183 }
184
185 __offload_myo_shared_init_table_process(
186 &__offload_myo_init_table_start + 1);
187 return MYO_SUCCESS;
188 }
189 #endif // !HOST_LIBRARY
190
191 static void vtable_initializer()
192 {
193 }
194
195 #if !HOST_LIBRARY
196 static MyoError vtable_initializer_wrapper()
197 {
198 __offload_myoAcquire();
199 __offload_init_vtables();
200 __offload_myoRelease();
201 return MYO_SUCCESS;
202 }
203 #endif
204
205 static void* __offload_vtable_initializer_thunk_ptr = 0;
206
207 // offload myo fptr section prolog
208 // first element is pre-initialized to the MIC vtable initializer
209 ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_START)
210 #ifdef TARGET_WINNT
211 __declspec(align(sizeof(FptrTableEntry)))
212 #endif // TARGET_WINNT
213 static MYOFuncTable::Entry __offload_myo_fptr_table_start = {
214 #if HOST_LIBRARY
215 "--vtable_initializer--",
216 (void*)&vtable_initializer,
217 (void*)&__offload_vtable_initializer_thunk_ptr,
218 #ifdef TARGET_WINNT
219 // Dummy to pad up to 32 bytes
220 0
221 #endif // TARGET_WINNT
222 #else // HOST_LIBRARY
223 "--vtable_initializer--",
224 (void*)&vtable_initializer,
225 (void*)&vtable_initializer_wrapper,
226 &__offload_vtable_initializer_thunk_ptr,
227 #endif // HOST_LIBRARY
228 };
229
230 // list element for the current module
231 static MYOFuncTableList::Node __offload_myo_fptr_table_node = {
232 { &__offload_myo_fptr_table_start },
233 0, 0
234 };
235
236 #endif // MYO_SUPPORT
237
238 // init/fini code which adds/removes local lookup data to/from the global list
239
240 static void offload_fini();
241 static void offload_fini_so();
242
243 #ifndef TARGET_WINNT
244 static void offload_init() __attribute__((constructor(101)));
245 #else // TARGET_WINNT
246 static void offload_init();
247
248 // Place offload initialization before user constructors
249 ALLOCATE(OFFLOAD_CRTINIT_SECTION_START)
250 static void (*addressof_offload_init)() = offload_init;
251 #endif // TARGET_WINNT
252
253 static void offload_init()
254 {
255 bool success;
256
257 // register offload tables
258 __offload_register_tables(&__offload_entry_node,
259 &__offload_func_node,
260 &__offload_var_node);
261
262 #if HOST_LIBRARY
263 success = __offload_register_image(&__offload_target_image);
264 if (!success)
265 {
266 return;
267 }
268 #endif // HOST_LIBRARY
269 #ifdef MYO_SUPPORT
270 #if HOST_LIBRARY
271 // If this was the main program register main atexit routine
272 if (__offload_myoProcessTables(
273 &__offload_target_image,
274 &__offload_myo_init_table_node,
275 &__offload_myo_shared_var_node,
276 &__offload_myo_shared_vtable_node,
277 &__offload_myo_fptr_table_node))
278 {
279 atexit(offload_fini);
280 #ifdef TARGET_WINNT
281 } else {
282 atexit(offload_fini_so);
283 #endif
284 }
285 #else // HOST_LIBRARY
286 __offload_myoProcessTables(
287 &__offload_myo_init_table_start + 1,
288 &__offload_myo_shared_var_start + 1,
289 &__offload_myo_shared_vtable_start + 1,
290 &__offload_myo_fptr_table_start
291 );
292 #endif // HOST_LIBRARY
293 #endif // MYO_SUPPORT
294 }
295
296 #ifndef TARGET_WINNT
297 static void offload_fini_so() __attribute__((destructor(101)));
298 #else // TARGET_WINNT
299 static void offload_init_so();
300 #endif // TARGET_WINNT
301
302 static void offload_fini()
303 {
304 #if HOST_LIBRARY
305 __offload_unregister_image(&__offload_target_image);
306 #endif // HOST_LIBRARY
307 }
308
309 static void offload_fini_so()
310 {
311 // Offload and MYO tables need to be removed from list
312 // to prevent invalid accesses after dlclose
313 // Remove offload tables
314 __offload_unregister_tables(&__offload_entry_node,
315 &__offload_func_node,
316 &__offload_var_node);
317 #if HOST_LIBRARY
318 if(!__offload_target_image_is_executable(&__offload_target_image)) {
319 __offload_unregister_image(&__offload_target_image);
320 }
321 #endif
322 #ifdef MYO_SUPPORT
323 #if HOST_LIBRARY
324 // Remove MYO tables
325 __offload_myoRemoveTables(
326 &__offload_myo_init_table_node,
327 &__offload_myo_shared_var_node,
328 &__offload_myo_shared_vtable_node,
329 &__offload_myo_fptr_table_node);
330 #endif // HOST_LIBRARY
331 #endif // MYO_SUPPORT
332 }