@@ -74,6 +74,8 @@ enum gomp_map_kind
GOMP_MAP_FORCE_DEVICEPTR = (GOMP_MAP_FLAG_SPECIAL_1 | 0),
/* Do not map, copy bits for firstprivate instead. */
GOMP_MAP_FIRSTPRIVATE = (GOMP_MAP_FLAG_SPECIAL | 0),
+ /* Do not map, but pointer assign a pointer instead. */
+ GOMP_MAP_FIRSTPRIVATE_POINTER = (GOMP_MAP_FLAG_SPECIAL | 1),
/* Allocate. */
GOMP_MAP_FORCE_ALLOC = (GOMP_MAP_FLAG_FORCE | GOMP_MAP_ALLOC),
/* ..., and copy to device. */
@@ -276,12 +276,8 @@ gomp_map_vars (struct gomp_device_descr
tgt->list[i].key = NULL;
continue;
}
- cur_node.host_start = (uintptr_t) hostaddrs[i];
- if (!GOMP_MAP_POINTER_P (kind & typemask))
- cur_node.host_end = cur_node.host_start + sizes[i];
- else
- cur_node.host_end = cur_node.host_start + sizeof (void *);
- if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE)
+ if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE
+ || (kind & typemask) == GOMP_MAP_FIRSTPRIVATE_POINTER)
{
tgt->list[i].key = NULL;
@@ -289,10 +285,18 @@ gomp_map_vars (struct gomp_device_descr
if (tgt_align < align)
tgt_align = align;
tgt_size = (tgt_size + align - 1) & ~(align - 1);
- tgt_size += cur_node.host_end - cur_node.host_start;
+ if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE_POINTER)
+ tgt_size += sizeof (void *);
+ else
+ tgt_size += sizes[i];
has_firstprivate = true;
continue;
}
+ cur_node.host_start = (uintptr_t) hostaddrs[i];
+ if (!GOMP_MAP_POINTER_P (kind & typemask))
+ cur_node.host_end = cur_node.host_start + sizes[i];
+ else
+ cur_node.host_end = cur_node.host_start + sizeof (void *);
splay_tree_key n = splay_tree_lookup (mem_map, &cur_node);
if (n)
gomp_map_vars_existing (devicep, n, &cur_node, &tgt->list[i],
@@ -374,15 +378,28 @@ gomp_map_vars (struct gomp_device_descr
int kind = get_kind (short_mapkind, kinds, i);
if (hostaddrs[i] == NULL)
continue;
- if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE)
+ if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE
+ || (kind & typemask) == GOMP_MAP_FIRSTPRIVATE_POINTER)
{
size_t align = (size_t) 1 << (kind >> rshift);
tgt_size = (tgt_size + align - 1) & ~(align - 1);
tgt->list[i].offset = tgt_size;
- size_t len = sizes[i];
- devicep->host2dev_func (devicep->target_id,
- (void *) (tgt->tgt_start + tgt_size),
- (void *) hostaddrs[i], len);
+ size_t len;
+ if ((kind & typemask) == GOMP_MAP_FIRSTPRIVATE_POINTER)
+ {
+ len = sizeof (void *);
+ gomp_map_pointer (tgt, (uintptr_t)
+ *(void **) (hostaddrs[i]),
+ tgt_size, sizes[i]);
+ }
+ else
+ {
+ len = sizes[i];
+ devicep->host2dev_func (devicep->target_id,
+ (void *) (tgt->tgt_start
+ + tgt_size),
+ (void *) hostaddrs[i], len);
+ }
tgt_size += len;
continue;
}