Hi Gergő!

On Fri, 21 Dec 2018 13:29:09 +0100, Gergö Barany <ge...@codesourcery.com> wrote:
> OpenACC 2.6 specifies `if' and `if_present' clauses on the `host_data' 
> construct. These patches add support for these clauses. The first patch, 
> by Thomas, reorganizes libgomp internals to turn a "device" argument 
> into "flags" that can provide more information to the runtime. The 
> second patch adds support for the `if' and `if_present' clauses, using 
> the new flag mechanism.
> 
> OK for openacc-gcc-8-branch?

Yes, thanks.  To record the review effort, please include "Reviewed-by:
Thomas Schwinge <tho...@codesourcery.com>" in the commit log, see
<https://gcc.gnu.org/wiki/Reviewed-by>.  (Not for my own commit, of
course.)

Again, just the commit message of the second commit needs to be adjusted, from:

>     [...]
>     gcc/testsuite/c-c++-common/goacc/
>     * host_data-1.c: Add tests of if and if_present clauses on host_data.
>     gcc/testsuite/gfortran.dg/goacc/
>     * host_data-tree.f95: Likewise.
>     [...]
>     libgomp/
>     * libgomp.h (enum gomp_map_vars_kind): Add
>     GOMP_MAP_VARS_OPENACC_IF_PRESENT.
> 
>     libgomp/
>     * oacc-parallel.c (GOACC_data_start): Handle
>     GOACC_FLAG_HOST_DATA_IF_PRESENT flag.
>     * target.c (gomp_map_vars_async): Handle
>     GOMP_MAP_VARS_OPENACC_IF_PRESENT mapping kind.
> 
>     libgomp/testsuite/libgomp.oacc-c-c++-common/
>     * host_data-6.c: New test.

... to:

>     [...]
>     gcc/testsuite/
>     * c-c++-common/goacc/host_data-1.c: Add tests of if and if_present 
> clauses on host_data. [add suitable line break some where]
>     * gfortran.dg/goacc/host_data-tree.f95: Likewise.
>     [...]
>     libgomp/
>     * libgomp.h (enum gomp_map_vars_kind): Add
>     GOMP_MAP_VARS_OPENACC_IF_PRESENT.
>     * oacc-parallel.c (GOACC_data_start): Handle
>     GOACC_FLAG_HOST_DATA_IF_PRESENT flag.
>     * target.c (gomp_map_vars_async): Handle
>     GOMP_MAP_VARS_OPENACC_IF_PRESENT mapping kind.
>     * testsuite/libgomp.oacc-c-c++-common/host_data-6.c: New test.


Grüße
 Thomas


> From 6d719cc2bcfa8f7ed8cb59e753e44aab6bf634fb Mon Sep 17 00:00:00 2001
> From: Thomas Schwinge <tho...@codesourcery.com>
> Date: Wed, 19 Dec 2018 20:04:18 +0100
> Subject: [PATCH 1/2] For libgomp OpenACC entry points, redefine the "device"
>  argument to "flags"
> 
> ... so that we're then able to use this for other flags in addition to
> "GOACC_FLAG_HOST_FALLBACK".
> 
>       gcc/
>       * omp-expand.c (expand_omp_target): Restructure OpenACC vs. OpenMP
>       code paths.  Update for libgomp OpenACC entry points change.
>       include/
>       * gomp-constants.h (GOACC_FLAG_HOST_FALLBACK)
>       (GOACC_FLAGS_MARSHAL_OP, GOACC_FLAGS_UNMARSHAL): Define.
>       libgomp/
>       * oacc-parallel.c (GOACC_parallel_keyed, GOACC_parallel)
>       (GOACC_data_start, GOACC_enter_exit_data, GOACC_update)
>       (GOACC_declare): Redefine the "device" argument to "flags".
> ---
>  gcc/ChangeLog.openacc      |   5 ++
>  gcc/omp-expand.c           | 111 
> +++++++++++++++++++++++++++++----------------
>  gcc/tree-ssa-structalias.c |   4 +-
>  include/ChangeLog.openacc  |   5 ++
>  include/gomp-constants.h   |  12 +++++
>  libgomp/ChangeLog.openacc  |   6 +++
>  libgomp/oacc-parallel.c    |  60 ++++++++++++++----------
>  7 files changed, 139 insertions(+), 64 deletions(-)
> 
> diff --git a/gcc/ChangeLog.openacc b/gcc/ChangeLog.openacc
> index 718044c..6a51b1e 100644
> --- a/gcc/ChangeLog.openacc
> +++ b/gcc/ChangeLog.openacc
> @@ -1,3 +1,8 @@
> +2018-12-21  Thomas Schwinge  <tho...@codesourcery.com>
> +
> +     * omp-expand.c (expand_omp_target): Restructure OpenACC vs. OpenMP
> +     code paths.  Update for libgomp OpenACC entry points change.
> +
>  2018-12-21  Gergö Barany  <ge...@codesourcery.com>
>  
>       * omp-low.c (scan_sharing_clauses): Fix call to renamed function
> diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
> index 988b1bb..ea264da 100644
> --- a/gcc/omp-expand.c
> +++ b/gcc/omp-expand.c
> @@ -7204,7 +7204,7 @@ expand_omp_target (struct omp_region *region)
>       transfers.  */
>    tree t1, t2, t3, t4, device, cond, depend, c, clauses;
>    enum built_in_function start_ix;
> -  location_t clause_loc;
> +  location_t clause_loc = UNKNOWN_LOCATION;
>    unsigned int flags_i = 0;
>  
>    switch (gimple_omp_target_kind (entry_stmt))
> @@ -7249,49 +7249,62 @@ expand_omp_target (struct omp_region *region)
>  
>    clauses = gimple_omp_target_clauses (entry_stmt);
>  
> -  /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
> -     library choose) and there is no conditional.  */
> -  cond = NULL_TREE;
> -  device = build_int_cst (integer_type_node, GOMP_DEVICE_ICV);
> -
> -  c = omp_find_clause (clauses, OMP_CLAUSE_IF);
> -  if (c)
> -    cond = OMP_CLAUSE_IF_EXPR (c);
> -
> -  c = omp_find_clause (clauses, OMP_CLAUSE_DEVICE);
> -  if (c)
> +  device = NULL_TREE;
> +  tree goacc_flags = NULL_TREE;
> +  if (is_gimple_omp_oacc (entry_stmt))
>      {
> -      /* Even if we pass it to all library function calls, it is currently 
> only
> -      defined/used for the OpenMP target ones.  */
> -      gcc_checking_assert (start_ix == BUILT_IN_GOMP_TARGET
> -                        || start_ix == BUILT_IN_GOMP_TARGET_DATA
> -                        || start_ix == BUILT_IN_GOMP_TARGET_UPDATE
> -                        || start_ix == BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA);
> -
> -      device = OMP_CLAUSE_DEVICE_ID (c);
> -      clause_loc = OMP_CLAUSE_LOCATION (c);
> +      /* By default, no GOACC_FLAGs are set.  */
> +      goacc_flags = integer_zero_node;
>      }
>    else
> -    clause_loc = gimple_location (entry_stmt);
> -
> -  c = omp_find_clause (clauses, OMP_CLAUSE_NOWAIT);
> -  if (c)
> -    flags_i |= GOMP_TARGET_FLAG_NOWAIT;
> +    {
> +      c = omp_find_clause (clauses, OMP_CLAUSE_DEVICE);
> +      if (c)
> +     {
> +       device = OMP_CLAUSE_DEVICE_ID (c);
> +       clause_loc = OMP_CLAUSE_LOCATION (c);
> +     }
> +      else
> +     {
> +       /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
> +          library choose).  */
> +       device = build_int_cst (integer_type_node, GOMP_DEVICE_ICV);
> +       clause_loc = gimple_location (entry_stmt);
> +     }
>  
> -  /* Ensure 'device' is of the correct type.  */
> -  device = fold_convert_loc (clause_loc, integer_type_node, device);
> +      c = omp_find_clause (clauses, OMP_CLAUSE_NOWAIT);
> +      if (c)
> +     flags_i |= GOMP_TARGET_FLAG_NOWAIT;
> +    }
>  
> -  /* If we found the clause 'if (cond)', build
> -     (cond ? device : GOMP_DEVICE_HOST_FALLBACK).  */
> +  /* By default, there is no conditional.  */
> +  cond = NULL_TREE;
> +  c = omp_find_clause (clauses, OMP_CLAUSE_IF);
> +  if (c)
> +    cond = OMP_CLAUSE_IF_EXPR (c);
> +  /* If we found the clause 'if (cond)', build:
> +     OpenACC: goacc_flags = (cond ? goacc_flags : flags | 
> GOACC_FLAG_HOST_FALLBACK)
> +     OpenMP: device = (cond ? device : GOMP_DEVICE_HOST_FALLBACK) */
>    if (cond)
>      {
> +      tree *tp;
> +      if (is_gimple_omp_oacc (entry_stmt))
> +     tp = &goacc_flags;
> +      else
> +     {
> +       /* Ensure 'device' is of the correct type.  */
> +       device = fold_convert_loc (clause_loc, integer_type_node, device);
> +
> +       tp = &device;
> +     }
> +
>        cond = gimple_boolify (cond);
>  
>        basic_block cond_bb, then_bb, else_bb;
>        edge e;
>        tree tmp_var;
>  
> -      tmp_var = create_tmp_var (TREE_TYPE (device));
> +      tmp_var = create_tmp_var (TREE_TYPE (*tp));
>        if (offloaded)
>       e = split_block_after_labels (new_bb);
>        else
> @@ -7314,13 +7327,20 @@ expand_omp_target (struct omp_region *region)
>        gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
>  
>        gsi = gsi_start_bb (then_bb);
> -      stmt = gimple_build_assign (tmp_var, device);
> +      stmt = gimple_build_assign (tmp_var, *tp);
>        gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
>  
>        gsi = gsi_start_bb (else_bb);
> -      stmt = gimple_build_assign (tmp_var,
> -                               build_int_cst (integer_type_node,
> -                                              GOMP_DEVICE_HOST_FALLBACK));
> +      if (is_gimple_omp_oacc (entry_stmt))
> +     stmt = gimple_build_assign (tmp_var,
> +                                 BIT_IOR_EXPR,
> +                                 *tp,
> +                                 build_int_cst (integer_type_node,
> +                                                GOACC_FLAG_HOST_FALLBACK));
> +      else
> +     stmt = gimple_build_assign (tmp_var,
> +                                 build_int_cst (integer_type_node,
> +                                                GOMP_DEVICE_HOST_FALLBACK));
>        gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
>  
>        make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
> @@ -7330,14 +7350,17 @@ expand_omp_target (struct omp_region *region)
>        make_edge (then_bb, new_bb, EDGE_FALLTHRU);
>        make_edge (else_bb, new_bb, EDGE_FALLTHRU);
>  
> -      device = tmp_var;
> +      *tp = tmp_var;
> +
>        gsi = gsi_last_nondebug_bb (new_bb);
>      }
>    else
>      {
>        gsi = gsi_last_nondebug_bb (new_bb);
> -      device = force_gimple_operand_gsi (&gsi, device, true, NULL_TREE,
> -                                      true, GSI_SAME_STMT);
> +
> +      if (device != NULL_TREE)
> +     device = force_gimple_operand_gsi (&gsi, device, true, NULL_TREE,
> +                                        true, GSI_SAME_STMT);
>      }
>  
>    t = gimple_omp_target_data_arg (entry_stmt);
> @@ -7361,7 +7384,17 @@ expand_omp_target (struct omp_region *region)
>    bool tagging = false;
>    /* The maximum number used by any start_ix, without varargs.  */
>    auto_vec<tree, 11> args;
> -  args.quick_push (device);
> +  if (is_gimple_omp_oacc (entry_stmt))
> +    {
> +      tree goacc_flags_m = fold_build1 (GOACC_FLAGS_MARSHAL_OP,
> +                                     TREE_TYPE (goacc_flags), goacc_flags);
> +      goacc_flags_m = force_gimple_operand_gsi (&gsi, goacc_flags_m, true,
> +                                             NULL_TREE, true,
> +                                             GSI_SAME_STMT);
> +      args.quick_push (goacc_flags_m);
> +    }
> +  else
> +    args.quick_push (device);
>    if (start_ix == BUILT_IN_GOACC_PARALLEL)
>      {
>        tree use_params = oacc_parallel ? integer_one_node : integer_zero_node;
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index a4f7251..bcf3fd3 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -4684,7 +4684,7 @@ find_func_aliases_for_builtin_call (struct function 
> *fn, gcall *t)
>                 argpos = 1;
>                 break;
>               case BUILT_IN_GOACC_PARALLEL:
> -               /* __builtin_GOACC_parallel (device, fn, mapnum, hostaddrs,
> +               /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
>                                              sizes, kinds, ...).  */
>                 fnpos = 2;
>                 argpos = 4;
> @@ -5263,7 +5263,7 @@ find_func_clobbers (struct function *fn, gimple *origt)
>                 argpos = 1;
>                 break;
>               case BUILT_IN_GOACC_PARALLEL:
> -               /* __builtin_GOACC_parallel (device, fn, mapnum, hostaddrs,
> +               /* __builtin_GOACC_parallel (flags_m, fn, mapnum, hostaddrs,
>                                              sizes, kinds, ...).  */
>                 fnpos = 2;
>                 argpos = 4;
> diff --git a/include/ChangeLog.openacc b/include/ChangeLog.openacc
> index 20ed27f..aa583ea 100644
> --- a/include/ChangeLog.openacc
> +++ b/include/ChangeLog.openacc
> @@ -1,3 +1,8 @@
> +2018-12-21  Thomas Schwinge  <tho...@codesourcery.com>
> +
> +     * gomp-constants.h (GOACC_FLAG_HOST_FALLBACK)
> +     (GOACC_FLAGS_MARSHAL_OP, GOACC_FLAGS_UNMARSHAL): Define.
> +
>  2018-12-20  Julian Brown  <jul...@codesourcery.com>
>           Maciej W. Rozycki  <ma...@codesourcery.com>
>  
> diff --git a/include/gomp-constants.h b/include/gomp-constants.h
> index 27de5bc..b5d8441 100644
> --- a/include/gomp-constants.h
> +++ b/include/gomp-constants.h
> @@ -252,6 +252,18 @@ enum gomp_map_kind
>  /* Internal to libgomp.  */
>  #define GOMP_TARGET_FLAG_UPDATE              (1U << 31)
>  
> +
> +/* OpenACC construct flags.  */
> +
> +/* Force host fallback execution.  */
> +#define GOACC_FLAG_HOST_FALLBACK     (1 << 0)
> +
> +/* For legacy reasons, in the ABI, the GOACC_FLAGs are encoded as an inverted
> +   bitmask.  */
> +#define GOACC_FLAGS_MARSHAL_OP               BIT_NOT_EXPR
> +#define GOACC_FLAGS_UNMARSHAL(X)     (~(X))
> +
> +
>  /* Versions of libgomp and device-specific plugins.  GOMP_VERSION
>     should be incremented whenever an ABI-incompatible change is introduced
>     to the plugin interface defined in libgomp/libgomp.h.  */
> diff --git a/libgomp/ChangeLog.openacc b/libgomp/ChangeLog.openacc
> index b48453b..04cea5f 100644
> --- a/libgomp/ChangeLog.openacc
> +++ b/libgomp/ChangeLog.openacc
> @@ -1,3 +1,9 @@
> +2018-12-21  Thomas Schwinge  <tho...@codesourcery.com>
> +
> +     * oacc-parallel.c (GOACC_parallel_keyed, GOACC_parallel)
> +     (GOACC_data_start, GOACC_enter_exit_data, GOACC_update)
> +     (GOACC_declare): Redefine the "device" argument to "flags".
> +
>  2018-12-20  Gergö Barany  <ge...@codesourcery.com>
>           Thomas Schwinge  <tho...@codesourcery.com>
>  
> diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
> index c74221f..0b5f41a 100644
> --- a/libgomp/oacc-parallel.c
> +++ b/libgomp/oacc-parallel.c
> @@ -41,6 +41,16 @@
>  #include <stdarg.h>
>  #include <assert.h>
>  
> +
> +/* In the ABI, the GOACC_FLAGs are encoded as an inverted bitmask, so that we
> +   continue to support the following two legacy values.  */
> +_Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_ICV) == 0,
> +             "legacy GOMP_DEVICE_ICV broken");
> +_Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_HOST_FALLBACK)
> +             == GOACC_FLAG_HOST_FALLBACK,
> +             "legacy GOMP_DEVICE_HOST_FALLBACK broken");
> +
> +
>  /* Returns the number of mappings associated with the pointer or pset. PSET
>     have three mappings, whereas pointer have two.  */
>  
> @@ -159,17 +169,18 @@ goacc_call_host_fn (void (*fn) (void *), size_t mapnum, 
> void **hostaddrs,
>    fn (hostaddrs);
>  }
>  
> -/* Launch a possibly offloaded function on DEVICE.  FN is the host fn
> +/* Launch a possibly offloaded function with FLAGS.  FN is the host fn
>     address.  MAPNUM, HOSTADDRS, SIZES & KINDS  describe the memory
>     blocks to be copied to/from the device.  Varadic arguments are
>     keyed optional parameters terminated with a zero.  */
>  
>  static void
> -GOACC_parallel_keyed_internal (int device, int params, void (*fn) (void *),
> +GOACC_parallel_keyed_internal (int flags_m, int params, void (*fn) (void *),
>                              size_t mapnum, void **hostaddrs, size_t *sizes,
>                              unsigned short *kinds, va_list *ap)
>  {
> -  bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
> +  int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
> +
>    struct goacc_thread *thr;
>    struct gomp_device_descr *acc_dev;
>    struct target_mem_desc *tgt;
> @@ -252,7 +263,7 @@ GOACC_parallel_keyed_internal (int device, int params, 
> void (*fn) (void *),
>  
>    /* Host fallback if "if" clause is false or if the current device is set to
>       the host.  */
> -  if (host_fallback)
> +  if (flags & GOACC_FLAG_HOST_FALLBACK)
>      {
>        //TODO
>        prof_info.device_type = acc_device_host;
> @@ -448,25 +459,25 @@ GOACC_parallel_keyed_internal (int device, int params, 
> void (*fn) (void *),
>  }
>  
>  void
> -GOACC_parallel_keyed (int device, void (*fn) (void *),
> +GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
>                     size_t mapnum, void **hostaddrs, size_t *sizes,
>                     unsigned short *kinds, ...)
>  {
>    va_list ap;
>    va_start (ap, kinds);
> -  GOACC_parallel_keyed_internal (device, 0, fn, mapnum, hostaddrs, sizes,
> +  GOACC_parallel_keyed_internal (flags_m, 0, fn, mapnum, hostaddrs, sizes,
>                                kinds, &ap);
>    va_end (ap);
>  }
>  
>  void
> -GOACC_parallel_keyed_v2 (int device, int args, void (*fn) (void *),
> +GOACC_parallel_keyed_v2 (int flags_m, int args, void (*fn) (void *),
>                        size_t mapnum, void **hostaddrs, size_t *sizes,
>                        unsigned short *kinds, ...)
>  {
>    va_list ap;
>    va_start (ap, kinds);
> -  GOACC_parallel_keyed_internal (device, args, fn, mapnum, hostaddrs, sizes,
> +  GOACC_parallel_keyed_internal (flags_m, args, fn, mapnum, hostaddrs, sizes,
>                                kinds, &ap);
>    va_end (ap);
>  }
> @@ -474,7 +485,7 @@ GOACC_parallel_keyed_v2 (int device, int args, void (*fn) 
> (void *),
>  /* Legacy entry point, only provide host execution.  */
>  
>  void
> -GOACC_parallel (int device, void (*fn) (void *),
> +GOACC_parallel (int flags_m, void (*fn) (void *),
>               size_t mapnum, void **hostaddrs, size_t *sizes,
>               unsigned short *kinds,
>               int num_gangs, int num_workers, int vector_length,
> @@ -486,10 +497,11 @@ GOACC_parallel (int device, void (*fn) (void *),
>  }
>  
>  void
> -GOACC_data_start (int device, size_t mapnum,
> +GOACC_data_start (int flags_m, size_t mapnum,
>                 void **hostaddrs, size_t *sizes, unsigned short *kinds)
>  {
> -  bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
> +  int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
> +
>    struct target_mem_desc *tgt;
>  
>  #ifdef HAVE_INTTYPES_H
> @@ -575,7 +587,7 @@ GOACC_data_start (int device, size_t mapnum,
>  
>    /* Host fallback or 'do nothing'.  */
>    if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
> -      || host_fallback)
> +      || (flags & GOACC_FLAG_HOST_FALLBACK))
>      {
>        //TODO
>        prof_info.device_type = acc_device_host;
> @@ -694,13 +706,14 @@ GOACC_data_end (void)
>  }
>  
>  void
> -GOACC_enter_exit_data (int device, size_t mapnum,
> +GOACC_enter_exit_data (int flags_m, size_t mapnum,
>                      void **hostaddrs, size_t *sizes, unsigned short *kinds,
>                      int async, int num_waits, ...)
>  {
> +  int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
> +
>    struct goacc_thread *thr;
>    struct gomp_device_descr *acc_dev;
> -  bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
>    bool data_enter = false;
>    size_t i;
>  
> @@ -815,7 +828,7 @@ GOACC_enter_exit_data (int device, size_t mapnum,
>                             &api_info);
>  
>    if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
> -      || host_fallback)
> +      || (flags & GOACC_FLAG_HOST_FALLBACK))
>      {
>        //TODO
>        prof_info.device_type = acc_device_host;
> @@ -1098,11 +1111,12 @@ goacc_wait (int async, int num_waits, va_list *ap)
>  }
>  
>  void
> -GOACC_update (int device, size_t mapnum,
> +GOACC_update (int flags_m, size_t mapnum,
>             void **hostaddrs, size_t *sizes, unsigned short *kinds,
>             int async, int num_waits, ...)
>  {
> -  bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
> +  int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
> +
>    size_t i;
>  
>    goacc_lazy_initialize ();
> @@ -1163,7 +1177,7 @@ GOACC_update (int device, size_t mapnum,
>      goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
>  
>    if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
> -      || host_fallback)
> +      || (flags & GOACC_FLAG_HOST_FALLBACK))
>      {
>        //TODO
>        prof_info.device_type = acc_device_host;
> @@ -1309,7 +1323,7 @@ GOACC_get_thread_num (void)
>  }
>  
>  void
> -GOACC_declare (int device, size_t mapnum,
> +GOACC_declare (int flags_m, size_t mapnum,
>              void **hostaddrs, size_t *sizes, unsigned short *kinds)
>  {
>    int i;
> @@ -1329,7 +1343,7 @@ GOACC_declare (int device, size_t mapnum,
>         case GOMP_MAP_POINTER:
>         case GOMP_MAP_RELEASE:
>         case GOMP_MAP_DELETE:
> -         GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
> +         GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
>                                  &kinds[i], 0, 0);
>           break;
>  
> @@ -1338,18 +1352,18 @@ GOACC_declare (int device, size_t mapnum,
>  
>         case GOMP_MAP_ALLOC:
>           if (!acc_is_present (hostaddrs[i], sizes[i]))
> -           GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
> +           GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
>                                    &kinds[i], 0, 0);
>           break;
>  
>         case GOMP_MAP_TO:
> -         GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
> +         GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
>                                  &kinds[i], 0, 0);
>  
>           break;
>  
>         case GOMP_MAP_FROM:
> -         GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
> +         GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
>                                  &kinds[i], 0, 0);
>           break;
>  
> -- 
> 2.8.1
> 
> From cbd9efcd4ebb6c73a14ead01d85e452d63b7c937 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Gerg=C3=B6=20Barany?= <ge...@codesourcery.com>
> Date: Fri, 21 Dec 2018 01:12:44 -0800
> Subject: [PATCH 2/2] [og8] Add OpenACC 2.6 if and if_present clauses on
>  host_data construct: GOACC_FLAG_HOST_DATA_IF_PRESENT
> 
>     gcc/c/
>     * c-parser.c (OACC_HOST_DATA_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_IF
>     and PRAGMA_OACC_CLAUSE_IF_PRESENT.
>     gcc/cp/
>     * parser.c (OACC_HOST_DATA_CLAUSE_MASK): Likewise.
> 
>     gcc/fortran/
>     * openmp.c (OACC_HOST_DATA_CLAUSES): Add OMP_CLAUSE_IF and
>     OMP_CLAUSE_IF_PRESENT.
> 
>     gcc/
>     * omp-expand.c (expand_omp_target): Handle if_present flag on
>     OpenACC host_data construct.
> 
>     gcc/testsuite/c-c++-common/goacc/
>     * host_data-1.c: Add tests of if and if_present clauses on host_data.
>     gcc/testsuite/gfortran.dg/goacc/
>     * host_data-tree.f95: Likewise.
> 
>     include/
>     * gomp-constants.h (GOACC_FLAG_HOST_DATA_IF_PRESENT): New constant.
> 
>     libgomp/
>     * libgomp.h (enum gomp_map_vars_kind): Add
>     GOMP_MAP_VARS_OPENACC_IF_PRESENT.
> 
>     libgomp/
>     * oacc-parallel.c (GOACC_data_start): Handle
>     GOACC_FLAG_HOST_DATA_IF_PRESENT flag.
>     * target.c (gomp_map_vars_async): Handle
>     GOMP_MAP_VARS_OPENACC_IF_PRESENT mapping kind.
> 
>     libgomp/testsuite/libgomp.oacc-c-c++-common/
>     * host_data-6.c: New test.
> ---
>  gcc/ChangeLog.openacc                              |  5 ++
>  gcc/c/ChangeLog.openacc                            |  5 ++
>  gcc/c/c-parser.c                                   |  4 +-
>  gcc/cp/ChangeLog.openacc                           |  5 ++
>  gcc/cp/parser.c                                    |  4 +-
>  gcc/fortran/ChangeLog.openacc                      |  5 ++
>  gcc/fortran/openmp.c                               |  4 +-
>  gcc/omp-expand.c                                   | 12 ++++-
>  gcc/testsuite/ChangeLog.openacc                    |  6 +++
>  gcc/testsuite/c-c++-common/goacc/host_data-1.c     | 28 +++++++++++-
>  gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 | 12 ++++-
>  include/ChangeLog.openacc                          |  4 ++
>  include/gomp-constants.h                           |  2 +
>  libgomp/ChangeLog.openacc                          | 10 ++++
>  libgomp/libgomp.h                                  |  3 ++
>  libgomp/oacc-parallel.c                            | 11 +++--
>  libgomp/target.c                                   |  3 ++
>  .../libgomp.oacc-c-c++-common/host_data-6.c        | 53 
> ++++++++++++++++++++++
>  18 files changed, 167 insertions(+), 9 deletions(-)
>  create mode 100644 libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-6.c
> 
> diff --git a/gcc/ChangeLog.openacc b/gcc/ChangeLog.openacc
> index 6a51b1e..66eba7b 100644
> --- a/gcc/ChangeLog.openacc
> +++ b/gcc/ChangeLog.openacc
> @@ -1,3 +1,8 @@
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
> +     * omp-expand.c (expand_omp_target): Handle if_present flag on
> +     OpenACC host_data construct.
> +
>  2018-12-21  Thomas Schwinge  <tho...@codesourcery.com>
>  
>       * omp-expand.c (expand_omp_target): Restructure OpenACC vs. OpenMP
> diff --git a/gcc/c/ChangeLog.openacc b/gcc/c/ChangeLog.openacc
> index 10c00e5..e607ea8 100644
> --- a/gcc/c/ChangeLog.openacc
> +++ b/gcc/c/ChangeLog.openacc
> @@ -1,3 +1,8 @@
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
> +     * c-parser.c (OACC_HOST_DATA_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_IF
> +     and PRAGMA_OACC_CLAUSE_IF_PRESENT.
> +
>  2018-12-20  Julian Brown  <jul...@codesourcery.com>
>           Maciej W. Rozycki  <ma...@codesourcery.com>
>  
> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
> index a352d54..2bc4f45 100644
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -14876,7 +14876,9 @@ c_parser_oacc_enter_exit_data (c_parser *parser, bool 
> enter)
>  */
>  
>  #define OACC_HOST_DATA_CLAUSE_MASK                                   \
> -     ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
> +        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)          \
> +        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
> +        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
>  
>  static tree
>  c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
> diff --git a/gcc/cp/ChangeLog.openacc b/gcc/cp/ChangeLog.openacc
> index 37b0028..76889c7 100644
> --- a/gcc/cp/ChangeLog.openacc
> +++ b/gcc/cp/ChangeLog.openacc
> @@ -1,3 +1,8 @@
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
> +     * parser.c (OACC_HOST_DATA_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_IF
> +     and PRAGMA_OACC_CLAUSE_IF_PRESENT.
> +
>  2018-12-20  Julian Brown  <jul...@codesourcery.com>
>           Maciej W. Rozycki  <ma...@codesourcery.com>
>  
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 083700b..38b0a6d 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -36973,7 +36973,9 @@ cp_parser_oacc_data (cp_parser *parser, cp_token 
> *pragma_tok, bool *if_p)
>    structured-block  */
>  
>  #define OACC_HOST_DATA_CLAUSE_MASK                                   \
> -  ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
> +  ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)                \
> +  | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                        \
> +  | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
>  
>  static tree
>  cp_parser_oacc_host_data (cp_parser *parser, cp_token *pragma_tok, bool 
> *if_p)
> diff --git a/gcc/fortran/ChangeLog.openacc b/gcc/fortran/ChangeLog.openacc
> index a369219..306871e 100644
> --- a/gcc/fortran/ChangeLog.openacc
> +++ b/gcc/fortran/ChangeLog.openacc
> @@ -1,3 +1,8 @@
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
> +     * openmp.c (OACC_HOST_DATA_CLAUSES): Add OMP_CLAUSE_IF and
> +     OMP_CLAUSE_IF_PRESENT.
> +
>  2018-12-20  Julian Brown  <jul...@codesourcery.com>
>           Maciej W. Rozycki  <ma...@codesourcery.com>
>  
> diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
> index 350f4b1..4273dee 100644
> --- a/gcc/fortran/openmp.c
> +++ b/gcc/fortran/openmp.c
> @@ -2107,7 +2107,9 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, omp_mask 
> mask,
>     | OMP_CLAUSE_CREATE | OMP_CLAUSE_NO_CREATE | OMP_CLAUSE_PRESENT   \
>     | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_ATTACH)
>  #define OACC_HOST_DATA_CLAUSES \
> -  (omp_mask (OMP_CLAUSE_USE_DEVICE))
> +  (omp_mask (OMP_CLAUSE_USE_DEVICE)                                     \
> +   | OMP_CLAUSE_IF                                                      \
> +   | OMP_CLAUSE_IF_PRESENT)
>  #define OACC_LOOP_CLAUSES \
>    (omp_mask (OMP_CLAUSE_COLLAPSE)                                    \
>     | OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR         \
> diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
> index ea264da..42c4910 100644
> --- a/gcc/omp-expand.c
> +++ b/gcc/omp-expand.c
> @@ -7254,7 +7254,17 @@ expand_omp_target (struct omp_region *region)
>    if (is_gimple_omp_oacc (entry_stmt))
>      {
>        /* By default, no GOACC_FLAGs are set.  */
> -      goacc_flags = integer_zero_node;
> +      int goacc_flags_i = 0;
> +
> +      if (start_ix != BUILT_IN_GOACC_UPDATE
> +       && omp_find_clause (clauses, OMP_CLAUSE_IF_PRESENT))
> +     {
> +       gcc_checking_assert (gimple_omp_target_kind (entry_stmt)
> +                            == GF_OMP_TARGET_KIND_OACC_HOST_DATA);
> +       goacc_flags_i |= GOACC_FLAG_HOST_DATA_IF_PRESENT;
> +     }
> +
> +      goacc_flags = build_int_cst (integer_type_node, goacc_flags_i);
>      }
>    else
>      {
> diff --git a/gcc/testsuite/ChangeLog.openacc b/gcc/testsuite/ChangeLog.openacc
> index 473eb9d..2e4bd3d 100644
> --- a/gcc/testsuite/ChangeLog.openacc
> +++ b/gcc/testsuite/ChangeLog.openacc
> @@ -1,5 +1,11 @@
>  2018-12-21  Gergö Barany  <ge...@codesourcery.com>
>  
> +     * c-c++-common/goacc/host_data-1.c: Add tests of if and if_present
> +     clauses on host_data.
> +     * gfortran.dg/goacc/host_data-tree.f95: Likewise.
> +
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
>       * c-c++-common/goacc/nested-reductions-fail.c: Renamed to...
>       * c-c++-common/goacc/nested-reductions-parallel-fail.c: ...this file,
>       with kernels tests...
> diff --git a/gcc/testsuite/c-c++-common/goacc/host_data-1.c 
> b/gcc/testsuite/c-c++-common/goacc/host_data-1.c
> index 0c7a857..658b7a6 100644
> --- a/gcc/testsuite/c-c++-common/goacc/host_data-1.c
> +++ b/gcc/testsuite/c-c++-common/goacc/host_data-1.c
> @@ -7,6 +7,9 @@ f (void)
>  {
>  #pragma acc host_data use_device(v1)
>    ;
> +
> +#pragma acc host_data use_device(v1) if_present
> +  ;
>  }
>  
>  
> @@ -16,9 +19,32 @@ void
>  foo (float *x, float *y)
>  {
>    int n = 1 << 10;
> -#pragma acc data create(x[0:n]) copyout(y[0:n])
> +#pragma acc data create(x[0:n])
>    {
> +    bar (x, y);
> +
> +    /* This should fail at run time because y is not mapped.  */
>  #pragma acc host_data use_device(x,y)
>      bar (x, y);
> +
> +    /* y is still not mapped, but this should not fail at run time but
> +       continue execution with y remaining as the host address.  */
> +#pragma acc host_data use_device(x,y) if_present
> +    bar (x, y);
> +
> +#pragma acc data copyout(y[0:n])
> +    {
> +#pragma acc host_data use_device(x,y)
> +      bar (x, y);
> +
> +#pragma acc host_data use_device(x,y) if_present
> +      bar (x, y);
> +
> +#pragma acc host_data use_device(x,y) if(x != y)
> +      bar (x, y);
> +
> +#pragma acc host_data use_device(x,y) if_present if(x != y)
> +      bar (x, y);
> +    }
>    }
>  }
> diff --git a/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 
> b/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95
> index d44ca58..2ac1c0d 100644
> --- a/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95
> +++ b/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95
> @@ -7,5 +7,15 @@ program test
>  
>    !$acc host_data use_device(p)
>    !$acc end host_data
> +
> +  !$acc host_data use_device(p) if (p == 42)
> +  !$acc end host_data
> +
> +  !$acc host_data use_device(p) if_present if (p == 43)
> +  !$acc end host_data
>  end program test
> -! { dg-final { scan-tree-dump-times "pragma acc host_data 
> use_device_ptr\\(p\\)" 1 "original" } }
> +! { dg-final { scan-tree-dump-times "pragma acc host_data 
> use_device_ptr\\(p\\)" 3 "original" } }
> +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*p == 42;" 1 "original" 
> } }
> +! { dg-final { scan-tree-dump-times "pragma acc host_data 
> use_device_ptr\\(p\\) if\\(D.\[0-9\]+\\)" 2 "original" } }
> +! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = \\*p == 43;" 1 "original" 
> } }
> +! { dg-final { scan-tree-dump-times "pragma acc host_data 
> use_device_ptr\\(p\\) if\\(D.\[0-9\]+\\) if_present" 1 "original" } }
> diff --git a/include/ChangeLog.openacc b/include/ChangeLog.openacc
> index aa583ea..82058e7 100644
> --- a/include/ChangeLog.openacc
> +++ b/include/ChangeLog.openacc
> @@ -1,3 +1,7 @@
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
> +     * gomp-constants.h (GOACC_FLAG_HOST_DATA_IF_PRESENT): New constant.
> +
>  2018-12-21  Thomas Schwinge  <tho...@codesourcery.com>
>  
>       * gomp-constants.h (GOACC_FLAG_HOST_FALLBACK)
> diff --git a/include/gomp-constants.h b/include/gomp-constants.h
> index b5d8441..953df8f 100644
> --- a/include/gomp-constants.h
> +++ b/include/gomp-constants.h
> @@ -257,6 +257,8 @@ enum gomp_map_kind
>  
>  /* Force host fallback execution.  */
>  #define GOACC_FLAG_HOST_FALLBACK     (1 << 0)
> +/* "if_present" semantics for OpenACC "host_data" constructs.  */
> +#define GOACC_FLAG_HOST_DATA_IF_PRESENT      (1 << 1)
>  
>  /* For legacy reasons, in the ABI, the GOACC_FLAGs are encoded as an inverted
>     bitmask.  */
> diff --git a/libgomp/ChangeLog.openacc b/libgomp/ChangeLog.openacc
> index 04cea5f..7b9e2c5 100644
> --- a/libgomp/ChangeLog.openacc
> +++ b/libgomp/ChangeLog.openacc
> @@ -1,3 +1,13 @@
> +2018-12-21  Gergö Barany  <ge...@codesourcery.com>
> +
> +     * libgomp.h (enum gomp_map_vars_kind): Add
> +     GOMP_MAP_VARS_OPENACC_IF_PRESENT.
> +     * oacc-parallel.c (GOACC_data_start): Handle
> +     GOACC_FLAG_HOST_DATA_IF_PRESENT flag.
> +     * target.c (gomp_map_vars_async): Handle
> +     GOMP_MAP_VARS_OPENACC_IF_PRESENT mapping kind.
> +     * testsuite/libgomp.oacc-c-c++-common/host_data-6.c: New test.
> +
>  2018-12-21  Thomas Schwinge  <tho...@codesourcery.com>
>  
>       * oacc-parallel.c (GOACC_parallel_keyed, GOACC_parallel)
> diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
> index 64895c5..11948d5 100644
> --- a/libgomp/libgomp.h
> +++ b/libgomp/libgomp.h
> @@ -1024,6 +1024,9 @@ struct gomp_device_descr
>  enum gomp_map_vars_kind
>  {
>    GOMP_MAP_VARS_OPENACC,
> +  /* Like "GOMP_MAP_VARS_OPENACC", but with "GOACC_FLAG_HOST_DATA_IF_PRESENT"
> +     semantics.  */
> +  GOMP_MAP_VARS_OPENACC_IF_PRESENT,
>    GOMP_MAP_VARS_OPENACC_ENTER_DATA,
>    GOMP_MAP_VARS_TARGET,
>    GOMP_MAP_VARS_DATA,
> diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
> index 0b5f41a..3da87a1 100644
> --- a/libgomp/oacc-parallel.c
> +++ b/libgomp/oacc-parallel.c
> @@ -585,6 +585,12 @@ GOACC_data_start (int flags_m, size_t mapnum,
>  
>    handle_ftn_pointers (mapnum, hostaddrs, sizes, kinds);
>  
> +  enum gomp_map_vars_kind pragma_kind;
> +  if (flags & GOACC_FLAG_HOST_DATA_IF_PRESENT)
> +    pragma_kind = GOMP_MAP_VARS_OPENACC_IF_PRESENT;
> +  else
> +    pragma_kind = GOMP_MAP_VARS_OPENACC;
> +
>    /* Host fallback or 'do nothing'.  */
>    if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
>        || (flags & GOACC_FLAG_HOST_FALLBACK))
> @@ -592,8 +598,7 @@ GOACC_data_start (int flags_m, size_t mapnum,
>        //TODO
>        prof_info.device_type = acc_device_host;
>        api_info.device_type = prof_info.device_type;
> -      tgt = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, true,
> -                        GOMP_MAP_VARS_OPENACC);
> +      tgt = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, true, 
> pragma_kind);
>        tgt->prev = thr->mapped_data;
>        thr->mapped_data = tgt;
>        goto out;
> @@ -601,7 +606,7 @@ GOACC_data_start (int flags_m, size_t mapnum,
>  
>    gomp_debug (0, "  %s: prepare mappings\n", __FUNCTION__);
>    tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs, NULL, sizes, kinds, true,
> -                    GOMP_MAP_VARS_OPENACC);
> +                    pragma_kind);
>    gomp_debug (0, "  %s: mappings prepared\n", __FUNCTION__);
>    tgt->prev = thr->mapped_data;
>    thr->mapped_data = tgt;
> diff --git a/libgomp/target.c b/libgomp/target.c
> index 0594405..bdfd640 100644
> --- a/libgomp/target.c
> +++ b/libgomp/target.c
> @@ -1137,6 +1137,9 @@ gomp_map_vars_async (struct gomp_device_descr *devicep,
>         splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
>         if (n == NULL)
>           {
> +              if (pragma_kind == GOMP_MAP_VARS_OPENACC_IF_PRESENT)
> +                /* No error, continue using the host address.  */
> +                continue;
>             gomp_mutex_unlock (&devicep->lock);
>             gomp_fatal ("use_device_ptr pointer wasn't mapped");
>           }
> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-6.c 
> b/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-6.c
> new file mode 100644
> index 0000000..c5744fe
> --- /dev/null
> +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-6.c
> @@ -0,0 +1,53 @@
> +/* Test if, if_present clauses on host_data construct.  */
> +
> +#include <assert.h>
> +#include <stdint.h>
> +
> +void
> +foo (float *p, intptr_t host_p, int shared_mem_p, int cond)
> +{
> +  assert (p == (float *) host_p);
> +
> +#pragma acc data copyin(host_p)
> +  {
> +#pragma acc host_data use_device(p) if_present
> +    /* p not mapped yet, so it will be equal to the host pointer.  */
> +    assert (p == (float *) host_p);
> +
> +#pragma acc data copy(p[0:100])
> +    {
> +      /* Not inside a host_data construct, so p is still the host pointer.  
> */
> +      assert (p == (float *) host_p);
> +
> +      if (!shared_mem_p)
> +      {
> +#pragma acc host_data use_device(p)
> +        /* The device address is different from the host address.  */
> +        assert (p != (float *) host_p);
> +
> +#pragma acc host_data use_device(p) if_present
> +        /* p is present now, so this is the same as above.  */
> +        assert (p != (float *) host_p);
> +      }
> +
> +#pragma acc host_data use_device(p) if(cond)
> +      /* p is the device pointer iff cond is true and device memory is
> +         separate from host memory.  */
> +      assert ((p != (float *) host_p) == (cond && !shared_mem_p));
> +    }
> +  }
> +}
> +
> +int
> +main (void)
> +{
> +  float arr[100];
> +  int shared_mem_p = 0;
> +#if ACC_MEM_SHARED
> +  shared_mem_p = 1;
> +#endif
> +  foo (arr, (intptr_t) arr, shared_mem_p, 0);
> +  foo (arr, (intptr_t) arr, shared_mem_p, 1);
> +
> +  return 0;
> +}
> -- 
> 2.8.1
> 

Reply via email to