OpenMP/Fortran: Add support for enter clause on declare target Fortran version to C/C++ commit r13-797-g0ccba4ed8571c18c7015413441e971 gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_clauses): Handle OMP_LIST_ENTER. * gfortran.h: Add OMP_LIST_ENTER. * openmp.cc (enum omp_mask2, OMP_DECLARE_TARGET_CLAUSES): Add OMP_CLAUSE_ENTER. (gfc_match_omp_clauses, gfc_match_omp_declare_target, resolve_omp_clauses): Handle 'enter' clause. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark 'enter' clause as supported. * testsuite/libgomp.fortran/declare-target-1.f90: Extend to test explicit 'to' and 'enter' clause. * testsuite/libgomp.fortran/declare-target-2.f90: Update accordingly. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/declare-target-2.f90: Add 'enter' clause test. * gfortran.dg/gomp/declare-target-4.f90: Likewise. gcc/fortran/dump-parse-tree.cc | 1 + gcc/fortran/gfortran.h | 1 + gcc/fortran/openmp.cc | 59 +++++++++++++++------- .../gfortran.dg/gomp/declare-target-2.f90 | 18 +++++-- .../gfortran.dg/gomp/declare-target-4.f90 | 9 +++- libgomp/libgomp.texi | 2 +- .../testsuite/libgomp.fortran/declare-target-1.f90 | 4 +- .../testsuite/libgomp.fortran/declare-target-2.f90 | 10 +++- 8 files changed, 76 insertions(+), 28 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 4e8986bd599..e3affb8bc48 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1679,6 +1679,7 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) case OMP_LIST_IN_REDUCTION: type = "IN_REDUCTION"; break; case OMP_LIST_TASK_REDUCTION: type = "TASK_REDUCTION"; break; case OMP_LIST_DEVICE_RESIDENT: type = "DEVICE_RESIDENT"; break; + case OMP_LIST_ENTER: type = "ENTER"; break; case OMP_LIST_LINK: type = "LINK"; break; case OMP_LIST_USE_DEVICE: type = "USE_DEVICE"; break; case OMP_LIST_CACHE: type = "CACHE"; break; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 5d970bc1df0..0bac8657790 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1395,6 +1395,7 @@ enum OMP_LIST_NONTEMPORAL, OMP_LIST_ALLOCATE, OMP_LIST_HAS_DEVICE_ADDR, + OMP_LIST_ENTER, OMP_LIST_NUM /* Must be the last. */ }; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index efa62b64f2b..66c30ebea51 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -986,6 +986,7 @@ enum omp_mask2 OMP_CLAUSE_ATTACH, OMP_CLAUSE_NOHOST, OMP_CLAUSE_HAS_DEVICE_ADDR, /* OpenMP 5.1 */ + OMP_CLAUSE_ENTER, /* OpenMP 5.2 */ /* This must come last. */ OMP_MASK2_LAST }; @@ -2101,6 +2102,16 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, continue; } break; + case 'e': + if ((mask & OMP_CLAUSE_ENTER)) + { + m = gfc_match_omp_to_link ("enter (", &c->lists[OMP_LIST_ENTER]); + if (m == MATCH_ERROR) + goto error; + if (m == MATCH_YES) + continue; + } + break; case 'f': if ((mask & OMP_CLAUSE_FAIL) && (m = gfc_match_dupl_check (c->fail == OMP_MEMORDER_UNSET, @@ -2921,8 +2932,12 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, continue; if ((mask & OMP_CLAUSE_TO) && (mask & OMP_CLAUSE_LINK)) { - if (gfc_match_omp_to_link ("to (", &c->lists[OMP_LIST_TO]) - == MATCH_YES) + /* Declare target: 'to' is an alias for 'enter'; + 'to' is deprecated since 5.2. */ + m = gfc_match_omp_to_link ("to (", &c->lists[OMP_LIST_TO]); + if (m == MATCH_ERROR) + goto error; + if (m == MATCH_YES) continue; } else if ((mask & OMP_CLAUSE_TO) @@ -3724,7 +3739,8 @@ cleanup: #define OMP_ORDERED_CLAUSES \ (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD) #define OMP_DECLARE_TARGET_CLAUSES \ - (omp_mask (OMP_CLAUSE_TO) | OMP_CLAUSE_LINK | OMP_CLAUSE_DEVICE_TYPE) + (omp_mask (OMP_CLAUSE_ENTER) | OMP_CLAUSE_LINK | OMP_CLAUSE_DEVICE_TYPE \ + | OMP_CLAUSE_TO) #define OMP_ATOMIC_CLAUSES \ (omp_mask (OMP_CLAUSE_ATOMIC) | OMP_CLAUSE_CAPTURE | OMP_CLAUSE_HINT \ | OMP_CLAUSE_MEMORDER | OMP_CLAUSE_COMPARE | OMP_CLAUSE_FAIL \ @@ -4530,7 +4546,7 @@ gfc_match_omp_declare_target (void) { c = gfc_get_omp_clauses (); gfc_current_locus = old_loc; - m = gfc_match_omp_to_link (" (", &c->lists[OMP_LIST_TO]); + m = gfc_match_omp_to_link (" (", &c->lists[OMP_LIST_ENTER]); if (m != MATCH_YES) goto syntax; if (gfc_match_omp_eos () != MATCH_YES) @@ -4544,16 +4560,20 @@ gfc_match_omp_declare_target (void) gfc_buffer_error (false); - for (list = OMP_LIST_TO; list != OMP_LIST_NUM; - list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM)) + for (list = OMP_LIST_ENTER; list != OMP_LIST_NUM; + list = (list == OMP_LIST_ENTER + ? OMP_LIST_TO + : (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))) for (n = c->lists[list]; n; n = n->next) if (n->sym) n->sym->mark = 0; else if (n->u.common->head) n->u.common->head->mark = 0; - for (list = OMP_LIST_TO; list != OMP_LIST_NUM; - list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM)) + for (list = OMP_LIST_ENTER; list != OMP_LIST_NUM; + list = (list == OMP_LIST_ENTER + ? OMP_LIST_TO + : (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))) for (n = c->lists[list]; n; n = n->next) if (n->sym) { @@ -4564,14 +4584,14 @@ gfc_match_omp_declare_target (void) && n->sym->attr.omp_declare_target_link && list != OMP_LIST_LINK) gfc_error_now ("OMP DECLARE TARGET variable at %L previously " - "mentioned in LINK clause and later in TO clause", - &n->where); + "mentioned in LINK clause and later in %s clause", + &n->where, list == OMP_LIST_TO ? "TO" : "ENTER"); else if (n->sym->attr.omp_declare_target && !n->sym->attr.omp_declare_target_link && list == OMP_LIST_LINK) gfc_error_now ("OMP DECLARE TARGET variable at %L previously " - "mentioned in TO clause and later in LINK clause", - &n->where); + "mentioned in TO or ENTER clause and later in " + "LINK clause", &n->where); else if (n->sym->mark) gfc_error_now ("Variable at %L mentioned multiple times in " "clauses of the same OMP DECLARE TARGET directive", @@ -4598,14 +4618,14 @@ gfc_match_omp_declare_target (void) && n->u.common->omp_declare_target_link && list != OMP_LIST_LINK) gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously " - "mentioned in LINK clause and later in TO clause", - &n->where); + "mentioned in LINK clause and later in %s clause", + &n->where, list == OMP_LIST_TO ? "TO" : "ENTER"); else if (n->u.common->omp_declare_target && !n->u.common->omp_declare_target_link && list == OMP_LIST_LINK) gfc_error_now ("OMP DECLARE TARGET COMMON at %L previously " - "mentioned in TO clause and later in LINK clause", - &n->where); + "mentioned in TO or ENTER clause and later in " + "LINK clause", &n->where); else if (n->u.common->head && n->u.common->head->mark) gfc_error_now ("COMMON at %L mentioned multiple times in " "clauses of the same OMP DECLARE TARGET directive", @@ -4639,7 +4659,10 @@ gfc_match_omp_declare_target (void) s->attr.omp_device_type = c->device_type; } } - if (c->device_type && !c->lists[OMP_LIST_TO] && !c->lists[OMP_LIST_LINK]) + if (c->device_type + && !c->lists[OMP_LIST_ENTER] + && !c->lists[OMP_LIST_TO] + && !c->lists[OMP_LIST_LINK]) gfc_warning_now (0, "OMP DECLARE TARGET directive at %L with only " "DEVICE_TYPE clause is ignored", &old_loc); @@ -6331,7 +6354,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, "IN_REDUCTION", "TASK_REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE", "CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR", - "NONTEMPORAL", "ALLOCATE", "HAS_DEVICE_ADDR" }; + "NONTEMPORAL", "ALLOCATE", "HAS_DEVICE_ADDR", "ENTER" }; STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM); if (omp_clauses == NULL) diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-target-2.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-target-2.f90 index 2217eab07e5..7ac25c84483 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-target-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-target-2.f90 @@ -1,9 +1,9 @@ ! { dg-do compile } module declare_target_2 - !$omp declare target to (a) link (a) ! { dg-error "TO clause and later in LINK" } + !$omp declare target to (a) link (a) ! { dg-error "TO or ENTER clause and later in LINK" } !$omp declare target (b) - !$omp declare target link (b) ! { dg-error "TO clause and later in LINK" } + !$omp declare target link (b) ! { dg-error "TO or ENTER clause and later in LINK" } !$omp declare target link (f) !$omp declare target to (f) ! { dg-error "LINK clause and later in TO" } !$omp declare target(c, c) ! { dg-error "mentioned multiple times in clauses of the same" } @@ -39,9 +39,9 @@ subroutine foo ! { dg-error "attribute conflicts" } !$omp declare target to (/c2/) !$omp declare target (/c2/) !$omp declare target to(/c2/) - !$omp declare target link(/c2/) ! { dg-error "TO clause and later in LINK" } + !$omp declare target link(/c2/) ! { dg-error "TO or ENTER clause and later in LINK" } !$omp declare target link(/c3/) - !$omp declare target (/c3/) ! { dg-error "LINK clause and later in TO" } + !$omp declare target (/c3/) ! { dg-error "LINK clause and later in ENTER" } !$omp declare target (/c4/, /c4/) ! { dg-error "mentioned multiple times in clauses of the same" } !$omp declare target to (/c4/) to(/c4/) ! { dg-error "mentioned multiple times in clauses of the same" } !$omp declare target link (/c5/) @@ -49,3 +49,13 @@ subroutine foo ! { dg-error "attribute conflicts" } !$omp declare target link(/c5/)link(/c5/) ! { dg-error "mentioned multiple times in clauses of the same" } !$omp declare target link(/c5/,/c5/) ! { dg-error "mentioned multiple times in clauses of the same" } end subroutine + +module declare_target_3 + !$omp declare target enter (a) link (a) ! { dg-error "TO or ENTER clause and later in LINK" } + !$omp declare target link(b) enter(b) ! { dg-error "TO or ENTER clause and later in LINK" } + !$omp declare target to (c) enter (c) ! { dg-error "mentioned multiple times in clauses of the same" } + !$omp declare target enter (d) to (d) ! { dg-error "mentioned multiple times in clauses of the same" } + !$omp declare target enter (e) enter (e) ! { dg-error "mentioned multiple times in clauses of the same" } + integer, save :: a, b, c, d, e +end + diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90 index 8947b887534..4f5de4bd8c7 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-target-4.f90 @@ -21,6 +21,10 @@ subroutine f5 !$omp declare target device_type (nohost) to (f5) end subroutine +subroutine f6 + !$omp declare target enter (f6) device_type (any) +end subroutine + module mymod ! device_type is ignored for variables in OpenMP 5.0 ! but TR8 and later apply those rules to variables as well @@ -69,13 +73,14 @@ module m2 public :: m, n, o, p, q, r, s, t, u, v, w, x end module m2 -! { dg-final { scan-tree-dump-times "omp declare target" 7 "original" } } -! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(" 7 "original" } } +! { dg-final { scan-tree-dump-times "omp declare target" 8 "original" } } +! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(" 8 "original" } } ! { dg-final { scan-tree-dump-not "__attribute__\\(\\(omp declare target \[^\n\r\]*\[\n\r\]void f1" "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r]void f2" 1 "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void f3" 1 "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(host\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void f4" 1 "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(nohost\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void f5" 1 "original" } } +! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r]void f6" 1 "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(any\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void s1" 1 "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(nohost\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void s2" 1 "original" } } ! { dg-final { scan-tree-dump-times "__attribute__\\(\\(omp declare target \\(device_type\\(host\\)\\)\\)\\)\[\n\r]__attribute__\[^\n\r]+\[\n\r\]void s3" 1 "original" } } diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 56aab4494ad..ff02ccd4969 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -368,7 +368,7 @@ The OpenMP 4.5 specification is fully supported. @item If a matching mapped list item is not found in the data environment, the pointer retains its original value @tab N @tab @item New @code{enter} clause as alias for @code{to} on declare target directive - @tab N @tab + @tab Y @tab @item Deprecation of @code{to} clause on declare target directive @tab N @tab @item Extended list of directives permitted in Fortran pure procedures @tab N @tab diff --git a/libgomp/testsuite/libgomp.fortran/declare-target-1.f90 b/libgomp/testsuite/libgomp.fortran/declare-target-1.f90 index fd9c26fde95..d9abf685a54 100644 --- a/libgomp/testsuite/libgomp.fortran/declare-target-1.f90 +++ b/libgomp/testsuite/libgomp.fortran/declare-target-1.f90 @@ -2,8 +2,10 @@ ! { dg-additional-sources declare-target-2.f90 } module declare_target_1_mod - integer :: var_x + integer :: var_x, var_y, var_z !$omp declare target(var_x) + !$omp declare target to(var_y) + !$omp declare target enter(var_z) end module declare_target_1_mod interface diff --git a/libgomp/testsuite/libgomp.fortran/declare-target-2.f90 b/libgomp/testsuite/libgomp.fortran/declare-target-2.f90 index 85fc68c6ede..2210fc5a52f 100644 --- a/libgomp/testsuite/libgomp.fortran/declare-target-2.f90 +++ b/libgomp/testsuite/libgomp.fortran/declare-target-2.f90 @@ -7,12 +7,18 @@ subroutine foo use declare_target_1_mod var_x = 10 - !$omp target update to(var_x) + var_y = 20 + var_z = 30 + !$omp target update to(var_x, var_y, var_z) !$omp target var_x = var_x * 2; + var_y = var_y * 3; + var_z = var_z * 4; !$omp end target - !$omp target update from(var_x) + !$omp target update from(var_x, var_y, var_z) if (var_x /= 20) stop 1 + if (var_y /= 20*3) stop 2 + if (var_z /= 30*4) stop 3 end subroutine foo