This patch is by Thomas Schwinge and Jakub Jelinek, and was originally posted here:
https://gcc.gnu.org/ml/gcc-patches/2014-07/msg00656.html It adds some mappings required by the OpenACC implementation for Fortran. Julian xxxx-xx-xx Thomas Schwinge <tho...@codesourcery.com> Jakub Jelinek <ja...@redhat.com> * target.c (gomp_map_vars, gomp_unmap_vars, gomp_update): Support NULL mappings as well as mapping kind OMP_CLAUSE_MAP_TO_PSET. Also, some code reformatting.
commit b661af0d60506bf174b687dbd0a590bacd0a4ed4 Author: Julian Brown <jul...@codesourcery.com> Date: Fri Sep 19 09:18:03 2014 -0700 Merge r212405. 2014-07-09 Thomas Schwinge <tho...@codesourcery.com> Jakub Jelinek <ja...@redhat.com> * target.c (gomp_map_vars, gomp_unmap_vars, gomp_update): Support NULL mappings as well as mapping kind OMP_CLAUSE_MAP_TO_PSET. Also, some code reformatting. diff --git a/libgomp/target.c b/libgomp/target.c index ef62228..64b787e 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -238,6 +238,11 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, gomp_mutex_lock (&devicep->dev_env_lock); for (i = 0; i < mapnum; i++) { + if (hostaddrs[i] == NULL) + { + tgt->list[i] = NULL; + continue; + } cur_node.host_start = (uintptr_t) hostaddrs[i]; if ((kinds[i] & 7) != 4) cur_node.host_end = cur_node.host_start + sizes[i]; @@ -259,6 +264,22 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, tgt_align = align; tgt_size = (tgt_size + align - 1) & ~(align - 1); tgt_size += cur_node.host_end - cur_node.host_start; + if ((kinds[i] & 7) == 5) + { + size_t j; + for (j = i + 1; j < mapnum; j++) + if ((kinds[j] & 7) != 4) + break; + else if ((uintptr_t) hostaddrs[j] < cur_node.host_start + || ((uintptr_t) hostaddrs[j] + sizeof (void *) + > cur_node.host_end)) + break; + else + { + tgt->list[j] = NULL; + i++; + } + } } } @@ -281,10 +302,13 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, { tgt->array = gomp_malloc (not_found_cnt * sizeof (*tgt->array)); splay_tree_node array = tgt->array; + size_t j; for (i = 0; i < mapnum; i++) if (tgt->list[i] == NULL) { + if (hostaddrs[i] == NULL) + continue; splay_tree_key k = &array->key; k->host_start = (uintptr_t) hostaddrs[i]; if ((kinds[i] & 7) != 4) @@ -324,14 +348,25 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, /* FIXME: Perhaps add some smarts, like if copying several adjacent fields from host to target, use some host buffer to avoid sending each var individually. */ - devicep->device_host2dev_func((void *) (tgt->tgt_start - + k->tgt_offset), - (void *) k->host_start, - k->host_end - k->host_start); + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + k->tgt_offset), + (void *) k->host_start, + k->host_end - k->host_start); break; case 4: /* POINTER */ cur_node.host_start = (uintptr_t) *(void **) k->host_start; + if (cur_node.host_start == (uintptr_t) NULL) + { + cur_node.tgt_offset = (uintptr_t) NULL; + /* Copy from host to device memory. */ + /* FIXME: see above FIXME comment. */ + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + k->tgt_offset), + (void *) &cur_node.tgt_offset, + sizeof (void *)); + break; + } /* Add bias to the pointer value. */ cur_node.host_start += sizes[i]; cur_node.host_end = cur_node.host_start + 1; @@ -363,11 +398,86 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, cur_node.tgt_offset -= sizes[i]; /* Copy from host to device memory. */ /* FIXME: see above FIXME comment. */ - devicep->device_host2dev_func ((void *) (tgt->tgt_start - + k->tgt_offset), - (void *) &cur_node.tgt_offset, - sizeof (void *)); + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + k->tgt_offset), + (void *) &cur_node.tgt_offset, + sizeof (void *)); break; + case 5: /* TO_PSET */ + /* Copy from host to device memory. */ + /* FIXME: see above FIXME comment. */ + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + k->tgt_offset), + (void *) k->host_start, + (k->host_end - k->host_start)); + for (j = i + 1; j < mapnum; j++) + if ((kinds[j] & 7) != 4) + break; + else if ((uintptr_t) hostaddrs[j] < k->host_start + || ((uintptr_t) hostaddrs[j] + sizeof (void *) + > k->host_end)) + break; + else + { + tgt->list[j] = k; + k->refcount++; + cur_node.host_start + = (uintptr_t) *(void **) hostaddrs[j]; + if (cur_node.host_start == (uintptr_t) NULL) + { + cur_node.tgt_offset = (uintptr_t) NULL; + /* Copy from host to device memory. */ + /* FIXME: see above FIXME comment. */ + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + k->tgt_offset + + ((uintptr_t) hostaddrs[j] + - k->host_start)), + (void *) &cur_node.tgt_offset, + sizeof (void *)); + i++; + continue; + } + /* Add bias to the pointer value. */ + cur_node.host_start += sizes[j]; + cur_node.host_end = cur_node.host_start + 1; + n = splay_tree_lookup (&devicep->dev_splay_tree, + &cur_node); + if (n == NULL) + { + /* Could be possibly zero size array section. */ + cur_node.host_end--; + n = splay_tree_lookup (&devicep->dev_splay_tree, + &cur_node); + if (n == NULL) + { + cur_node.host_start--; + n = splay_tree_lookup + (&devicep->dev_splay_tree, &cur_node); + cur_node.host_start++; + } + } + if (n == NULL) + gomp_fatal ("Pointer target of array section " + "wasn't mapped"); + cur_node.host_start -= n->host_start; + cur_node.tgt_offset = n->tgt->tgt_start + + n->tgt_offset + + cur_node.host_start; + /* At this point tgt_offset is target address of the + array section. Now subtract bias to get what we + want to initialize the pointer with. */ + cur_node.tgt_offset -= sizes[j]; + /* Copy from host to device memory. */ + /* FIXME: see above FIXME comment. */ + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + k->tgt_offset + + ((uintptr_t) hostaddrs[j] + - k->host_start)), + (void *) &cur_node.tgt_offset, + sizeof (void *)); + i++; + } + break; } array++; } @@ -377,14 +487,17 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, { for (i = 0; i < mapnum; i++) { - cur_node.tgt_offset = tgt->list[i]->tgt->tgt_start - + tgt->list[i]->tgt_offset; + if (tgt->list[i] == NULL) + cur_node.tgt_offset = (uintptr_t) NULL; + else + cur_node.tgt_offset = tgt->list[i]->tgt->tgt_start + + tgt->list[i]->tgt_offset; /* Copy from host to device memory. */ /* FIXME: see above FIXME comment. */ - devicep->device_host2dev_func ((void *) (tgt->tgt_start - + i * sizeof (void *)), - (void *) &cur_node.tgt_offset, - sizeof (void *)); + devicep->device_host2dev_func + ((void *) (tgt->tgt_start + i * sizeof (void *)), + (void *) &cur_node.tgt_offset, + sizeof (void *)); } } @@ -417,17 +530,19 @@ gomp_unmap_vars (struct target_mem_desc *tgt) size_t i; gomp_mutex_lock (&devicep->dev_env_lock); for (i = 0; i < tgt->list_count; i++) - if (tgt->list[i]->refcount > 1) + if (tgt->list[i] == NULL) + ; + else if (tgt->list[i]->refcount > 1) tgt->list[i]->refcount--; else { splay_tree_key k = tgt->list[i]; if (k->copy_from) /* Copy from device to host memory. */ - devicep->device_dev2host_func ((void *) k->host_start, - (void *) (k->tgt->tgt_start - + k->tgt_offset), - k->host_end - k->host_start); + devicep->device_dev2host_func + ((void *) k->host_start, + (void *) (k->tgt->tgt_start + k->tgt_offset), + k->host_end - k->host_start); splay_tree_remove (&devicep->dev_splay_tree, k); if (k->tgt->refcount > 1) k->tgt->refcount--; @@ -475,22 +590,22 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, (void *) n->host_end); if ((kinds[i] & 7) == 1) /* Copy from host to device memory. */ - devicep->device_host2dev_func ((void *) (n->tgt->tgt_start - + n->tgt_offset - + cur_node.host_start - - n->host_start), - (void *) cur_node.host_start, - cur_node.host_end - - cur_node.host_start); + devicep->device_host2dev_func + ((void *) (n->tgt->tgt_start + + n->tgt_offset + + cur_node.host_start + - n->host_start), + (void *) cur_node.host_start, + cur_node.host_end - cur_node.host_start); else if ((kinds[i] & 7) == 2) /* Copy from device to host memory. */ - devicep->device_dev2host_func ((void *) cur_node.host_start, - (void *) (n->tgt->tgt_start - + n->tgt_offset - + cur_node.host_start - - n->host_start), - cur_node.host_end - - cur_node.host_start); + devicep->device_dev2host_func + ((void *) cur_node.host_start, + (void *) (n->tgt->tgt_start + + n->tgt_offset + + cur_node.host_start + - n->host_start), + cur_node.host_end - cur_node.host_start); } else gomp_fatal ("Trying to update [%p..%p) object that is not mapped",