/* OpenACC Runtime initialization routines

   Copyright (C) 2013-2021 Free Software Foundation, Inc.

   Contributed by Mentor Embedded.

   This file is part of the GNU Offloading and Multi Processing Library
   (libgomp).

   Libgomp is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   more details.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

#include "openacc.h"
#include "libgomp.h"
#include "gomp-constants.h"
#include "oacc-int.h"
#include <string.h>
#include <assert.h>

/* Return block containing [H->S), or NULL if not contained.  The device lock
   for DEV must be locked on entry, and remains locked on exit.  */

static splay_tree_key
lookup_host (struct gomp_device_descr *dev, void *h, size_t s)
{
  struct splay_tree_key_s node;
  splay_tree_key key;

  node.host_start = (uintptr_t) h;
  node.host_end = (uintptr_t) h + s;

  key = splay_tree_lookup (&dev->mem_map, &node);

  return key;
}

/* Helper for lookup_dev.  Iterate over splay tree.  */

static splay_tree_key
lookup_dev_1 (splay_tree_node node, uintptr_t d, size_t s)
{
  splay_tree_key key = &node->key;
  if (d >= key->tgt->tgt_start && d + s <= key->tgt->tgt_end)
    return key;

  key = NULL;
  if (node->left)
    key = lookup_dev_1 (node->left, d, s);
  if (!key && node->right)
    key = lookup_dev_1 (node->right, d, s);

  return key;
}

/* Return block containing [D->S), or NULL if not contained.

   This iterates over the splay tree.  This is not expected to be a common
   operation.

   The device lock associated with MEM_MAP must be locked on entry, and remains
   locked on exit.  */

static splay_tree_key
lookup_dev (splay_tree mem_map, void *d, size_t s)
{
  if (!mem_map || !mem_map->root)
    return NULL;

  return lookup_dev_1 (mem_map->root, (uintptr_t) d, s);
}


/* OpenACC is silent on how memory exhaustion is indicated.  We return
   NULL.  */

void *
acc_malloc (size_t s)
{
  if (!s)
    return NULL;

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();

  assert (thr->dev);

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return malloc (s);

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);

  void *res = thr->dev->alloc_func (thr->dev->target_id, s);

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }

  return res;
}

void
acc_free (void *d)
{
  splay_tree_key k;

  if (!d)
    return;

  struct goacc_thread *thr = goacc_thread ();

  assert (thr && thr->dev);

  struct gomp_device_descr *acc_dev = thr->dev;

  if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return free (d);

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);

  gomp_mutex_lock (&acc_dev->lock);

  /* We don't have to call lazy open here, as the ptr value must have
     been returned by acc_malloc.  It's not permitted to pass NULL in
     (unless you got that null from acc_malloc).  */
  if ((k = lookup_dev (&acc_dev->mem_map, d, 1)))
    {
      void *offset = d - k->tgt->tgt_start + k->tgt_offset;
      void *h = k->host_start + offset;
      size_t h_size = k->host_end - k->host_start;
      gomp_mutex_unlock (&acc_dev->lock);
      /* PR92503 "[OpenACC] Behavior of 'acc_free' if the memory space is still
	 used in a mapping".  */
      gomp_fatal ("refusing to free device memory space at %p that is still"
		  " mapped at [%p,+%d]",
		  d, h, (int) h_size);
    }
  else
    gomp_mutex_unlock (&acc_dev->lock);

  if (!acc_dev->free_func (acc_dev->target_id, d))
    gomp_fatal ("error in freeing device memory in %s", __FUNCTION__);

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }
}

static void
memcpy_tofrom_device (bool from, void *d, void *h, size_t s, int async,
		      const char *libfnname)
{
  /* No need to call lazy open here, as the device pointer must have
     been obtained from a routine that did that.  */
  struct goacc_thread *thr = goacc_thread ();

  assert (thr && thr->dev);

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    {
      if (from)
	memmove (h, d, s);
      else
	memmove (d, h, s);
      return;
    }

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
  if (profiling_p)
    {
      prof_info.async = async;
      prof_info.async_queue = prof_info.async;
    }

  goacc_aq aq = get_goacc_asyncqueue (async);
  if (from)
    gomp_copy_dev2host (thr->dev, aq, h, d, s);
  else
    gomp_copy_host2dev (thr->dev, aq, d, h, s, /* TODO: cbuf? */ NULL);

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }
}

void
acc_memcpy_to_device (void *d, void *h, size_t s)
{
  memcpy_tofrom_device (false, d, h, s, acc_async_sync, __FUNCTION__);
}

void
acc_memcpy_to_device_async (void *d, void *h, size_t s, int async)
{
  memcpy_tofrom_device (false, d, h, s, async, __FUNCTION__);
}

void
acc_memcpy_from_device (void *h, void *d, size_t s)
{
  memcpy_tofrom_device (true, d, h, s, acc_async_sync, __FUNCTION__);
}

void
acc_memcpy_from_device_async (void *h, void *d, size_t s, int async)
{
  memcpy_tofrom_device (true, d, h, s, async, __FUNCTION__);
}

/* Return the device pointer that corresponds to host data H.  Or NULL
   if no mapping.  */

void *
acc_deviceptr (void *h)
{
  splay_tree_key n;
  void *d;
  void *offset;

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *dev = thr->dev;

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return h;

  /* In the following, no OpenACC Profiling Interface events can possibly be
     generated.  */

  gomp_mutex_lock (&dev->lock);

  n = lookup_host (dev, h, 1);

  if (!n)
    {
      gomp_mutex_unlock (&dev->lock);
      return NULL;
    }

  offset = h - n->host_start;

  d = n->tgt->tgt_start + n->tgt_offset + offset;

  gomp_mutex_unlock (&dev->lock);

  return d;
}

/* Return the host pointer that corresponds to device data D.  Or NULL
   if no mapping.  */

void *
acc_hostptr (void *d)
{
  splay_tree_key n;
  void *h;
  void *offset;

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return d;

  /* In the following, no OpenACC Profiling Interface events can possibly be
     generated.  */

  gomp_mutex_lock (&acc_dev->lock);

  n = lookup_dev (&acc_dev->mem_map, d, 1);

  if (!n)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      return NULL;
    }

  offset = d - n->tgt->tgt_start + n->tgt_offset;

  h = n->host_start + offset;

  gomp_mutex_unlock (&acc_dev->lock);

  return h;
}

/* Return 1 if host data [H,+S] is present on the device.  */

int
acc_is_present (void *h, size_t s)
{
  splay_tree_key n;

  if (!s || !h)
    return 0;

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return h != NULL;

  /* In the following, no OpenACC Profiling Interface events can possibly be
     generated.  */

  gomp_mutex_lock (&acc_dev->lock);

  n = lookup_host (acc_dev, h, s);

  if (n && ((uintptr_t)h < n->host_start
	    || (uintptr_t)h + s > n->host_end
	    || s > n->host_end - n->host_start))
    n = NULL;

  gomp_mutex_unlock (&acc_dev->lock);

  return n != NULL;
}

/* Create a mapping for host [H,+S] -> device [D,+S] */

void
acc_map_data (void *h, void *d, size_t s)
{
  size_t mapnum = 1;
  void *hostaddrs = h;
  void *devaddrs = d;
  size_t sizes = s;
  unsigned short kinds = GOMP_MAP_ALLOC;

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    {
      if (d != h)
        gomp_fatal ("cannot map data on shared-memory system");
    }
  else
    {
      struct goacc_thread *thr = goacc_thread ();

      if (!d || !h || !s)
	gomp_fatal ("[%p,+%d]->[%p,+%d] is a bad map",
                    (void *)h, (int)s, (void *)d, (int)s);

      acc_prof_info prof_info;
      acc_api_info api_info;
      bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);

      gomp_mutex_lock (&acc_dev->lock);

      if (lookup_host (acc_dev, h, s))
        {
	  gomp_mutex_unlock (&acc_dev->lock);
	  gomp_fatal ("host address [%p, +%d] is already mapped", (void *)h,
		      (int)s);
	}

      if (lookup_dev (&thr->dev->mem_map, d, s))
        {
	  gomp_mutex_unlock (&acc_dev->lock);
	  gomp_fatal ("device address [%p, +%d] is already mapped", (void *)d,
		      (int)s);
	}

      gomp_mutex_unlock (&acc_dev->lock);

      struct target_mem_desc *tgt
	= goacc_map_vars (acc_dev, NULL, mapnum, &hostaddrs, &devaddrs, &sizes,
			  &kinds, true, GOMP_MAP_VARS_ENTER_DATA);
      assert (tgt);
      assert (tgt->list_count == 1);
      splay_tree_key n = tgt->list[0].key;
      assert (n);
      assert (n->refcount == 1);
      assert (n->dynamic_refcount == 0);
      /* Special reference counting behavior.  */
      n->refcount = REFCOUNT_INFINITY;

      if (profiling_p)
	{
	  thr->prof_info = NULL;
	  thr->api_info = NULL;
	}
    }
}

void
acc_unmap_data (void *h)
{
  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  /* No need to call lazy open, as the address must have been mapped.  */

  /* This is a no-op on shared-memory targets.  */
  if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return;

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);

  gomp_mutex_lock (&acc_dev->lock);

  splay_tree_key n = lookup_host (acc_dev, h, 1);

  if (!n)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("%p is not a mapped block", (void *)h);
    }

  size_t host_size = n->host_end - n->host_start;

  if (n->host_start != (uintptr_t) h)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("[%p,%d] surrounds %p",
		  (void *) n->host_start, (int) host_size, (void *) h);
    }
  /* TODO This currently doesn't catch 'REFCOUNT_INFINITY' usage different from
     'acc_map_data'.  Maybe 'dynamic_refcount' can be used for disambiguating
     the different 'REFCOUNT_INFINITY' cases, or simply separate
     'REFCOUNT_INFINITY' values per different usage ('REFCOUNT_ACC_MAP_DATA'
     etc.)?  */
  else if (n->refcount != REFCOUNT_INFINITY)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("refusing to unmap block [%p,+%d] that has not been mapped"
		  " by 'acc_map_data'",
		  (void *) h, (int) host_size);
    }

  struct target_mem_desc *tgt = n->tgt;

  if (tgt->refcount == REFCOUNT_INFINITY)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("cannot unmap target block");
    }

  /* Above, we've verified that the mapping must have been set up by
     'acc_map_data'.  */
  assert (tgt->refcount == 1);

  /* Nullifying these fields prevents 'gomp_unmap_tgt' via 'gomp_remove_var'
     from freeing the target memory.  */
  tgt->tgt_end = 0;
  tgt->to_free = NULL;

  bool is_tgt_unmapped = gomp_remove_var (acc_dev, n);
  assert (is_tgt_unmapped);

  gomp_mutex_unlock (&acc_dev->lock);

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }
}


/* Helper function to map a single dynamic data item, represented by a single
   mapping.  The acc_dev->lock should be held on entry, and remains locked on
   exit.  */

static void *
goacc_map_var_existing (struct gomp_device_descr *acc_dev, void *hostaddr,
			size_t size, splay_tree_key n)
{
  assert (n);

  /* Present. */
  void *d = (void *) (n->tgt->tgt_start + n->tgt_offset + hostaddr
	    - n->host_start);

  if (hostaddr + size > (void *) n->host_end)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("[%p,+%d] not mapped", hostaddr, (int) size);
    }

  assert (n->refcount != REFCOUNT_LINK);
  if (n->refcount != REFCOUNT_INFINITY)
    n->refcount++;
  n->dynamic_refcount++;

  return d;
}

/* Enter dynamic mapping for a single datum.  Return the device pointer.  */

static void *
goacc_enter_datum (void **hostaddrs, size_t *sizes, void *kinds, int async)
{
  void *d;
  splay_tree_key n;

  if (!hostaddrs[0] || !sizes[0])
    gomp_fatal ("[%p,+%d] is a bad range", hostaddrs[0], (int) sizes[0]);

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return hostaddrs[0];

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
  if (profiling_p)
    {
      prof_info.async = async;
      prof_info.async_queue = prof_info.async;
    }

  gomp_mutex_lock (&acc_dev->lock);

  n = lookup_host (acc_dev, hostaddrs[0], sizes[0]);
  if (n)
    {
      d = goacc_map_var_existing (acc_dev, hostaddrs[0], sizes[0], n);
      gomp_mutex_unlock (&acc_dev->lock);
    }
  else
    {
      const size_t mapnum = 1;

      gomp_mutex_unlock (&acc_dev->lock);

      goacc_aq aq = get_goacc_asyncqueue (async);

      struct target_mem_desc *tgt
	= goacc_map_vars (acc_dev, aq, mapnum, hostaddrs, NULL, sizes,
			  kinds, true, GOMP_MAP_VARS_ENTER_DATA);
      assert (tgt);
      assert (tgt->list_count == 1);
      n = tgt->list[0].key;
      assert (n);
      assert (n->refcount == 1);
      assert (n->dynamic_refcount == 0);
      n->dynamic_refcount++;

      d = (void *) tgt->tgt_start;
    }

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }

  return d;
}

void *
acc_create (void *h, size_t s)
{
  unsigned short kinds[1] = { GOMP_MAP_ALLOC };
  return goacc_enter_datum (&h, &s, &kinds, acc_async_sync);
}

void
acc_create_async (void *h, size_t s, int async)
{
  unsigned short kinds[1] = { GOMP_MAP_ALLOC };
  goacc_enter_datum (&h, &s, &kinds, async);
}

/* acc_present_or_create used to be what acc_create is now.  */
/* acc_pcreate is acc_present_or_create by a different name.  */
#ifdef HAVE_ATTRIBUTE_ALIAS
strong_alias (acc_create, acc_present_or_create)
strong_alias (acc_create, acc_pcreate)
#else
void *
acc_present_or_create (void *h, size_t s)
{
  return acc_create (h, s);
}

void *
acc_pcreate (void *h, size_t s)
{
  return acc_create (h, s);
}
#endif

void *
acc_copyin (void *h, size_t s)
{
  unsigned short kinds[1] = { GOMP_MAP_TO };
  return goacc_enter_datum (&h, &s, &kinds, acc_async_sync);
}

void
acc_copyin_async (void *h, size_t s, int async)
{
  unsigned short kinds[1] = { GOMP_MAP_TO };
  goacc_enter_datum (&h, &s, &kinds, async);
}

/* acc_present_or_copyin used to be what acc_copyin is now.  */
/* acc_pcopyin is acc_present_or_copyin by a different name.  */
#ifdef HAVE_ATTRIBUTE_ALIAS
strong_alias (acc_copyin, acc_present_or_copyin)
strong_alias (acc_copyin, acc_pcopyin)
#else
void *
acc_present_or_copyin (void *h, size_t s)
{
  return acc_copyin (h, s);
}

void *
acc_pcopyin (void *h, size_t s)
{
  return acc_copyin (h, s);
}
#endif


/* Helper function to unmap a single data item.  Device lock should be held on
   entry, and remains locked on exit.  */

static void
goacc_exit_datum_1 (struct gomp_device_descr *acc_dev, void *h, size_t s,
		    unsigned short kind, splay_tree_key n, goacc_aq aq)
{
  assert (kind != GOMP_MAP_DETACH
	  && kind != GOMP_MAP_FORCE_DETACH);

  if ((uintptr_t) h < n->host_start || (uintptr_t) h + s > n->host_end)
    {
      size_t host_size = n->host_end - n->host_start;
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("[%p,+%d] outside mapped block [%p,+%d]",
		  (void *) h, (int) s, (void *) n->host_start, (int) host_size);
    }

  bool finalize = (kind == GOMP_MAP_FORCE_FROM
		   || kind == GOMP_MAP_DELETE);

  assert (n->refcount != REFCOUNT_LINK);
  if (n->refcount != REFCOUNT_INFINITY
      && n->refcount < n->dynamic_refcount)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("Dynamic reference counting assert fail\n");
    }

  if (finalize)
    {
      if (n->refcount != REFCOUNT_INFINITY)
	n->refcount -= n->dynamic_refcount;
      n->dynamic_refcount = 0;
    }
  else if (n->dynamic_refcount)
    {
      if (n->refcount != REFCOUNT_INFINITY)
	n->refcount--;
      n->dynamic_refcount--;
    }

  if (n->refcount == 0)
    {
      bool copyout = (kind == GOMP_MAP_FROM
		      || kind == GOMP_MAP_FORCE_FROM);
      if (copyout)
	{
	  void *d = (void *) (n->tgt->tgt_start + n->tgt_offset
			      + (uintptr_t) h - n->host_start);
	  gomp_copy_dev2host (acc_dev, aq, h, d, s);
	}

      if (aq)
	/* TODO We can't do the 'is_tgt_unmapped' checking -- see the
	   'gomp_unref_tgt' comment in
	   <http://mid.mail-archive.com/878snl36eu.fsf@euler.schwinge.homeip.net>;
	   PR92881.  */
	gomp_remove_var_async (acc_dev, n, aq);
      else
	{
	  size_t num_mappings = 0;
	  /* If the target_mem_desc represents a single data mapping, we can
	     check that it is freed when this splay tree key's refcount reaches
	     zero.  Otherwise (e.g. for a 'GOMP_MAP_STRUCT' mapping with
	     multiple members), fall back to skipping the test.  */
	  for (size_t l_i = 0; l_i < n->tgt->list_count; ++l_i)
	    if (n->tgt->list[l_i].key
		&& !n->tgt->list[l_i].is_attach)
	      ++num_mappings;
	  bool is_tgt_unmapped = gomp_remove_var (acc_dev, n);
	  assert (is_tgt_unmapped || num_mappings > 1);
	}
    }
}


/* Exit a dynamic mapping for a single variable.  */

static void
goacc_exit_datum (void *h, size_t s, unsigned short kind, int async)
{
  /* No need to call lazy open, as the data must already have been
     mapped.  */

  kind &= 0xff;

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return;

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
  if (profiling_p)
    {
      prof_info.async = async;
      prof_info.async_queue = prof_info.async;
    }

  gomp_mutex_lock (&acc_dev->lock);

  splay_tree_key n = lookup_host (acc_dev, h, s);
  /* Non-present data is a no-op: PR92726, RP92970, PR92984.  */
  if (n)
    {
      goacc_aq aq = get_goacc_asyncqueue (async);
      goacc_exit_datum_1 (acc_dev, h, s, kind, n, aq);
    }

  gomp_mutex_unlock (&acc_dev->lock);

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }
}

void
acc_delete (void *h , size_t s)
{
  goacc_exit_datum (h, s, GOMP_MAP_RELEASE, acc_async_sync);
}

void
acc_delete_async (void *h , size_t s, int async)
{
  goacc_exit_datum (h, s, GOMP_MAP_RELEASE, async);
}

void
acc_delete_finalize (void *h , size_t s)
{
  goacc_exit_datum (h, s, GOMP_MAP_DELETE, acc_async_sync);
}

void
acc_delete_finalize_async (void *h , size_t s, int async)
{
  goacc_exit_datum (h, s, GOMP_MAP_DELETE, async);
}

void
acc_copyout (void *h, size_t s)
{
  goacc_exit_datum (h, s, GOMP_MAP_FROM, acc_async_sync);
}

void
acc_copyout_async (void *h, size_t s, int async)
{
  goacc_exit_datum (h, s, GOMP_MAP_FROM, async);
}

void
acc_copyout_finalize (void *h, size_t s)
{
  goacc_exit_datum (h, s, GOMP_MAP_FORCE_FROM, acc_async_sync);
}

void
acc_copyout_finalize_async (void *h, size_t s, int async)
{
  goacc_exit_datum (h, s, GOMP_MAP_FORCE_FROM, async);
}

static void
update_dev_host (int is_dev, void *h, size_t s, int async)
{
  splay_tree_key n;
  void *d;

  goacc_lazy_initialize ();

  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;

  if (acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return;

  /* Fortran optional arguments that are non-present result in a
     NULL host address here.  This can safely be ignored as it is
     not possible to 'update' a non-present optional argument.  */
  if (h == NULL)
    return;

  acc_prof_info prof_info;
  acc_api_info api_info;
  bool profiling_p = GOACC_PROFILING_SETUP_P (thr, &prof_info, &api_info);
  if (profiling_p)
    {
      prof_info.async = async;
      prof_info.async_queue = prof_info.async;
    }

  gomp_mutex_lock (&acc_dev->lock);

  n = lookup_host (acc_dev, h, s);

  if (!n)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("[%p,%d] is not mapped", h, (int)s);
    }

  d = (void *) (n->tgt->tgt_start + n->tgt_offset
		+ (uintptr_t) h - n->host_start);

  goacc_aq aq = get_goacc_asyncqueue (async);

  if (is_dev)
    gomp_copy_host2dev (acc_dev, aq, d, h, s, /* TODO: cbuf? */ NULL);
  else
    gomp_copy_dev2host (acc_dev, aq, h, d, s);

  gomp_mutex_unlock (&acc_dev->lock);

  if (profiling_p)
    {
      thr->prof_info = NULL;
      thr->api_info = NULL;
    }
}

void
acc_update_device (void *h, size_t s)
{
  update_dev_host (1, h, s, acc_async_sync);
}

void
acc_update_device_async (void *h, size_t s, int async)
{
  update_dev_host (1, h, s, async);
}

void
acc_update_self (void *h, size_t s)
{
  update_dev_host (0, h, s, acc_async_sync);
}

void
acc_update_self_async (void *h, size_t s, int async)
{
  update_dev_host (0, h, s, async);
}

void
acc_attach_async (void **hostaddr, int async)
{
  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;
  goacc_aq aq = get_goacc_asyncqueue (async);

  struct splay_tree_key_s cur_node;
  splay_tree_key n;

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return;

  gomp_mutex_lock (&acc_dev->lock);

  cur_node.host_start = (uintptr_t) hostaddr;
  cur_node.host_end = cur_node.host_start + sizeof (void *);
  n = splay_tree_lookup (&acc_dev->mem_map, &cur_node);

  if (n == NULL)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("struct not mapped for acc_attach");
    }

  gomp_attach_pointer (acc_dev, aq, &acc_dev->mem_map, n, (uintptr_t) hostaddr,
		       0, NULL);

  gomp_mutex_unlock (&acc_dev->lock);
}

void
acc_attach (void **hostaddr)
{
  acc_attach_async (hostaddr, acc_async_sync);
}

static void
goacc_detach_internal (void **hostaddr, int async, bool finalize)
{
  struct goacc_thread *thr = goacc_thread ();
  struct gomp_device_descr *acc_dev = thr->dev;
  struct splay_tree_key_s cur_node;
  splay_tree_key n;
  struct goacc_asyncqueue *aq = get_goacc_asyncqueue (async);

  if (thr->dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
    return;

  gomp_mutex_lock (&acc_dev->lock);

  cur_node.host_start = (uintptr_t) hostaddr;
  cur_node.host_end = cur_node.host_start + sizeof (void *);
  n = splay_tree_lookup (&acc_dev->mem_map, &cur_node);

  if (n == NULL)
    {
      gomp_mutex_unlock (&acc_dev->lock);
      gomp_fatal ("struct not mapped for acc_detach");
    }

  gomp_detach_pointer (acc_dev, aq, n, (uintptr_t) hostaddr, finalize, NULL);

  gomp_mutex_unlock (&acc_dev->lock);
}

void
acc_detach (void **hostaddr)
{
  goacc_detach_internal (hostaddr, acc_async_sync, false);
}

void
acc_detach_async (void **hostaddr, int async)
{
  goacc_detach_internal (hostaddr, async, false);
}

void
acc_detach_finalize (void **hostaddr)
{
  goacc_detach_internal (hostaddr, acc_async_sync, true);
}

void
acc_detach_finalize_async (void **hostaddr, int async)
{
  goacc_detach_internal (hostaddr, async, true);
}

/* Some types of (pointer) variables use several consecutive mappings, which
   must be treated as a group for enter/exit data directives.  This function
   returns the last mapping in such a group (inclusive), or POS for singleton
   mappings.  */

static int
find_group_last (int pos, size_t mapnum, size_t *sizes, unsigned short *kinds)
{
  unsigned char kind0 = kinds[pos] & 0xff;
  int first_pos = pos;

  switch (kind0)
    {
    case GOMP_MAP_TO_PSET:
      if (pos + 1 < mapnum
	  && (kinds[pos + 1] & 0xff) == GOMP_MAP_ATTACH)
	return pos + 1;

      while (pos + 1 < mapnum
	     && (kinds[pos + 1] & 0xff) == GOMP_MAP_POINTER)
	pos++;
      /* We expect at least one GOMP_MAP_POINTER (if not a single
	 GOMP_MAP_ATTACH) after a GOMP_MAP_TO_PSET.  */
      assert (pos > first_pos);
      break;

    case GOMP_MAP_STRUCT:
      pos += sizes[pos];
      break;

    case GOMP_MAP_POINTER:
    case GOMP_MAP_ALWAYS_POINTER:
      /* These mappings are only expected after some other mapping.  If we
	 see one by itself, something has gone wrong.  */
      gomp_fatal ("unexpected mapping");
      break;

    case GOMP_MAP_ATTACH:
      break;

    default:
      /* GOMP_MAP_ALWAYS_POINTER can only appear directly after some other
	 mapping.  */
      if (pos + 1 < mapnum)
	{
	  unsigned char kind1 = kinds[pos + 1] & 0xff;
	  if (kind1 == GOMP_MAP_ALWAYS_POINTER)
	    return pos + 1;
	}

      /* We can have a single GOMP_MAP_ATTACH mapping after a to/from
	 mapping.  */
      if (pos + 1 < mapnum
	  && (kinds[pos + 1] & 0xff) == GOMP_MAP_ATTACH)
	return pos + 1;

      /* We can have zero or more GOMP_MAP_POINTER mappings after a to/from
	 (etc.) mapping.  */
      while (pos + 1 < mapnum
	     && (kinds[pos + 1] & 0xff) == GOMP_MAP_POINTER)
	pos++;
    }

  return pos;
}

/* Map variables for OpenACC "enter data".  We can't just call
   goacc_map_vars once, because individual mapped variables might have
   "exit data" called for them at different times.  */

static void
goacc_enter_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum,
			   void **hostaddrs, size_t *sizes,
			   unsigned short *kinds, goacc_aq aq)
{
  gomp_mutex_lock (&acc_dev->lock);

  for (size_t i = 0; i < mapnum; i++)
    {
      splay_tree_key n;
      size_t group_last = find_group_last (i, mapnum, sizes, kinds);
      bool struct_p = false;
      size_t size, groupnum = (group_last - i) + 1;

      switch (kinds[i] & 0xff)
	{
	case GOMP_MAP_STRUCT:
	  {
	    size = (uintptr_t) hostaddrs[group_last] + sizes[group_last]
		   - (uintptr_t) hostaddrs[i];
	    struct_p = true;
	  }
	  break;

	case GOMP_MAP_ATTACH:
	  size = sizeof (void *);
	  break;

	default:
	  size = sizes[i];
	}

      n = lookup_host (acc_dev, hostaddrs[i], size);

      if (n && struct_p)
	{
	  for (size_t j = i + 1; j <= group_last; j++)
	    {
	      struct splay_tree_key_s cur_node;
	      cur_node.host_start = (uintptr_t) hostaddrs[j];
	      cur_node.host_end = cur_node.host_start + sizes[j];
	      splay_tree_key n2
		= splay_tree_lookup (&acc_dev->mem_map, &cur_node);
	      if (!n2
		  || n2->tgt != n->tgt
		  || n2->host_start - n->host_start
		     != n2->tgt_offset - n->tgt_offset)
		{
		  gomp_mutex_unlock (&acc_dev->lock);
		  gomp_fatal ("Trying to map into device [%p..%p) structure "
			      "element when other mapped elements from the "
			      "same structure weren't mapped together with "
			      "it", (void *) cur_node.host_start,
			      (void *) cur_node.host_end);
		}
	    }
	  /* This is a special case because we must increment the refcount by
	     the number of mapped struct elements, rather than by one.  */
	  if (n->refcount != REFCOUNT_INFINITY)
	    n->refcount += groupnum - 1;
	  n->dynamic_refcount += groupnum - 1;
	}
      else if (n && groupnum == 1)
	{
	  void *h = hostaddrs[i];
	  size_t s = sizes[i];

	  if ((kinds[i] & 0xff) == GOMP_MAP_ATTACH)
	    {
	      gomp_attach_pointer (acc_dev, aq, &acc_dev->mem_map, n,
				   (uintptr_t) h, s, NULL);
	      /* OpenACC 'attach'/'detach' doesn't affect structured/dynamic
		 reference counts ('n->refcount', 'n->dynamic_refcount').  */
	    }
	  else
	    goacc_map_var_existing (acc_dev, h, s, n);
	}
      else if (n && groupnum > 1)
	{
	  assert (n->refcount != REFCOUNT_INFINITY
		  && n->refcount != REFCOUNT_LINK);

	  for (size_t j = i + 1; j <= group_last; j++)
	    if ((kinds[j] & 0xff) == GOMP_MAP_ATTACH)
	      {
		splay_tree_key m
		  = lookup_host (acc_dev, hostaddrs[j], sizeof (void *));
		gomp_attach_pointer (acc_dev, aq, &acc_dev->mem_map, m,
				     (uintptr_t) hostaddrs[j], sizes[j], NULL);
	      }

	  bool processed = false;

	  struct target_mem_desc *tgt = n->tgt;
	  for (size_t j = 0; j < tgt->list_count; j++)
	    if (tgt->list[j].key == n)
	      {
		/* We are processing a group of mappings (e.g.
		   [GOMP_MAP_TO, GOMP_MAP_TO_PSET, GOMP_MAP_POINTER]).
		   Find the right group in the target_mem_desc's variable
		   list, and increment the refcounts for each item in that
		   group.  */
		for (size_t k = 0; k < groupnum; k++)
		  if (j + k < tgt->list_count
		      && tgt->list[j + k].key
		      && !tgt->list[j + k].is_attach)
		    {
		      tgt->list[j + k].key->refcount++;
		      tgt->list[j + k].key->dynamic_refcount++;
		    }
		processed = true;
		break;
	      }

	  if (!processed)
	    {
	      gomp_mutex_unlock (&acc_dev->lock);
	      gomp_fatal ("dynamic refcount incrementing failed for "
			  "pointer/pset");
	    }
	}
      else if (hostaddrs[i])
	{
	  /* The data is not mapped already.  Map it now, unless the first
	     member in the group has a NULL pointer (e.g. a non-present
	     optional parameter).  */
	  gomp_mutex_unlock (&acc_dev->lock);

	  struct target_mem_desc *tgt
	    = goacc_map_vars (acc_dev, aq, groupnum, &hostaddrs[i], NULL,
			      &sizes[i], &kinds[i], true,
			      GOMP_MAP_VARS_ENTER_DATA);
	  assert (tgt);

	  gomp_mutex_lock (&acc_dev->lock);

	  for (size_t j = 0; j < tgt->list_count; j++)
	    {
	      n = tgt->list[j].key;
	      if (n && !tgt->list[j].is_attach)
		n->dynamic_refcount++;
	    }
	}

      i = group_last;
    }

  gomp_mutex_unlock (&acc_dev->lock);
}

/* Unmap variables for OpenACC "exit data".  */

static void
goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum,
			  void **hostaddrs, size_t *sizes,
			  unsigned short *kinds, goacc_aq aq)
{
  gomp_mutex_lock (&acc_dev->lock);

  /* Handle "detach" before copyback/deletion of mapped data.  */
  for (size_t i = 0; i < mapnum; ++i)
    {
      unsigned char kind = kinds[i] & 0xff;
      bool finalize = false;
      switch (kind)
	{
	case GOMP_MAP_FORCE_DETACH:
	  finalize = true;
	  /* Fallthrough.  */

	case GOMP_MAP_DETACH:
	  {
	    struct splay_tree_key_s cur_node;
	    uintptr_t hostaddr = (uintptr_t) hostaddrs[i];
	    cur_node.host_start = hostaddr;
	    cur_node.host_end = cur_node.host_start + sizeof (void *);
	    splay_tree_key n
	      = splay_tree_lookup (&acc_dev->mem_map, &cur_node);

	    if (n == NULL)
	      {
		gomp_mutex_unlock (&acc_dev->lock);
		gomp_fatal ("struct not mapped for detach operation");
	      }

	    gomp_detach_pointer (acc_dev, aq, n, hostaddr, finalize, NULL);
	  }
	  break;
	default:
	  ;
	}
    }

  for (size_t i = 0; i < mapnum; ++i)
    {
      unsigned char kind = kinds[i] & 0xff;

      switch (kind)
	{
	case GOMP_MAP_FROM:
	case GOMP_MAP_FORCE_FROM:
	case GOMP_MAP_TO_PSET:
	case GOMP_MAP_POINTER:
	case GOMP_MAP_DELETE:
	case GOMP_MAP_RELEASE:
	  {
	    struct splay_tree_key_s cur_node;
	    size_t size;
	    if (kind == GOMP_MAP_POINTER)
	      size = sizeof (void *);
	    else
	      size = sizes[i];
	    cur_node.host_start = (uintptr_t) hostaddrs[i];
	    cur_node.host_end = cur_node.host_start + size;
	    splay_tree_key n
	      = splay_tree_lookup (&acc_dev->mem_map, &cur_node);

	    if (n == NULL)
	      continue;

	    goacc_exit_datum_1 (acc_dev, hostaddrs[i], size, kind, n, aq);
	  }
	  break;

	case GOMP_MAP_STRUCT:
	  /* Skip the 'GOMP_MAP_STRUCT' itself, and use the regular processing
	     for all its entries.  This special handling exists for GCC 10.1
	     compatibility; afterwards, we're not generating these no-op
	     'GOMP_MAP_STRUCT's anymore.  */
	  break;

	case GOMP_MAP_DETACH:
	case GOMP_MAP_FORCE_DETACH:
	  /* OpenACC 'attach'/'detach' doesn't affect structured/dynamic
	     reference counts ('n->refcount', 'n->dynamic_refcount').  */
	  break;

	default:
	  gomp_fatal (">>>> goacc_exit_data_internal UNHANDLED kind 0x%.2x",
			  kind);
	}
    }

  gomp_mutex_unlock (&acc_dev->lock);
}

static void
goacc_enter_exit_data_internal (int flags_m, size_t mapnum, void **hostaddrs,
				size_t *sizes, unsigned short *kinds,
				bool data_enter, int async, int num_waits,
				va_list *ap)
{
  int flags = GOACC_FLAGS_UNMARSHAL (flags_m);

  struct goacc_thread *thr;
  struct gomp_device_descr *acc_dev;

  goacc_lazy_initialize ();

  thr = goacc_thread ();
  acc_dev = thr->dev;

  bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);

  acc_prof_info prof_info;
  if (profiling_p)
    {
      thr->prof_info = &prof_info;

      prof_info.event_type
	= data_enter ? acc_ev_enter_data_start : acc_ev_exit_data_start;
      prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
      prof_info.version = _ACC_PROF_INFO_VERSION;
      prof_info.device_type = acc_device_type (acc_dev->type);
      prof_info.device_number = acc_dev->target_id;
      prof_info.thread_id = -1;
      prof_info.async = async;
      prof_info.async_queue = prof_info.async;
      prof_info.src_file = NULL;
      prof_info.func_name = NULL;
      prof_info.line_no = -1;
      prof_info.end_line_no = -1;
      prof_info.func_line_no = -1;
      prof_info.func_end_line_no = -1;
    }
  acc_event_info enter_exit_data_event_info;
  if (profiling_p)
    {
      enter_exit_data_event_info.other_event.event_type
	= prof_info.event_type;
      enter_exit_data_event_info.other_event.valid_bytes
	= _ACC_OTHER_EVENT_INFO_VALID_BYTES;
      enter_exit_data_event_info.other_event.parent_construct
	= data_enter ? acc_construct_enter_data : acc_construct_exit_data;
      enter_exit_data_event_info.other_event.implicit = 0;
      enter_exit_data_event_info.other_event.tool_info = NULL;
    }
  acc_api_info api_info;
  if (profiling_p)
    {
      thr->api_info = &api_info;

      api_info.device_api = acc_device_api_none;
      api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
      api_info.device_type = prof_info.device_type;
      api_info.vendor = -1;
      api_info.device_handle = NULL;
      api_info.context_handle = NULL;
      api_info.async_handle = NULL;
    }

  if (profiling_p)
    goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
			      &api_info);

  if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
      || (flags & GOACC_FLAG_HOST_FALLBACK))
    {
      prof_info.device_type = acc_device_host;
      api_info.device_type = prof_info.device_type;

      goto out_prof;
    }

  if (num_waits)
    goacc_wait (async, num_waits, ap);

  goacc_aq aq = get_goacc_asyncqueue (async);

  if (data_enter)
    goacc_enter_data_internal (acc_dev, mapnum, hostaddrs, sizes, kinds, aq);
  else
    goacc_exit_data_internal (acc_dev, mapnum, hostaddrs, sizes, kinds, aq);

 out_prof:
  if (profiling_p)
    {
      prof_info.event_type
	= data_enter ? acc_ev_enter_data_end : acc_ev_exit_data_end;
      enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
      goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
				&api_info);

      thr->prof_info = NULL;
      thr->api_info = NULL;
    }
}

/* Legacy entry point (GCC 11 and earlier).  */

void
GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
		       size_t *sizes, unsigned short *kinds, int async,
		       int num_waits, ...)
{
  /* Determine if this is an OpenACC "enter data".  */
  bool data_enter = false;
  for (size_t i = 0; i < mapnum; ++i)
    {
      unsigned char kind = kinds[i] & 0xff;

      if (kind == GOMP_MAP_POINTER
	  || kind == GOMP_MAP_TO_PSET
	  || kind == GOMP_MAP_STRUCT)
	continue;

      if (kind == GOMP_MAP_FORCE_ALLOC
	  || kind == GOMP_MAP_FORCE_PRESENT
	  || kind == GOMP_MAP_ATTACH
	  || kind == GOMP_MAP_FORCE_TO
	  || kind == GOMP_MAP_TO
	  || kind == GOMP_MAP_ALLOC)
	{
	  data_enter = true;
	  break;
	}

      if (kind == GOMP_MAP_RELEASE
	  || kind == GOMP_MAP_DELETE
	  || kind == GOMP_MAP_DETACH
	  || kind == GOMP_MAP_FORCE_DETACH
	  || kind == GOMP_MAP_FROM
	  || kind == GOMP_MAP_FORCE_FROM)
	break;

      gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
		      kind);
    }

  va_list ap;
  va_start (ap, num_waits);
  goacc_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds,
				  data_enter, async, num_waits, &ap);
  va_end (ap);
}

void
GOACC_enter_data (int flags_m, size_t mapnum, void **hostaddrs,
		  size_t *sizes, unsigned short *kinds, int async,
		  int num_waits, ...)
{
  va_list ap;
  va_start (ap, num_waits);
  goacc_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds,
				  true, async, num_waits, &ap);
  va_end (ap);
}

void
GOACC_exit_data (int flags_m, size_t mapnum, void **hostaddrs,
		 size_t *sizes, unsigned short *kinds, int async,
		 int num_waits, ...)
{
  va_list ap;
  va_start (ap, num_waits);
  goacc_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds,
				  false, async, num_waits, &ap);
  va_end (ap);
}

void
GOACC_declare (int flags_m, size_t mapnum,
	       void **hostaddrs, size_t *sizes, unsigned short *kinds)
{
  for (size_t i = 0; i < mapnum; i++)
    {
      unsigned char kind = kinds[i] & 0xff;

      if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
	continue;

      switch (kind)
	{
	case GOMP_MAP_ALLOC:
	  if (acc_is_present (hostaddrs[i], sizes[i]))
	    continue;
	  /* FALLTHRU */
	case GOMP_MAP_FORCE_ALLOC:
	case GOMP_MAP_TO:
	case GOMP_MAP_FORCE_TO:
	  goacc_enter_exit_data_internal (flags_m, 1, &hostaddrs[i], &sizes[i],
					  &kinds[i], true, GOMP_ASYNC_SYNC, 0, NULL);
	  break;

	case GOMP_MAP_FROM:
	case GOMP_MAP_FORCE_FROM:
	case GOMP_MAP_RELEASE:
	case GOMP_MAP_DELETE:
	  goacc_enter_exit_data_internal (flags_m, 1, &hostaddrs[i], &sizes[i],
					  &kinds[i], false, GOMP_ASYNC_SYNC, 0, NULL);
	  break;

	case GOMP_MAP_FORCE_DEVICEPTR:
	  break;

	case GOMP_MAP_FORCE_PRESENT:
	  if (!acc_is_present (hostaddrs[i], sizes[i]))
	    gomp_fatal ("[%p,%ld] is not mapped", hostaddrs[i],
			(unsigned long) sizes[i]);
	  break;

	default:
	  assert (0);
	  break;
	}
    }
}
