mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 03:47:02 -05:00
Commit r12-2891-gd0befed793b94f3f407be44e6f69f81a02f5f073 added C/C++ support for the masked construct. This patch extends it to Fortran. gcc/fortran/ChangeLog: * dump-parse-tree.c (show_omp_clauses): Handle 'filter' clause. (show_omp_node, show_code_node): Handle (combined) omp masked construct. * frontend-passes.c (gfc_code_walker): Likewise. * gfortran.h (enum gfc_statement): Add ST_OMP_*_MASKED*. (enum gfc_exec_op): Add EXEC_OMP_*_MASKED*. * match.h (gfc_match_omp_masked, gfc_match_omp_masked_taskloop, gfc_match_omp_masked_taskloop_simd, gfc_match_omp_parallel_masked, gfc_match_omp_parallel_masked_taskloop, gfc_match_omp_parallel_masked_taskloop_simd): New prototypes. * openmp.c (enum omp_mask1): Add OMP_CLAUSE_FILTER. (gfc_match_omp_clauses): Match it. (OMP_MASKED_CLAUSES, gfc_match_omp_parallel_masked, gfc_match_omp_parallel_masked_taskloop, gfc_match_omp_parallel_masked_taskloop_simd, gfc_match_omp_masked, gfc_match_omp_masked_taskloop, gfc_match_omp_masked_taskloop_simd): New. (resolve_omp_clauses): Resolve filter clause. (gfc_resolve_omp_parallel_blocks, resolve_omp_do, omp_code_to_statement, gfc_resolve_omp_directive): Handle omp masked constructs. * parse.c (decode_omp_directive, case_exec_markers, gfc_ascii_statement, parse_omp_do, parse_omp_structured_block, parse_executable): Likewise. * resolve.c (gfc_resolve_blocks, gfc_resolve_code): Likewise. * st.c (gfc_free_statement): Likewise. * trans-openmp.c (gfc_trans_omp_clauses): Handle filter clause. (GFC_OMP_SPLIT_MASKED, GFC_OMP_MASK_MASKED): New enum values. (gfc_trans_omp_masked): New. (gfc_split_omp_clauses): Handle combined masked directives. (gfc_trans_omp_master_taskloop): Rename to ... (gfc_trans_omp_master_masked_taskloop): ... this; handle also combined masked directives. (gfc_trans_omp_parallel_master): Rename to ... (gfc_trans_omp_parallel_master_masked): ... this; handle combined masked directives. (gfc_trans_omp_directive): Handle EXEC_OMP_*_MASKED*. * trans.c (trans_code): Likewise. libgomp/ChangeLog: * testsuite/libgomp.fortran/masked-1.f90: New test. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/masked-1.f90: New test. * gfortran.dg/gomp/masked-2.f90: New test. * gfortran.dg/gomp/masked-3.f90: New test. * gfortran.dg/gomp/masked-combined-1.f90: New test. * gfortran.dg/gomp/masked-combined-2.f90: New test.
120 lines
2.5 KiB
Fortran
120 lines
2.5 KiB
Fortran
module m
|
|
use omp_lib
|
|
implicit none (type, external)
|
|
contains
|
|
subroutine foo (x, a)
|
|
integer, value :: x
|
|
integer, contiguous :: a(0:)
|
|
integer :: i
|
|
|
|
!$omp masked
|
|
if (omp_get_thread_num () /= 0) &
|
|
stop 1
|
|
a(128) = a(128) + 1
|
|
!$omp end masked
|
|
|
|
!$omp masked filter (0)
|
|
if (omp_get_thread_num () /= 0) &
|
|
stop 2
|
|
a(129) = a(129) + 1
|
|
!$omp end masked
|
|
|
|
!$omp masked filter (7)
|
|
if (omp_get_thread_num () /= 7) &
|
|
stop 3
|
|
a(130) = a(130) + 1
|
|
!$omp end masked
|
|
|
|
!$omp masked filter (x)
|
|
if (omp_get_thread_num () /= x) &
|
|
stop 4
|
|
a(131) = a(131) + 1
|
|
!$omp end masked
|
|
|
|
!$omp masked taskloop simd filter (x) shared(a) grainsize (12) simdlen (4)
|
|
do i = 0, 127
|
|
a(i) = a(i) + i
|
|
end do
|
|
!$omp end masked taskloop simd
|
|
end
|
|
end
|
|
|
|
program main
|
|
use m
|
|
implicit none (type, external)
|
|
integer :: i
|
|
integer :: a(0:135)
|
|
|
|
a = 0
|
|
|
|
!$omp parallel num_threads (4)
|
|
call foo (4, a)
|
|
!$omp end parallel
|
|
do i = 0, 127
|
|
if (a(i) /= 0) &
|
|
stop 5
|
|
end do
|
|
if (a(128) /= 1 .or. a(129) /= 1 .or. a(130) /= 0 .or. a(131) /= 0) &
|
|
stop 6
|
|
|
|
!$omp parallel num_threads (4)
|
|
call foo (3, a)
|
|
!$omp end parallel
|
|
do i = 0, 127
|
|
if (a(i) /= i) &
|
|
stop 7
|
|
end do
|
|
if (a(128) /= 2 .or. a(129) /= 2 .or. a(130) /= 0 .or. a(131) /= 1) &
|
|
stop 8
|
|
|
|
!$omp parallel num_threads (8)
|
|
call foo (8, a)
|
|
!$omp end parallel
|
|
do i = 0, 127
|
|
if (a(i) /= i) &
|
|
stop 9
|
|
end do
|
|
if (a(128) /= 3 .or. a(129) /= 3 .or. a(130) /= 1 .or. a(131) /= 1) &
|
|
stop 10
|
|
|
|
!$omp parallel num_threads (8)
|
|
call foo (6, a)
|
|
!$omp end parallel
|
|
do i = 0, 127
|
|
if (a(i) /= 2 * i) &
|
|
stop 11
|
|
end do
|
|
if (a(128) /= 4 .or. a(129) /= 4 .or. a(130) /= 2 .or. a(131) /= 2) &
|
|
stop 12
|
|
|
|
do i = 0, 7
|
|
a(i) = 0
|
|
end do
|
|
! The filter expression can evaluate to different values in different threads.
|
|
!$omp parallel masked num_threads (8) filter (omp_get_thread_num () + 1)
|
|
a(omp_get_thread_num ()) = a(omp_get_thread_num ()) + 1
|
|
!$omp end parallel masked
|
|
do i = 0, 7
|
|
if (a(i) /= 0) &
|
|
stop 13
|
|
end do
|
|
|
|
! And multiple threads can be filtered.
|
|
!$omp parallel masked num_threads (8) filter (iand (omp_get_thread_num (), not(1)))
|
|
a(omp_get_thread_num ()) = a(omp_get_thread_num ()) + 1
|
|
!$omp end parallel masked
|
|
do i = 0, 7
|
|
block
|
|
integer :: j
|
|
j = iand (i, 1)
|
|
if (j /= 0) then
|
|
j = 0
|
|
else
|
|
j = 1
|
|
end if
|
|
if (a(i) /= j) &
|
|
stop 14
|
|
end block
|
|
end do
|
|
end program main
|