Hi!

And here is untested incremental libgomp side of the proposed
GOMP_MAP_FIRSTPRIVATE_POINTER.
I'll probably tweak it so that if GOMP_MAP_FIRSTPRIVATE
is followed by one or more GOMP_MAP_FIRSTPRIVATE_POINTER where
the pointers fall into the extents of the firstprivate object,
it will make the whole object firstprivate and then overwrite
the pointers in it (somewhat similar to GOMP_MAP_TO_PSET).

--- include/gomp-constants.h.jj 2015-07-20 12:27:58.000000000 +0200
+++ include/gomp-constants.h    2015-07-20 19:43:47.734326985 +0200
@@ -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.  */
--- libgomp/target.c.jj 2015-07-20 16:03:20.000000000 +0200
+++ libgomp/target.c    2015-07-20 19:57:38.735556137 +0200
@@ -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;
              }


        Jakub

Reply via email to