]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/oacc-parallel.c
combine-stack-adj: Change return type of predicate function from int to bool
[thirdparty/gcc.git] / libgomp / oacc-parallel.c
CommitLineData
83ffe9cd 1/* Copyright (C) 2013-2023 Free Software Foundation, Inc.
41dbbb37
TS
2
3 Contributed by Mentor Embedded.
4
5 This file is part of the GNU Offloading and Multi Processing Library
6 (libgomp).
7
8 Libgomp is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
26
27/* This file handles OpenACC constructs. */
28
29#include "openacc.h"
30#include "libgomp.h"
41dbbb37
TS
31#include "gomp-constants.h"
32#include "oacc-int.h"
01c0b3b0
KT
33#ifdef HAVE_INTTYPES_H
34# include <inttypes.h> /* For PRIu64. */
35#endif
41dbbb37
TS
36#include <string.h>
37#include <stdarg.h>
38#include <assert.h>
41dbbb37 39
59d5960c
TS
40
41/* In the ABI, the GOACC_FLAGs are encoded as an inverted bitmask, so that we
42 continue to support the following two legacy values. */
43_Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_ICV) == 0,
44 "legacy GOMP_DEVICE_ICV broken");
45_Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_HOST_FALLBACK)
46 == GOACC_FLAG_HOST_FALLBACK,
47 "legacy GOMP_DEVICE_HOST_FALLBACK broken");
48
49
829c6349
CLT
50/* Handle the mapping pair that are presented when a
51 deviceptr clause is used with Fortran. */
52
53static void
54handle_ftn_pointers (size_t mapnum, void **hostaddrs, size_t *sizes,
55 unsigned short *kinds)
56{
57 int i;
58
59 for (i = 0; i < mapnum; i++)
60 {
61 unsigned short kind1 = kinds[i] & 0xff;
62
63 /* Handle Fortran deviceptr clause. */
64 if (kind1 == GOMP_MAP_FORCE_DEVICEPTR)
65 {
66 unsigned short kind2;
67
68 if (i < (signed)mapnum - 1)
69 kind2 = kinds[i + 1] & 0xff;
70 else
71 kind2 = 0xffff;
72
73 if (sizes[i] == sizeof (void *))
74 continue;
75
76 /* At this point, we're dealing with a Fortran deviceptr.
77 If the next element is not what we're expecting, then
78 this is an instance of where the deviceptr variable was
79 not used within the region and the pointer was removed
80 by the gimplifier. */
81 if (kind2 == GOMP_MAP_POINTER
82 && sizes[i + 1] == 0
83 && hostaddrs[i] == *(void **)hostaddrs[i + 1])
84 {
85 kinds[i+1] = kinds[i];
86 sizes[i+1] = sizeof (void *);
87 }
88
89 /* Invalidate the entry. */
90 hostaddrs[i] = NULL;
91 }
92 }
41dbbb37
TS
93}
94
3e32ee19 95
59d5960c 96/* Launch a possibly offloaded function with FLAGS. FN is the host fn
3e32ee19
NS
97 address. MAPNUM, HOSTADDRS, SIZES & KINDS describe the memory
98 blocks to be copied to/from the device. Varadic arguments are
99 keyed optional parameters terminated with a zero. */
41dbbb37
TS
100
101void
59d5960c 102GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
3e32ee19
NS
103 size_t mapnum, void **hostaddrs, size_t *sizes,
104 unsigned short *kinds, ...)
41dbbb37 105{
59d5960c
TS
106 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
107
41dbbb37
TS
108 va_list ap;
109 struct goacc_thread *thr;
110 struct gomp_device_descr *acc_dev;
41dbbb37
TS
111 unsigned int i;
112 struct splay_tree_key_s k;
113 splay_tree_key tgt_fn_key;
114 void (*tgt_fn);
3e32ee19
NS
115 int async = GOMP_ASYNC_SYNC;
116 unsigned dims[GOMP_DIM_MAX];
117 unsigned tag;
41dbbb37 118
01c0b3b0 119#ifdef HAVE_INTTYPES_H
3e32ee19
NS
120 gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
121 __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
01c0b3b0 122#else
3e32ee19
NS
123 gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
124 __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
01c0b3b0 125#endif
d93bdab5 126 goacc_lazy_initialize ();
41dbbb37
TS
127
128 thr = goacc_thread ();
129 acc_dev = thr->dev;
130
5fae049d
TS
131 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
132
133 acc_prof_info prof_info;
134 if (profiling_p)
135 {
136 thr->prof_info = &prof_info;
137
138 prof_info.event_type = acc_ev_compute_construct_start;
139 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
140 prof_info.version = _ACC_PROF_INFO_VERSION;
141 prof_info.device_type = acc_device_type (acc_dev->type);
142 prof_info.device_number = acc_dev->target_id;
143 prof_info.thread_id = -1;
144 prof_info.async = async;
145 prof_info.async_queue = prof_info.async;
146 prof_info.src_file = NULL;
147 prof_info.func_name = NULL;
148 prof_info.line_no = -1;
149 prof_info.end_line_no = -1;
150 prof_info.func_line_no = -1;
151 prof_info.func_end_line_no = -1;
152 }
153 acc_event_info compute_construct_event_info;
154 if (profiling_p)
155 {
156 compute_construct_event_info.other_event.event_type
157 = prof_info.event_type;
158 compute_construct_event_info.other_event.valid_bytes
159 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
160 compute_construct_event_info.other_event.parent_construct
161 = acc_construct_parallel;
162 compute_construct_event_info.other_event.implicit = 0;
163 compute_construct_event_info.other_event.tool_info = NULL;
164 }
165 acc_api_info api_info;
166 if (profiling_p)
167 {
168 thr->api_info = &api_info;
169
170 api_info.device_api = acc_device_api_none;
171 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
172 api_info.device_type = prof_info.device_type;
173 api_info.vendor = -1;
174 api_info.device_handle = NULL;
175 api_info.context_handle = NULL;
176 api_info.async_handle = NULL;
177 }
178
179 if (profiling_p)
180 goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
181 &api_info);
182
829c6349
CLT
183 handle_ftn_pointers (mapnum, hostaddrs, sizes, kinds);
184
41dbbb37
TS
185 /* Host fallback if "if" clause is false or if the current device is set to
186 the host. */
59d5960c 187 if (flags & GOACC_FLAG_HOST_FALLBACK)
41dbbb37 188 {
5fae049d
TS
189 prof_info.device_type = acc_device_host;
190 api_info.device_type = prof_info.device_type;
41dbbb37
TS
191 goacc_save_and_set_bind (acc_device_host);
192 fn (hostaddrs);
193 goacc_restore_bind ();
5fae049d 194 goto out_prof;
41dbbb37
TS
195 }
196 else if (acc_device_type (acc_dev->type) == acc_device_host)
197 {
198 fn (hostaddrs);
5fae049d 199 goto out_prof;
41dbbb37
TS
200 }
201
f99c3557
TS
202 /* Default: let the runtime choose. */
203 for (i = 0; i != GOMP_DIM_MAX; i++)
204 dims[i] = 0;
205
3e32ee19
NS
206 va_start (ap, kinds);
207 /* TODO: This will need amending when device_type is implemented. */
208 while ((tag = va_arg (ap, unsigned)) != 0)
a091118d 209 {
3e32ee19
NS
210 if (GOMP_LAUNCH_DEVICE (tag))
211 gomp_fatal ("device_type '%d' offload parameters, libgomp is too old",
212 GOMP_LAUNCH_DEVICE (tag));
213
214 switch (GOMP_LAUNCH_CODE (tag))
215 {
216 case GOMP_LAUNCH_DIM:
217 {
218 unsigned mask = GOMP_LAUNCH_OP (tag);
219
220 for (i = 0; i != GOMP_DIM_MAX; i++)
221 if (mask & GOMP_DIM_MASK (i))
222 dims[i] = va_arg (ap, unsigned);
223 }
224 break;
225
226 case GOMP_LAUNCH_ASYNC:
227 {
228 /* Small constant values are encoded in the operand. */
229 async = GOMP_LAUNCH_OP (tag);
230
231 if (async == GOMP_LAUNCH_OP_MAX)
232 async = va_arg (ap, unsigned);
5fae049d
TS
233
234 if (profiling_p)
235 {
236 prof_info.async = async;
237 prof_info.async_queue = prof_info.async;
238 }
239
3e32ee19
NS
240 break;
241 }
242
243 case GOMP_LAUNCH_WAIT:
244 {
245 unsigned num_waits = GOMP_LAUNCH_OP (tag);
19695f4d 246 goacc_wait (async, num_waits, &ap);
3e32ee19
NS
247 break;
248 }
249
250 default:
251 gomp_fatal ("unrecognized offload code '%d',"
252 " libgomp is too old", GOMP_LAUNCH_CODE (tag));
253 }
a091118d 254 }
3e32ee19 255 va_end (ap);
41dbbb37 256
41dbbb37
TS
257 if (!(acc_dev->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC))
258 {
259 k.host_start = (uintptr_t) fn;
260 k.host_end = k.host_start + 1;
a51df54e
IV
261 gomp_mutex_lock (&acc_dev->lock);
262 tgt_fn_key = splay_tree_lookup (&acc_dev->mem_map, &k);
263 gomp_mutex_unlock (&acc_dev->lock);
41dbbb37
TS
264
265 if (tgt_fn_key == NULL)
266 gomp_fatal ("target function wasn't mapped");
267
d93bdab5 268 tgt_fn = (void (*)) tgt_fn_key->tgt_offset;
41dbbb37
TS
269 }
270 else
271 tgt_fn = (void (*)) fn;
272
5fae049d
TS
273 acc_event_info enter_exit_data_event_info;
274 if (profiling_p)
275 {
276 prof_info.event_type = acc_ev_enter_data_start;
277 enter_exit_data_event_info.other_event.event_type
278 = prof_info.event_type;
279 enter_exit_data_event_info.other_event.valid_bytes
280 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
281 enter_exit_data_event_info.other_event.parent_construct
282 = compute_construct_event_info.other_event.parent_construct;
283 enter_exit_data_event_info.other_event.implicit = 1;
284 enter_exit_data_event_info.other_event.tool_info = NULL;
285 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
286 &api_info);
287 }
288
1f4c5b9b 289 goacc_aq aq = get_goacc_asyncqueue (async);
41dbbb37 290
f8332e52
TS
291 struct target_mem_desc *tgt
292 = goacc_map_vars (acc_dev, aq, mapnum, hostaddrs, NULL, sizes, kinds, true,
293 GOMP_MAP_VARS_TARGET);
294
5fae049d
TS
295 if (profiling_p)
296 {
297 prof_info.event_type = acc_ev_enter_data_end;
298 enter_exit_data_event_info.other_event.event_type
299 = prof_info.event_type;
300 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
301 &api_info);
302 }
275c736e 303
f8332e52 304 void **devaddrs = (void **) tgt->tgt_start;
1f4c5b9b 305 if (aq == NULL)
5fae049d
TS
306 acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
307 tgt);
308 else
309 acc_dev->openacc.async.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
310 dims, tgt, aq);
311
312 if (profiling_p)
1f4c5b9b 313 {
5fae049d
TS
314 prof_info.event_type = acc_ev_exit_data_start;
315 enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
316 enter_exit_data_event_info.other_event.tool_info = NULL;
317 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
318 &api_info);
1f4c5b9b 319 }
5fae049d 320
275c736e
CLT
321 /* If running synchronously (aq == NULL), this will unmap immediately. */
322 goacc_unmap_vars (tgt, true, aq);
5fae049d
TS
323
324 if (profiling_p)
829c6349 325 {
5fae049d
TS
326 prof_info.event_type = acc_ev_exit_data_end;
327 enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
328 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
329 &api_info);
330 }
331
332 out_prof:
333 if (profiling_p)
334 {
335 prof_info.event_type = acc_ev_compute_construct_end;
336 compute_construct_event_info.other_event.event_type
337 = prof_info.event_type;
338 goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
339 &api_info);
340
341 thr->prof_info = NULL;
342 thr->api_info = NULL;
829c6349 343 }
41dbbb37
TS
344}
345
2bbbfa4e 346/* Legacy entry point (GCC 5). Only provide host fallback execution. */
3e32ee19
NS
347
348void
59d5960c 349GOACC_parallel (int flags_m, void (*fn) (void *),
3e32ee19
NS
350 size_t mapnum, void **hostaddrs, size_t *sizes,
351 unsigned short *kinds,
352 int num_gangs, int num_workers, int vector_length,
353 int async, int num_waits, ...)
354{
355 goacc_save_and_set_bind (acc_device_host);
356 fn (hostaddrs);
357 goacc_restore_bind ();
358}
359
41dbbb37 360void
59d5960c 361GOACC_data_start (int flags_m, size_t mapnum,
41dbbb37
TS
362 void **hostaddrs, size_t *sizes, unsigned short *kinds)
363{
59d5960c
TS
364 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
365
41dbbb37
TS
366 struct target_mem_desc *tgt;
367
01c0b3b0
KT
368#ifdef HAVE_INTTYPES_H
369 gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
370 __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
371#else
372 gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
373 __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
374#endif
41dbbb37 375
d93bdab5 376 goacc_lazy_initialize ();
41dbbb37
TS
377
378 struct goacc_thread *thr = goacc_thread ();
379 struct gomp_device_descr *acc_dev = thr->dev;
380
5fae049d
TS
381 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
382
383 acc_prof_info prof_info;
384 if (profiling_p)
385 {
386 thr->prof_info = &prof_info;
387
388 prof_info.event_type = acc_ev_enter_data_start;
389 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
390 prof_info.version = _ACC_PROF_INFO_VERSION;
391 prof_info.device_type = acc_device_type (acc_dev->type);
392 prof_info.device_number = acc_dev->target_id;
393 prof_info.thread_id = -1;
394 prof_info.async = acc_async_sync; /* Always synchronous. */
395 prof_info.async_queue = prof_info.async;
396 prof_info.src_file = NULL;
397 prof_info.func_name = NULL;
398 prof_info.line_no = -1;
399 prof_info.end_line_no = -1;
400 prof_info.func_line_no = -1;
401 prof_info.func_end_line_no = -1;
402 }
403 acc_event_info enter_data_event_info;
404 if (profiling_p)
405 {
406 enter_data_event_info.other_event.event_type
407 = prof_info.event_type;
408 enter_data_event_info.other_event.valid_bytes
409 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
410 enter_data_event_info.other_event.parent_construct = acc_construct_data;
411 for (int i = 0; i < mapnum; ++i)
d5c23c6c
TB
412 if ((kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR
413 || (kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
5fae049d
TS
414 {
415 /* If there is one such data mapping kind, then this is actually an
416 OpenACC 'host_data' construct. (GCC maps the OpenACC
417 'host_data' construct to the OpenACC 'data' construct.) Apart
418 from artificial test cases (such as an OpenACC 'host_data'
419 construct's (implicit) device initialization when there hasn't
420 been any device data be set up before...), there can't really
421 any meaningful events be generated from OpenACC 'host_data'
422 constructs, though. */
423 enter_data_event_info.other_event.parent_construct
424 = acc_construct_host_data;
425 break;
426 }
427 enter_data_event_info.other_event.implicit = 0;
428 enter_data_event_info.other_event.tool_info = NULL;
429 }
430 acc_api_info api_info;
431 if (profiling_p)
432 {
433 thr->api_info = &api_info;
434
435 api_info.device_api = acc_device_api_none;
436 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
437 api_info.device_type = prof_info.device_type;
438 api_info.vendor = -1;
439 api_info.device_handle = NULL;
440 api_info.context_handle = NULL;
441 api_info.async_handle = NULL;
442 }
443
444 if (profiling_p)
445 goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
446
41dbbb37
TS
447 /* Host fallback or 'do nothing'. */
448 if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
59d5960c 449 || (flags & GOACC_FLAG_HOST_FALLBACK))
41dbbb37 450 {
5fae049d
TS
451 prof_info.device_type = acc_device_host;
452 api_info.device_type = prof_info.device_type;
275c736e 453 tgt = goacc_map_vars (NULL, NULL, 0, NULL, NULL, NULL, NULL, true, 0);
41dbbb37
TS
454 tgt->prev = thr->mapped_data;
455 thr->mapped_data = tgt;
456
5fae049d 457 goto out_prof;
41dbbb37
TS
458 }
459
460 gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
275c736e
CLT
461 tgt = goacc_map_vars (acc_dev, NULL, mapnum, hostaddrs, NULL, sizes, kinds,
462 true, 0);
41dbbb37
TS
463 gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
464 tgt->prev = thr->mapped_data;
465 thr->mapped_data = tgt;
5fae049d
TS
466
467 out_prof:
468 if (profiling_p)
469 {
470 prof_info.event_type = acc_ev_enter_data_end;
471 enter_data_event_info.other_event.event_type = prof_info.event_type;
472 goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
473
474 thr->prof_info = NULL;
475 thr->api_info = NULL;
476 }
41dbbb37
TS
477}
478
479void
480GOACC_data_end (void)
481{
482 struct goacc_thread *thr = goacc_thread ();
5fae049d 483 struct gomp_device_descr *acc_dev = thr->dev;
41dbbb37
TS
484 struct target_mem_desc *tgt = thr->mapped_data;
485
5fae049d
TS
486 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
487
488 acc_prof_info prof_info;
489 if (profiling_p)
490 {
491 thr->prof_info = &prof_info;
492
493 prof_info.event_type = acc_ev_exit_data_start;
494 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
495 prof_info.version = _ACC_PROF_INFO_VERSION;
496 prof_info.device_type = acc_device_type (acc_dev->type);
497 prof_info.device_number = acc_dev->target_id;
498 prof_info.thread_id = -1;
499 prof_info.async = acc_async_sync; /* Always synchronous. */
500 prof_info.async_queue = prof_info.async;
501 prof_info.src_file = NULL;
502 prof_info.func_name = NULL;
503 prof_info.line_no = -1;
504 prof_info.end_line_no = -1;
505 prof_info.func_line_no = -1;
506 prof_info.func_end_line_no = -1;
507 }
508 acc_event_info exit_data_event_info;
509 if (profiling_p)
510 {
511 exit_data_event_info.other_event.event_type
512 = prof_info.event_type;
513 exit_data_event_info.other_event.valid_bytes
514 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
515 exit_data_event_info.other_event.parent_construct = acc_construct_data;
516 exit_data_event_info.other_event.implicit = 0;
517 exit_data_event_info.other_event.tool_info = NULL;
518 }
519 acc_api_info api_info;
520 if (profiling_p)
521 {
522 thr->api_info = &api_info;
523
524 api_info.device_api = acc_device_api_none;
525 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
526 api_info.device_type = prof_info.device_type;
527 api_info.vendor = -1;
528 api_info.device_handle = NULL;
529 api_info.context_handle = NULL;
530 api_info.async_handle = NULL;
531 }
532
533 if (profiling_p)
534 goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
535
41dbbb37
TS
536 gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
537 thr->mapped_data = tgt->prev;
275c736e 538 goacc_unmap_vars (tgt, true, NULL);
41dbbb37 539 gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
5fae049d
TS
540
541 if (profiling_p)
542 {
543 prof_info.event_type = acc_ev_exit_data_end;
544 exit_data_event_info.other_event.event_type = prof_info.event_type;
545 goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
546
547 thr->prof_info = NULL;
548 thr->api_info = NULL;
549 }
41dbbb37
TS
550}
551
41dbbb37 552void
59d5960c 553GOACC_update (int flags_m, size_t mapnum,
41dbbb37
TS
554 void **hostaddrs, size_t *sizes, unsigned short *kinds,
555 int async, int num_waits, ...)
556{
59d5960c
TS
557 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
558
41dbbb37
TS
559 size_t i;
560
d93bdab5 561 goacc_lazy_initialize ();
41dbbb37
TS
562
563 struct goacc_thread *thr = goacc_thread ();
564 struct gomp_device_descr *acc_dev = thr->dev;
565
5fae049d
TS
566 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
567
568 acc_prof_info prof_info;
569 if (profiling_p)
570 {
571 thr->prof_info = &prof_info;
572
573 prof_info.event_type = acc_ev_update_start;
574 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
575 prof_info.version = _ACC_PROF_INFO_VERSION;
576 prof_info.device_type = acc_device_type (acc_dev->type);
577 prof_info.device_number = acc_dev->target_id;
578 prof_info.thread_id = -1;
579 prof_info.async = async;
580 prof_info.async_queue = prof_info.async;
581 prof_info.src_file = NULL;
582 prof_info.func_name = NULL;
583 prof_info.line_no = -1;
584 prof_info.end_line_no = -1;
585 prof_info.func_line_no = -1;
586 prof_info.func_end_line_no = -1;
587 }
588 acc_event_info update_event_info;
589 if (profiling_p)
590 {
591 update_event_info.other_event.event_type
592 = prof_info.event_type;
593 update_event_info.other_event.valid_bytes
594 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
595 update_event_info.other_event.parent_construct = acc_construct_update;
596 update_event_info.other_event.implicit = 0;
597 update_event_info.other_event.tool_info = NULL;
598 }
599 acc_api_info api_info;
600 if (profiling_p)
601 {
602 thr->api_info = &api_info;
603
604 api_info.device_api = acc_device_api_none;
605 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
606 api_info.device_type = prof_info.device_type;
607 api_info.vendor = -1;
608 api_info.device_handle = NULL;
609 api_info.context_handle = NULL;
610 api_info.async_handle = NULL;
611 }
612
613 if (profiling_p)
614 goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
615
41dbbb37 616 if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
59d5960c 617 || (flags & GOACC_FLAG_HOST_FALLBACK))
5fae049d
TS
618 {
619 prof_info.device_type = acc_device_host;
620 api_info.device_type = prof_info.device_type;
621
622 goto out_prof;
623 }
41dbbb37 624
a091118d 625 if (num_waits)
41dbbb37
TS
626 {
627 va_list ap;
628
629 va_start (ap, num_waits);
3e32ee19 630 goacc_wait (async, num_waits, &ap);
41dbbb37
TS
631 va_end (ap);
632 }
633
829c6349 634 bool update_device = false;
41dbbb37
TS
635 for (i = 0; i < mapnum; ++i)
636 {
637 unsigned char kind = kinds[i] & 0xff;
638
639 switch (kind)
640 {
641 case GOMP_MAP_POINTER:
642 case GOMP_MAP_TO_PSET:
643 break;
644
829c6349
CLT
645 case GOMP_MAP_ALWAYS_POINTER:
646 if (update_device)
647 {
648 /* Save the contents of the host pointer. */
649 void *dptr = acc_deviceptr (hostaddrs[i-1]);
650 uintptr_t t = *(uintptr_t *) hostaddrs[i];
651
652 /* Update the contents of the host pointer to reflect
653 the value of the allocated device memory in the
654 previous pointer. */
655 *(uintptr_t *) hostaddrs[i] = (uintptr_t)dptr;
1f4c5b9b
CLT
656 /* TODO: verify that we really cannot use acc_update_device_async
657 here. */
829c6349
CLT
658 acc_update_device (hostaddrs[i], sizeof (uintptr_t));
659
660 /* Restore the host pointer. */
661 *(uintptr_t *) hostaddrs[i] = t;
662 update_device = false;
663 }
664 break;
665
666 case GOMP_MAP_TO:
667 if (!acc_is_present (hostaddrs[i], sizes[i]))
668 {
669 update_device = false;
670 break;
671 }
672 /* Fallthru */
41dbbb37 673 case GOMP_MAP_FORCE_TO:
829c6349 674 update_device = true;
1f4c5b9b 675 acc_update_device_async (hostaddrs[i], sizes[i], async);
41dbbb37
TS
676 break;
677
829c6349
CLT
678 case GOMP_MAP_FROM:
679 if (!acc_is_present (hostaddrs[i], sizes[i]))
680 {
681 update_device = false;
682 break;
683 }
684 /* Fallthru */
41dbbb37 685 case GOMP_MAP_FORCE_FROM:
829c6349 686 update_device = false;
1f4c5b9b 687 acc_update_self_async (hostaddrs[i], sizes[i], async);
41dbbb37
TS
688 break;
689
690 default:
691 gomp_fatal (">>>> GOACC_update UNHANDLED kind 0x%.2x", kind);
692 break;
693 }
694 }
5fae049d
TS
695
696 out_prof:
697 if (profiling_p)
698 {
699 prof_info.event_type = acc_ev_update_end;
700 update_event_info.other_event.event_type = prof_info.event_type;
701 goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
702
703 thr->prof_info = NULL;
704 thr->api_info = NULL;
705 }
41dbbb37
TS
706}
707
41dbbb37 708
2bbbfa4e
TS
709/* Legacy entry point (GCC 5). */
710
41dbbb37
TS
711int
712GOACC_get_num_threads (void)
713{
714 return 1;
715}
716
2bbbfa4e
TS
717/* Legacy entry point (GCC 5). */
718
41dbbb37
TS
719int
720GOACC_get_thread_num (void)
721{
722 return 0;
723}