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.
This commit is contained in:
parent
ce1580252e
commit
e3803f9cbb
8 changed files with 82 additions and 36 deletions
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
};
|
||||
|
||||
|
|
|
@ -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,38 +4560,40 @@ 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))
|
||||
static const int to_enter_link_lists[]
|
||||
= { OMP_LIST_TO, OMP_LIST_ENTER, OMP_LIST_LINK };
|
||||
for (size_t listn = 0; listn < ARRAY_SIZE (to_enter_link_lists)
|
||||
&& (list = to_enter_link_lists[listn], true); ++listn)
|
||||
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 (size_t listn = 0; listn < ARRAY_SIZE (to_enter_link_lists)
|
||||
&& (list = to_enter_link_lists[listn], true); ++listn)
|
||||
for (n = c->lists[list]; n; n = n->next)
|
||||
if (n->sym)
|
||||
{
|
||||
if (n->sym->attr.in_common)
|
||||
gfc_error_now ("OMP DECLARE TARGET variable at %L is an "
|
||||
"element of a COMMON block", &n->where);
|
||||
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 LINK clause and later in TO clause",
|
||||
&n->where);
|
||||
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);
|
||||
else if (n->sym->mark)
|
||||
gfc_error_now ("Variable at %L mentioned multiple times in "
|
||||
"clauses of the same OMP DECLARE TARGET directive",
|
||||
&n->where);
|
||||
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 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 or ENTER clause and later in "
|
||||
"LINK clause", &n->where);
|
||||
else if (gfc_add_omp_declare_target (&n->sym->attr, n->sym->name,
|
||||
&n->sym->declared_at))
|
||||
{
|
||||
|
@ -4598,14 +4616,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 +4657,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 +6352,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)
|
||||
|
|
|
@ -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 "mentioned multiple times in clauses of the same OMP DECLARE TARGET directive" }
|
||||
!$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 "mentioned multiple times in clauses of the same OMP DECLARE TARGET directive" }
|
||||
!$omp declare target link(b) enter(b) ! { dg-error "mentioned multiple times in clauses of the same OMP DECLARE TARGET directive" }
|
||||
!$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
|
||||
|
||||
|
|
|
@ -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" } }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue