OpenMP: Handle tofrom with target enter/exit data In 5.2, a map clause can be map-entering or map-exiting, either containing 'tofrom'. The main reason for this is permit 'map(x)' with 'omp target enter/exit data', avoiding to specify 'to:/from:' explicitly. (OpenMP defaults to 'tofrom'.) gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_target_enter_data, c_parser_omp_target_exit_data): Accept tofrom map-type modifier but use 'to' / 'from' internally. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_target_enter_data, cp_parser_omp_target_exit_data): Accept tofrom map-type modifier but use 'to' / 'from' internally. gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_namelist): For the map-type, also handle the always modifer and release/delete. * openmp.cc (resolve_omp_clauses): Accept tofrom map-type modifier for target enter/exit data, but use 'to' / 'from' internally. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark target enter/exit data with fromto as implemented. gcc/testsuite/ChangeLog: * c-c++-common/gomp/target-data-2.c: New test. * c-c++-common/gomp/target-data-3.c: New test. * gfortran.dg/gomp/target-data-1.f90: New test. * gfortran.dg/gomp/target-data-2.f90: New test. gcc/c/c-parser.cc | 22 +++++++++++++++++++--- gcc/cp/parser.cc | 22 +++++++++++++++++++--- gcc/fortran/dump-parse-tree.cc | 5 +++++ gcc/fortran/openmp.cc | 20 ++++++++++++++++---- gcc/testsuite/c-c++-common/gomp/target-data-2.c | 20 ++++++++++++++++++++ gcc/testsuite/c-c++-common/gomp/target-data-3.c | 17 +++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/target-data-1.f90 | 17 +++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/target-data-2.f90 | 14 ++++++++++++++ libgomp/libgomp.texi | 2 +- 9 files changed, 128 insertions(+), 11 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 1704a52be12..97e3b23b5d2 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -21072,6 +21072,14 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser, case GOMP_MAP_ALLOC: map_seen = 3; break; + case GOMP_MAP_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO); + map_seen = 3; + break; + case GOMP_MAP_ALWAYS_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO); + map_seen = 3; + break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_ALWAYS_POINTER: case GOMP_MAP_ATTACH_DETACH: @@ -21080,7 +21088,7 @@ c_parser_omp_target_enter_data (location_t loc, c_parser *parser, map_seen |= 1; error_at (OMP_CLAUSE_LOCATION (*pc), "%<#pragma omp target enter data%> with map-type other " - "than % or % on % clause"); + "than %, % or % on % clause"); *pc = OMP_CLAUSE_CHAIN (*pc); continue; } @@ -21159,6 +21167,14 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser, case GOMP_MAP_DELETE: map_seen = 3; break; + case GOMP_MAP_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM); + map_seen = 3; + break; + case GOMP_MAP_ALWAYS_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM); + map_seen = 3; + break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_ALWAYS_POINTER: case GOMP_MAP_ATTACH_DETACH: @@ -21167,8 +21183,8 @@ c_parser_omp_target_exit_data (location_t loc, c_parser *parser, map_seen |= 1; error_at (OMP_CLAUSE_LOCATION (*pc), "%<#pragma omp target exit data%> with map-type other " - "than %, % or % on %" - " clause"); + "than %, %, % or % " + "on % clause"); *pc = OMP_CLAUSE_CHAIN (*pc); continue; } diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index da2f370cdca..e8376253a60 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -44405,6 +44405,14 @@ cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok, case GOMP_MAP_ALLOC: map_seen = 3; break; + case GOMP_MAP_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO); + map_seen = 3; + break; + case GOMP_MAP_ALWAYS_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO); + map_seen = 3; + break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_FIRSTPRIVATE_REFERENCE: case GOMP_MAP_ALWAYS_POINTER: @@ -44414,7 +44422,7 @@ cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok, map_seen |= 1; error_at (OMP_CLAUSE_LOCATION (*pc), "%<#pragma omp target enter data%> with map-type other " - "than % or % on % clause"); + "than %, % or % on % clause"); *pc = OMP_CLAUSE_CHAIN (*pc); continue; } @@ -44497,6 +44505,14 @@ cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok, case GOMP_MAP_DELETE: map_seen = 3; break; + case GOMP_MAP_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM); + map_seen = 3; + break; + case GOMP_MAP_ALWAYS_TOFROM: + OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM); + map_seen = 3; + break; case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_FIRSTPRIVATE_REFERENCE: case GOMP_MAP_ALWAYS_POINTER: @@ -44506,8 +44522,8 @@ cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok, map_seen |= 1; error_at (OMP_CLAUSE_LOCATION (*pc), "%<#pragma omp target exit data%> with map-type other " - "than %, % or % on %" - " clause"); + "than %, %, % or % " + "on % clause"); *pc = OMP_CLAUSE_CHAIN (*pc); continue; } diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index e3affb8bc48..8d7e926b901 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1414,6 +1414,11 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) case OMP_MAP_TO: fputs ("to:", dumpfile); break; case OMP_MAP_FROM: fputs ("from:", dumpfile); break; case OMP_MAP_TOFROM: fputs ("tofrom:", dumpfile); break; + case OMP_MAP_ALWAYS_TO: fputs ("always,to:", dumpfile); break; + case OMP_MAP_ALWAYS_FROM: fputs ("always,from:", dumpfile); break; + case OMP_MAP_ALWAYS_TOFROM: fputs ("always,tofrom:", dumpfile); break; + case OMP_MAP_DELETE: fputs ("always,tofrom:", dumpfile); break; + case OMP_MAP_RELEASE: fputs ("always,tofrom:", dumpfile); break; default: break; } else if (list_type == OMP_LIST_LINEAR) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index aeb8a43e12e..93e40f25f82 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -7153,10 +7153,16 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, case OMP_MAP_ALWAYS_TO: case OMP_MAP_ALLOC: break; + case OMP_MAP_TOFROM: + n->u.map_op = OMP_MAP_TO; + break; + case OMP_MAP_ALWAYS_TOFROM: + n->u.map_op = OMP_MAP_ALWAYS_TO; + break; default: gfc_error ("TARGET ENTER DATA with map-type other " - "than TO, or ALLOC on MAP clause at %L", - &n->where); + "than TO, TOFROM or ALLOC on MAP clause " + "at %L", &n->where); break; } break; @@ -7168,10 +7174,16 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, case OMP_MAP_RELEASE: case OMP_MAP_DELETE: break; + case OMP_MAP_TOFROM: + n->u.map_op = OMP_MAP_FROM; + break; + case OMP_MAP_ALWAYS_TOFROM: + n->u.map_op = OMP_MAP_ALWAYS_FROM; + break; default: gfc_error ("TARGET EXIT DATA with map-type other " - "than FROM, RELEASE, or DELETE on MAP " - "clause at %L", &n->where); + "than FROM, TOFROM, RELEASE, or DELETE on " + "MAP clause at %L", &n->where); break; } break; diff --git a/gcc/testsuite/c-c++-common/gomp/target-data-2.c b/gcc/testsuite/c-c++-common/gomp/target-data-2.c new file mode 100644 index 00000000000..e3248705b59 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-data-2.c @@ -0,0 +1,20 @@ +/* { dg-additional-options "-fdump-tree-original" } */ + +/* In OpenMP 5.2 permits tofrom for enter/exit data + in the FE, it is already converted to 'to' and 'from', respectively. */ +int x, y, z; + +void +copyin () +{ + #pragma omp target enter data map(x) map(tofrom: y) map(always, tofrom: z) +} + +void +copyout () +{ + #pragma omp target exit data map(x) map(tofrom: y) map(always, tofrom: z) +} + +/* { dg-final { scan-tree-dump-times "#pragma omp target enter data map\\(always,to:z\\) map\\(to:y\\) map\\(to:x\\)" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp target exit data map\\(always,from:z\\) map\\(from:y\\) map\\(from:x\\)" 1 "original" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/target-data-3.c b/gcc/testsuite/c-c++-common/gomp/target-data-3.c new file mode 100644 index 00000000000..8c6d5cb8869 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-data-3.c @@ -0,0 +1,17 @@ +/* In OpenMP 5.2 permits tofrom for enter/exit data + in the FE, it is already converted to 'to' and 'from', respectively. */ +int y, z; + +void +copyin () +{ + #pragma omp target enter data map(from: y) /* { dg-error "'#pragma omp target enter data' with map-type other than 'to', 'tofrom' or 'alloc' on 'map' clause" } */ + #pragma omp target enter data map(always, from: z) /* { dg-error "'#pragma omp target enter data' with map-type other than 'to', 'tofrom' or 'alloc' on 'map' clause" } */ +} + +void +copyout () +{ + #pragma omp target exit data map(to: y) /* { dg-error "'#pragma omp target exit data' with map-type other than 'from', 'tofrom', 'release' or 'delete' on 'map' clause" } */ + #pragma omp target exit data map(always, to: z) /* { dg-error "'#pragma omp target exit data' with map-type other than 'from', 'tofrom', 'release' or 'delete' on 'map' clause" } */ +} diff --git a/gcc/testsuite/gfortran.dg/gomp/target-data-1.f90 b/gcc/testsuite/gfortran.dg/gomp/target-data-1.f90 new file mode 100644 index 00000000000..0f086f5d71c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/target-data-1.f90 @@ -0,0 +1,17 @@ +! { dg-additional-options "-fdump-tree-original" } +! +! In OpenMP 5.2 permits tofrom for enter/exit data +! in the FE, it is already converted to 'to' and 'from', respectively. +module m + integer :: x, y, z +contains +subroutine copyin + !$omp target enter data map(x) map(tofrom: y) map(always, tofrom: z) +end +subroutine copyout + !$omp target exit data map(x) map(tofrom: y) map(always, tofrom: z) +end +end + +! { dg-final { scan-tree-dump-times "#pragma omp target enter data map\\(to:x\\) map\\(to:y\\) map\\(always,to:z\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp target exit data map\\(from:x\\) map\\(from:y\\) map\\(always,from:z\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/target-data-2.f90 b/gcc/testsuite/gfortran.dg/gomp/target-data-2.f90 new file mode 100644 index 00000000000..71ee1eb9b95 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/target-data-2.f90 @@ -0,0 +1,14 @@ +! In OpenMP 5.2 permits tofrom for enter/exit data +! in the FE, it is already converted to 'to' and 'from', respectively. +module m + integer :: y, z +contains +subroutine copyin + !$omp target enter data map(from: y) ! { dg-error "TARGET ENTER DATA with map-type other than TO, TOFROM or ALLOC on MAP clause" } + !$omp target enter data map(always, from: z) ! { dg-error "TARGET ENTER DATA with map-type other than TO, TOFROM or ALLOC on MAP clause" } +end +subroutine copyout + !$omp target exit data map(to: y) ! { dg-error "TARGET EXIT DATA with map-type other than FROM, TOFROM, RELEASE, or DELETE on MAP clause" } + !$omp target exit data map(always, to: z) ! { dg-error "TARGET EXIT DATA with map-type other than FROM, TOFROM, RELEASE, or DELETE on MAP clause" } +end +end diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 2c4622c1092..a75cd244a83 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -390,7 +390,7 @@ The OpenMP 4.5 specification is fully supported. @tab Y @tab @item @code{ompt_callback_work} @tab N @tab @item Default map-type for @code{map} clause in @code{target enter/exit data} - @tab N @tab + @tab Y @tab @item New @code{doacross} clause as alias for @code{depend} with @code{source}/@code{sink} modifier @tab N @tab @item Deprecation of @code{depend} with @code{source}/@code{sink} modifier