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.
* 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.
* 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.
Reviewed-by: Thomas Schwinge <thomas@codesourcery.com>
(cherry picked from openacc-gcc-9-branch commit
b52c8d006581b2a657ac3d81ab2527bb398b6615)
+2018-12-21 Gergö Barany <gergo@codesourcery.com>
+
+ * omp-expand.c (expand_omp_target): Handle if_present flag on
+ OpenACC host_data construct.
+
2018-12-20 Gergö Barany <gergo@codesourcery.com>
* omp-low.c (struct omp_context): New fields
+2018-12-21 Gergö Barany <gergo@codesourcery.com>
+
+ * c-parser.c (OACC_HOST_DATA_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_IF
+ and PRAGMA_OACC_CLAUSE_IF_PRESENT.
+
2018-12-13 Cesar Philippidis <cesar@codesourcery.com>
Nathan Sidwell <nathan@acm.org>
Julian Brown <julian@codesourcery.com>
*/
#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)
+2018-12-21 Gergö Barany <gergo@codesourcery.com>
+
+ * parser.c (OACC_HOST_DATA_CLAUSE_MASK): Likewise.
+
2018-12-13 Cesar Philippidis <cesar@codesourcery.com>
Nathan Sidwell <nathan@acm.org>
Julian Brown <julian@codesourcery.com>
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)
+2018-12-21 Gergö Barany <gergo@codesourcery.com>
+
+ * openmp.c (OACC_HOST_DATA_CLAUSES): Add OMP_CLAUSE_IF and
+ OMP_CLAUSE_IF_PRESENT.
+
2019-01-30 Kwok Cheung Yeung <kcy@codesourcery.com>
* trans-openmp.c (gfc_build_conditional_assign): New.
(OACC_LOOP_CLAUSES | OACC_PARALLEL_CLAUSES)
#define OACC_KERNELS_LOOP_CLAUSES \
(OACC_LOOP_CLAUSES | OACC_KERNELS_CLAUSES)
-#define OACC_HOST_DATA_CLAUSES omp_mask (OMP_CLAUSE_USE_DEVICE)
+#define OACC_HOST_DATA_CLAUSES \
+ (omp_mask (OMP_CLAUSE_USE_DEVICE) \
+ | OMP_CLAUSE_IF \
+ | OMP_CLAUSE_IF_PRESENT)
#define OACC_DECLARE_CLAUSES \
(omp_mask (OMP_CLAUSE_COPY) | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT \
| OMP_CLAUSE_CREATE | OMP_CLAUSE_DEVICEPTR | OMP_CLAUSE_DEVICE_RESIDENT \
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
{
+2018-12-21 Gergö Barany <gergo@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-20 Gergö Barany <gergo@codesourcery.com>
* c-c++-common/goacc/nested-reductions-fail.c: New test.
{
#pragma acc host_data use_device(v1)
;
+
+#pragma acc host_data use_device(v1) if_present
+ ;
}
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);
+ }
}
}
!$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" } }
+2018-12-21 Gergö Barany <gergo@codesourcery.com>
+
+ * gomp-constants.h (GOACC_FLAG_HOST_DATA_IF_PRESENT): New constant.
+
2018-10-04 Cesar Philippidis <cesar@codesourcery.com>
Julian Brown <julian@codesourcery.com>
/* 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. */
+2018-12-21 Gergö Barany <gergo@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-20 Gergö Barany <gergo@codesourcery.com>
* testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c:
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,
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))
{
- 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;
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;
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");
}
--- /dev/null
+/* 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;
+}