/* Decrement usage count and deallocate if zero. */
GOMP_MAP_RELEASE = (GOMP_MAP_FLAG_SPECIAL_2
| GOMP_MAP_DELETE),
- /* In OpenACC, attach a pointer to a mapped struct field. */
+ /* Mapping kinds for allocatable arrays. */
+ GOMP_MAP_DECLARE_ALLOCATE = (GOMP_MAP_FLAG_SPECIAL_4
+ | GOMP_MAP_FORCE_TO),
+ GOMP_MAP_DECLARE_DEALLOCATE = (GOMP_MAP_FLAG_SPECIAL_4
+ | GOMP_MAP_FORCE_FROM),
+ /* The attach/detach mappings below use the OMP_CLAUSE_SIZE field as a
+ bias. This will typically be zero, except when mapping an array slice
+ with a non-zero base. In that case the bias will indicate the
+ (positive) difference between the start of the actual mapped data and
+ the "virtual" origin of the array.
+ In OpenACC, attach a pointer to a mapped struct field. */
GOMP_MAP_ATTACH = (GOMP_MAP_DEEP_COPY | 0),
/* In OpenACC, detach a pointer to a mapped struct field. */
GOMP_MAP_DETACH = (GOMP_MAP_DEEP_COPY | 1),
gomp_fatal ("unexpected mapping");
break;
+ case GOMP_MAP_DECLARE_ALLOCATE:
+ case GOMP_MAP_DECLARE_DEALLOCATE:
+ {
+ /* The "declare allocate" and "declare deallocate" mappings can be
+ used to specify either a scalar allocatable (which just appears as
+ GOMP_MAP_DECLARE_{ALLOCATE,DEALLOCATE} by itself), or an array
+ allocatable (which appears as that directive followed by a
+ GOMP_MAP_TO_PSET and one (or more?) GOMP_MAP_POINTER mappings. */
+ if (pos + 1 >= mapnum)
+ break;
+
+ unsigned char kind1 = kinds[pos + 1] & 0xff;
+ if (kind1 != GOMP_MAP_TO_PSET)
+ break;
+
+ pos++;
+
+ while (pos + 1 < mapnum && (kinds[pos + 1] & 0xff) == GOMP_MAP_POINTER)
+ pos++;
+ }
+ break;
+
+ case GOMP_MAP_ATTACH:
+ break;
+
default:
/* GOMP_MAP_ALWAYS_POINTER can only appear directly after some other
mapping. */
has_firstprivate = true;
continue;
}
+ else if (GOMP_MAP_NONCONTIG_ARRAY_P (kind & typemask))
+ {
+ /* Ignore non-contiguous arrays for now, we process them together
+ later. */
+ tgt->list[i].key = NULL;
+ tgt->list[i].offset = 0;
+ not_found_cnt++;
+
+ /* The map for the non-contiguous array itself is never copied from
+ during unmapping, its the data rows that count. Set copy-from
+ flags to false here. */
+ tgt->list[i].copy_from = false;
+ tgt->list[i].always_copy_from = false;
+ tgt->list[i].do_detach = false;
+
+ size_t align = (size_t) 1 << (kind >> rshift);
+ if (tgt_align < align)
+ tgt_align = align;
+
+ continue;
+ }
+
cur_node.host_start = (uintptr_t) hostaddrs[i];
- if (!GOMP_MAP_POINTER_P (kind & typemask)
- && (kind & typemask) != GOMP_MAP_ATTACH)
+ 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 *);