OpenMP: Support 'lastprivate (conditional:' in Fortran

gcc/fortran/ChangeLog:

	* gfortran.h (gfc_omp_namelist): Add lastprivate_conditional.
	* openmp.c (gfc_match_omp_clauses): Handle 'conditional:'
	modifier of 'lastprivate'.
	* trans-openmp.c (gfc_omp_clause_default_ctor): Don't assert
	on OMP_CLAUSE__CONDTEMP_ and other OMP_*TEMP_.
	(gfc_trans_omp_variable_list): Handle lastprivate_conditional.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/lastprivate-conditional-1.f90: New test.
	* gfortran.dg/gomp/lastprivate-conditional-2.f90: New test.
	* gfortran.dg/gomp/lastprivate-conditional-3.f90: New test.
	* gfortran.dg/gomp/lastprivate-conditional-4.f90: New test.
	* gfortran.dg/gomp/lastprivate-conditional-5.f90: New test.
This commit is contained in:
Tobias Burnus 2020-07-23 17:36:41 +02:00
parent ad1bea3a4b
commit 084dc63a02
8 changed files with 304 additions and 8 deletions

View File

@ -1242,6 +1242,7 @@ typedef struct gfc_omp_namelist
gfc_omp_map_op map_op; gfc_omp_map_op map_op;
gfc_omp_linear_op linear_op; gfc_omp_linear_op linear_op;
struct gfc_common_head *common; struct gfc_common_head *common;
bool lastprivate_conditional;
} u; } u;
struct gfc_omp_namelist_udr *udr; struct gfc_omp_namelist_udr *udr;
struct gfc_omp_namelist *next; struct gfc_omp_namelist *next;

View File

@ -1355,10 +1355,22 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
break; break;
case 'l': case 'l':
if ((mask & OMP_CLAUSE_LASTPRIVATE) if ((mask & OMP_CLAUSE_LASTPRIVATE)
&& gfc_match_omp_variable_list ("lastprivate (", && gfc_match ("lastprivate ( ") == MATCH_YES)
&c->lists[OMP_LIST_LASTPRIVATE], {
true) == MATCH_YES) bool conditional = gfc_match ("conditional : ") == MATCH_YES;
continue; head = NULL;
if (gfc_match_omp_variable_list ("",
&c->lists[OMP_LIST_LASTPRIVATE],
false, NULL, &head) == MATCH_YES)
{
gfc_omp_namelist *n;
for (n = *head; n; n = n->next)
n->u.lastprivate_conditional = conditional;
continue;
}
gfc_current_locus = old_loc;
break;
}
end_colon = false; end_colon = false;
head = NULL; head = NULL;
if ((mask & OMP_CLAUSE_LINEAR) if ((mask & OMP_CLAUSE_LINEAR)

View File

@ -613,10 +613,21 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
tree type = TREE_TYPE (decl), size, ptr, cond, then_b, else_b; tree type = TREE_TYPE (decl), size, ptr, cond, then_b, else_b;
stmtblock_t block, cond_block; stmtblock_t block, cond_block;
gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_PRIVATE switch (OMP_CLAUSE_CODE (clause))
|| OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LASTPRIVATE {
|| OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR case OMP_CLAUSE__LOOPTEMP_:
|| OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION); case OMP_CLAUSE__REDUCTEMP_:
case OMP_CLAUSE__CONDTEMP_:
case OMP_CLAUSE__SCANTEMP_:
return NULL;
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_LASTPRIVATE:
case OMP_CLAUSE_LINEAR:
case OMP_CLAUSE_REDUCTION:
break;
default:
gcc_unreachable ();
}
if ((! GFC_DESCRIPTOR_TYPE_P (type) if ((! GFC_DESCRIPTOR_TYPE_P (type)
|| GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE) || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
@ -1678,6 +1689,10 @@ gfc_trans_omp_variable_list (enum omp_clause_code code,
tree node = build_omp_clause (input_location, code); tree node = build_omp_clause (input_location, code);
OMP_CLAUSE_DECL (node) = t; OMP_CLAUSE_DECL (node) = t;
list = gfc_trans_add_clause (node, list); list = gfc_trans_add_clause (node, list);
if (code == OMP_CLAUSE_LASTPRIVATE
&& namelist->u.lastprivate_conditional)
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (node) = 1;
} }
} }
return list; return list;

View File

@ -0,0 +1,82 @@
subroutine foo (p)
implicit none
logical :: p(:)
integer a, b, c, d, e, f, g, h;
integer :: i
a = -1; b = -1; c = -1; d = -1; e = -1; f = -1; g = -1; h = -1
!$omp teams
!$omp distribute lastprivate (conditional: a) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
do i = 1, 32
if (p(i)) &
a = i
end do
!$omp distribute simd lastprivate (conditional: b) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
do i = 1, 32
if (p(i)) &
b = i
end do
!$omp distribute parallel do lastprivate (conditional: c) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
do i = 1, 32
if (p(i)) &
c = i
end do
!$omp distribute parallel do simd lastprivate (conditional: d) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
do i = 1, 32
if (p(i)) &
d = i
end do
!$omp end teams
!$omp teams distribute parallel do lastprivate (conditional: e) ! { dg-error "conditional 'lastprivate' clause on 'distribute' construct" }
do i = 1, 32
if (p(i)) &
e = i
end do
!$omp parallel
!$omp master
!$omp taskloop lastprivate (conditional: f) ! { dg-error "conditional 'lastprivate' clause on 'taskloop' construct" }
do i = 1, 32
if (p(i)) &
f = i
end do
! !$omp master taskloop simd lastprivate (conditional: g) ! { dg!error "conditional 'lastprivate' clause on 'taskloop' construct" }
! do i = 1, 32
! if (p(i)) &
! g = i
! end do
!$omp end master
!$omp end parallel
! !$omp parallel master taskloop simd lastprivate (conditional: h) ! { dg!error "conditional 'lastprivate' clause on 'taskloop' construct" }
! do i = 1, 32
! if (p(i)) &
! h = i
! end do
! !$omp end parallel master taskloop simd
end subroutine
!struct S { int a, b; };
subroutine bar (p)
implicit none
logical :: p(:)
type s_t
integer :: a, b
end type s_t
type(s_t) s, t
integer i
s = s_t(-1, -1)
t = s_t( 1, 2)
!$omp parallel do lastprivate (conditional: s) ! { dg-error "non-scalar variable 's' in conditional 'lastprivate' clause" }
do i = 1, 32
if (p(i)) then
block
type(s_t) u
u = t
u%b = i
s = u
end block
end if
end do
end subroutine

View File

@ -0,0 +1,46 @@
! { dg-additional-options "-fdump-tree-original" }
subroutine foo (p)
logical :: p(:)
integer i
integer a, b, c, d, e, f, g, h
a = -1; b = -1; c = -1; d = -1; e = -1; f = -1; g = -1; h = -1
!$omp parallel
!$omp do lastprivate (conditional: a)
do i = 1, 32
if (p(i)) &
a = i
end do
!$omp end parallel
!$omp simd lastprivate (conditional: b)
do i = 1, 32
if (p(i)) &
b = i
end do
!$omp parallel
!$omp do simd lastprivate (conditional: c)
do i = 1, 32
if (p(i)) &
c = i
end do
!$omp end parallel
!$omp parallel do lastprivate (conditional: d)
do i = 1, 32
if (p(i)) &
d = i
end do
!$omp end parallel do
!$omp parallel do simd lastprivate (conditional: e)
do i = 1, 32
if (p(i)) &
e = i
end do
!$omp end parallel do simd
end subroutine
! { dg-final { scan-tree-dump-times "#pragma omp for lastprivate\\(conditional:a\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) lastprivate\\(conditional:b\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "#pragma omp for lastprivate\\(conditional:c\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) lastprivate\\(conditional:c\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "#pragma omp parallel lastprivate\\(conditional:d\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "#pragma omp parallel lastprivate\\(conditional:e\\)" 1 "original" } }
! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\) lastprivate\\(conditional:e\\)" 1 "original" } }

View File

@ -0,0 +1,65 @@
subroutine foo
integer i, j, k
!$omp parallel
!$omp do lastprivate (conditional: i) ! { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" }
do i = 1, 32
end do
!$omp do collapse (3) lastprivate (conditional: i) ! { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" }
do i = 1, 32
do j = 1, 32
do k = 1, 32
end do
end do
end do
!$omp do collapse (3) lastprivate (conditional: j) ! { dg-warning "conditional 'lastprivate' on loop iterator 'j' ignored" }
do i = 1, 32
do j = 1, 32
do k = 1, 32
end do
end do
end do
!$omp do collapse (3) lastprivate (conditional: k) ! { dg-warning "conditional 'lastprivate' on loop iterator 'k' ignored" }
do i = 1, 32
do j = 1, 32
do k = 1, 32
end do
end do
end do
!$omp end parallel
! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'i' ignored"
!$omp parallel do lastprivate (conditional: i)
do i = 1, 32
end do
!$omp end parallel do
! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'i' ignored"
!$omp parallel do collapse (3) lastprivate (conditional: i)
do i = 1, 32
do j = 1, 32
do k = 1, 32
end do
end do
end do
!$omp end parallel do
! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'j' ignored"
!$omp parallel do collapse (3) lastprivate (conditional: j)
do i = 1, 32
do j = 1, 32
do k = 1, 32
end do
end do
end do
!$omp end parallel do
! Error in eqiv. C code: "conditional 'lastprivate' on loop iterator 'k' ignored"
!$omp parallel do collapse (3) lastprivate (conditional: k)
do i = 1, 32
do j = 1, 32
do k = 1, 32
end do
end do
end do
!$omp end parallel do
end subroutine

View File

@ -0,0 +1,28 @@
module m
integer x, w
end module m
subroutine foo
use m
interface
logical function bar(i)
integer i
end function
end interface
integer y, i, z
logical tmp
y = 5
!$omp teams num_teams(1) firstprivate (x) shared (y) shared (w)
!$omp parallel do firstprivate (x, y, z, w) lastprivate (conditional: x, y, z, w)
do i = 1, 64
if (bar (i)) then
x = i;
y = i + 1;
z = i + 2;
w = i + 3;
end if
tmp = bar (y);
tmp = bar (z);
end do
!$omp end teams
end

View File

@ -0,0 +1,47 @@
! { dg-do compile }
! { dg-options "-O2 -fopenmp -fdump-tree-ompexp" }
! { dg-final { scan-tree-dump-times "GOMP_loop_start " 3 "ompexp" } }
! { dg-final { scan-tree-dump-times "GOMP_loop_end_nowait " 3 "ompexp" } }
module m
logical r
end module m
subroutine foo (a)
use m
implicit none
logical a(:)
integer :: i
!$omp do lastprivate(conditional: r)
do i = 1, 64
if (a(i)) &
r = a(i)
end do
!$omp end do nowait
end
subroutine bar (a)
use m
implicit none
logical a(:)
integer :: i
!$omp do lastprivate(conditional: r) schedule (static, 4)
do i = 1, 64
if (a(i)) &
r = a(i)
end do
!$omp end do nowait
end
subroutine baz (a)
use m
implicit none
logical a(:)
integer :: i
!$omp do lastprivate(conditional: r) schedule (runtime)
do i = 1, 64
if (a(i)) &
r = a(i)
end do
!$omp end do nowait
end