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:
parent
ad1bea3a4b
commit
084dc63a02
@ -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;
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
82
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-1.f90
Normal file
82
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-1.f90
Normal 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
|
||||||
46
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-2.f90
Normal file
46
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-2.f90
Normal 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" } }
|
||||||
65
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-3.f90
Normal file
65
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-3.f90
Normal 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
|
||||||
28
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-4.f90
Normal file
28
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-4.f90
Normal 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
|
||||||
47
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-5.f90
Normal file
47
gcc/testsuite/gfortran.dg/gomp/lastprivate-conditional-5.f90
Normal 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
|
||||||
Loading…
Reference in New Issue
Block a user