OpenACC: Separate enter/exit data APIs Move the OpenACC enter and exit data directives from using a single builtin to having one each. For most purposes it was easy to tell which was which, from the directives given, but there are some exceptions. In particular, zero-length array copies are indistiguishable, but we still want reference counting to work. gcc/ChangeLog: * gimple-pretty-print.c (dump_gimple_omp_target): Replace GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA with GF_OMP_TARGET_KIND_OACC_ENTER_DATA and GF_OMP_TARGET_KIND_OACC_EXIT_DATA. * gimple.h (enum gf_mask): Likewise. (is_gimple_omp_oacc): Likewise. * gimplify.c (gimplify_omp_target_update): Likewise. * omp-builtins.def (BUILT_IN_GOACC_ENTER_EXIT_DATA): Delete. (BUILT_IN_GOACC_ENTER_DATA): Add new. (BUILT_IN_GOACC_EXIT_DATA): Add new. * omp-expand.c (expand_omp_target): Replace GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA with GF_OMP_TARGET_KIND_OACC_ENTER_DATA and GF_OMP_TARGET_KIND_OACC_EXIT_DATA. (build_omp_regions_1): Likewise. (omp_make_gimple_edges): Likewise. * omp-low.c (check_omp_nesting_restrictions): Likewise. (lower_omp_target): Likewise. libgomp/ChangeLog: * libgomp.map: Add GOACC_enter_data and GOACC_exit_data. * libgomp_g.h (GOACC_enter_exit_data): Delete. (GOACC_enter_data): New prototype. (GOACC_exit_data) New prototype.: * oacc-mem.c (GOACC_enter_exit_data): Move most of the content ... (GOACC_enter_exit_data_internal): ... here. (GOACC_enter_data): New function. (GOACC_exit_data) New function.: * oacc-parallel.c (GOACC_declare): Replace GOACC_enter_exit_data with GOACC_enter_data and GOACC_exit_data. diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index e05b770138e..a4dfc493588 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1694,8 +1694,11 @@ dump_gimple_omp_target (pretty_printer *buffer, const gomp_target *gs, case GF_OMP_TARGET_KIND_OACC_UPDATE: kind = " oacc_update"; break; - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: - kind = " oacc_enter_exit_data"; + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + kind = " oacc_enter_data"; + break; + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: + kind = " oacc_exit_data"; break; case GF_OMP_TARGET_KIND_OACC_DECLARE: kind = " oacc_declare"; diff --git a/gcc/gimple.h b/gcc/gimple.h index d64c47a7d0d..681000d2ae4 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -180,9 +180,10 @@ enum gf_mask { GF_OMP_TARGET_KIND_OACC_SERIAL = 7, GF_OMP_TARGET_KIND_OACC_DATA = 8, GF_OMP_TARGET_KIND_OACC_UPDATE = 9, - GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 10, + GF_OMP_TARGET_KIND_OACC_ENTER_DATA = 10, GF_OMP_TARGET_KIND_OACC_DECLARE = 11, GF_OMP_TARGET_KIND_OACC_HOST_DATA = 12, + GF_OMP_TARGET_KIND_OACC_EXIT_DATA = 13, GF_OMP_TEAMS_GRID_PHONY = 1 << 0, GF_OMP_TEAMS_HOST = 1 << 1, @@ -6587,7 +6588,8 @@ is_gimple_omp_oacc (const gimple *stmt) case GF_OMP_TARGET_KIND_OACC_SERIAL: case GF_OMP_TARGET_KIND_OACC_DATA: case GF_OMP_TARGET_KIND_OACC_UPDATE: - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_DECLARE: case GF_OMP_TARGET_KIND_OACC_HOST_DATA: return true; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 15dfee903ab..6948c1ccdbb 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -12950,8 +12950,11 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p) switch (TREE_CODE (expr)) { case OACC_ENTER_DATA: + kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA; + ort = ORT_ACC; + break; case OACC_EXIT_DATA: - kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA; + kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA; ort = ORT_ACC; break; case OACC_UPDATE: diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def index f461d60e52b..ab45eecb752 100644 --- a/gcc/omp-builtins.def +++ b/gcc/omp-builtins.def @@ -35,7 +35,10 @@ DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_START, "GOACC_data_start", BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_END, "GOACC_data_end", BT_FN_VOID, ATTR_NOTHROW_LIST) -DEF_GOACC_BUILTIN (BUILT_IN_GOACC_ENTER_EXIT_DATA, "GOACC_enter_exit_data", +DEF_GOACC_BUILTIN (BUILT_IN_GOACC_ENTER_DATA, "GOACC_enter_data", + BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR, + ATTR_NOTHROW_LIST) +DEF_GOACC_BUILTIN (BUILT_IN_GOACC_EXIT_DATA, "GOACC_exit_data", BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_PARALLEL, "GOACC_parallel_keyed", diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index ee354b7ef9c..0e21ea90d90 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -8787,7 +8787,8 @@ expand_omp_target (struct omp_region *region) case GF_OMP_TARGET_KIND_OACC_KERNELS: case GF_OMP_TARGET_KIND_OACC_SERIAL: case GF_OMP_TARGET_KIND_OACC_UPDATE: - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_DECLARE: data_region = false; break; @@ -9052,8 +9053,11 @@ expand_omp_target (struct omp_region *region) case GF_OMP_TARGET_KIND_OACC_UPDATE: start_ix = BUILT_IN_GOACC_UPDATE; break; - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: - start_ix = BUILT_IN_GOACC_ENTER_EXIT_DATA; + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + start_ix = BUILT_IN_GOACC_ENTER_DATA; + break; + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: + start_ix = BUILT_IN_GOACC_EXIT_DATA; break; case GF_OMP_TARGET_KIND_OACC_DECLARE: start_ix = BUILT_IN_GOACC_DECLARE; @@ -9251,7 +9255,8 @@ expand_omp_target (struct omp_region *region) oacc_set_fn_attrib (child_fn, clauses, &args); tagging = true; /* FALLTHRU */ - case BUILT_IN_GOACC_ENTER_EXIT_DATA: + case BUILT_IN_GOACC_ENTER_DATA: + case BUILT_IN_GOACC_EXIT_DATA: case BUILT_IN_GOACC_UPDATE: { tree t_async = NULL_TREE; @@ -9822,7 +9827,8 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent, case GF_OMP_TARGET_KIND_ENTER_DATA: case GF_OMP_TARGET_KIND_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_UPDATE: - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_DECLARE: /* ..., other than for those stand-alone directives... */ region = NULL; @@ -10077,7 +10083,8 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region, case GF_OMP_TARGET_KIND_ENTER_DATA: case GF_OMP_TARGET_KIND_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_UPDATE: - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_DECLARE: cur_region = cur_region->outer; break; diff --git a/gcc/omp-low.c b/gcc/omp-low.c index da6c275f4a0..df9d108c8a7 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3414,8 +3414,10 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx) case GF_OMP_TARGET_KIND_OACC_SERIAL: stmt_name = "serial"; break; case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break; case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break; - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: - stmt_name = "enter/exit data"; break; + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + stmt_name = "enter data"; break; + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: + stmt_name = "exit data"; break; case GF_OMP_TARGET_KIND_OACC_DECLARE: stmt_name = "declare"; break; case GF_OMP_TARGET_KIND_OACC_HOST_DATA: stmt_name = "host_data"; break; @@ -11402,7 +11404,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) case GF_OMP_TARGET_KIND_OACC_KERNELS: case GF_OMP_TARGET_KIND_OACC_SERIAL: case GF_OMP_TARGET_KIND_OACC_UPDATE: - case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: + case GF_OMP_TARGET_KIND_OACC_ENTER_DATA: + case GF_OMP_TARGET_KIND_OACC_EXIT_DATA: case GF_OMP_TARGET_KIND_OACC_DECLARE: data_region = false; break; diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map index c808e810702..3965f036c43 100644 --- a/libgomp/libgomp.map +++ b/libgomp/libgomp.map @@ -517,6 +517,8 @@ GOACC_2.0 { global: GOACC_data_end; GOACC_data_start; + GOACC_enter_data; + GOACC_exit_data; GOACC_enter_exit_data; GOACC_parallel; GOACC_update; diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h index 59e3697bfd8..51df36bc8db 100644 --- a/libgomp/libgomp_g.h +++ b/libgomp/libgomp_g.h @@ -363,8 +363,10 @@ extern void GOACC_wait (int, int, ...); /* oacc-mem.c */ -extern void GOACC_enter_exit_data (int, size_t, void **, size_t *, - unsigned short *, int, int, ...); +extern void GOACC_enter_data (int, size_t, void **, size_t *, + unsigned short *, int, int, ...); +extern void GOACC_exit_data (int, size_t, void **, size_t *, + unsigned short *, int, int, ...); /* oacc-parallel.c */ diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c index 65757ab2ffc..45162d24786 100644 --- a/libgomp/oacc-mem.c +++ b/libgomp/oacc-mem.c @@ -1317,56 +1317,21 @@ goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum, gomp_mutex_unlock (&acc_dev->lock); } -void -GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs, - size_t *sizes, unsigned short *kinds, int async, - int num_waits, ...) +static void +GOACC_enter_exit_data_internal (int flags_m, size_t mapnum, void **hostaddrs, + size_t *sizes, unsigned short *kinds, + int async, bool data_enter, int num_waits, ...) { int flags = GOACC_FLAGS_UNMARSHAL (flags_m); struct goacc_thread *thr; struct gomp_device_descr *acc_dev; - bool data_enter = false; - size_t i; goacc_lazy_initialize (); thr = goacc_thread (); acc_dev = thr->dev; - /* Determine if this is an "acc enter data". */ - for (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); - } - bool profiling_p = GOACC_PROFILING_DISPATCH_P (true); acc_prof_info prof_info; @@ -1458,3 +1423,71 @@ GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs, thr->api_info = NULL; } } + +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; + GOACC_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds, + async, true, num_waits, 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; + GOACC_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds, + async, false, num_waits, ap); +} + +/* This function is not used. It is provided for backwards compatibility + with older user-binaries only. */ + +void +GOACC_enter_exit_data (int flags_m, size_t mapnum, void **hostaddrs, + size_t *sizes, unsigned short *kinds, int async, + int num_waits, ...) +{ + bool data_enter = false; + + /* Determine if this is an "acc enter data". */ + for (int 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; + GOACC_enter_exit_data_internal (flags_m, mapnum, hostaddrs, sizes, kinds, + async, data_enter, num_waits, ap); +} diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c index c7e46e35bd6..bca31b51427 100644 --- a/libgomp/oacc-parallel.c +++ b/libgomp/oacc-parallel.c @@ -745,12 +745,15 @@ GOACC_declare (int flags_m, size_t mapnum, switch (kind) { case GOMP_MAP_FORCE_ALLOC: - case GOMP_MAP_FORCE_FROM: case GOMP_MAP_FORCE_TO: - case GOMP_MAP_POINTER: + GOACC_enter_data (flags_m, 1, &hostaddrs[i], &sizes[i], + &kinds[i], GOMP_ASYNC_SYNC, 0); + break; + + case GOMP_MAP_FORCE_FROM: case GOMP_MAP_RELEASE: case GOMP_MAP_DELETE: - GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i], + GOACC_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i], &kinds[i], GOMP_ASYNC_SYNC, 0); break; @@ -759,19 +762,19 @@ GOACC_declare (int flags_m, size_t mapnum, case GOMP_MAP_ALLOC: if (!acc_is_present (hostaddrs[i], sizes[i])) - GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i], - &kinds[i], GOMP_ASYNC_SYNC, 0); + GOACC_enter_data (flags_m, 1, &hostaddrs[i], &sizes[i], + &kinds[i], GOMP_ASYNC_SYNC, 0); break; case GOMP_MAP_TO: - GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i], - &kinds[i], GOMP_ASYNC_SYNC, 0); + GOACC_enter_data (flags_m, 1, &hostaddrs[i], &sizes[i], + &kinds[i], GOMP_ASYNC_SYNC, 0); break; case GOMP_MAP_FROM: - GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i], - &kinds[i], GOMP_ASYNC_SYNC, 0); + GOACC_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i], + &kinds[i], GOMP_ASYNC_SYNC, 0); break; case GOMP_MAP_FORCE_PRESENT: