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?
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/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.
>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