diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-01-08 07:45:18 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-01-08 07:45:18 +0100 |
commit | 57bf30726cf3695077cde97bd3fd396cb1262eeb (patch) | |
tree | e9a3324b824366e319e9512c7ab45e0a701976ad | |
parent | 53290e072ae4d8e5d61f82d651b6fba309fed6f1 (diff) | |
download | gcc-57bf30726cf3695077cde97bd3fd396cb1262eeb.zip gcc-57bf30726cf3695077cde97bd3fd396cb1262eeb.tar.gz gcc-57bf30726cf3695077cde97bd3fd396cb1262eeb.tar.bz2 |
re PR fortran/69128 (OpenMP workshare problem with SUM())
PR fortran/69128
* trans.h (OMPWS_SCALARIZER_BODY): Define.
(OMPWS_NOWAIT): Renumber.
* trans-stmt.c (gfc_trans_where_3): Only set OMPWS_SCALARIZER_WS
if OMPWS_SCALARIZER_BODY is not set already, and set also
OMPWS_SCALARIZER_BODY until the final loop creation.
* trans-expr.c (gfc_trans_assignment_1): Likewise.
* trans-openmp.c (gfc_trans_omp_workshare): Also clear
OMPWS_SCALARIZER_BODY.
* trans-array.c (gfc_trans_scalarized_loop_end): Don't create
OMP_FOR if OMPWS_SCALARIZER_BODY is set.
* gfortran.dg/gomp/pr69128.f90: New test.
From-SVN: r232151
-rw-r--r-- | gcc/fortran/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 3 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 13 | ||||
-rw-r--r-- | gcc/fortran/trans-openmp.c | 2 | ||||
-rw-r--r-- | gcc/fortran/trans-stmt.c | 11 | ||||
-rw-r--r-- | gcc/fortran/trans.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/gomp/pr69128.f90 | 23 |
8 files changed, 66 insertions, 7 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e6ebe43..485a4ae 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,17 @@ +2016-01-08 Jakub Jelinek <jakub@redhat.com> + + PR fortran/69128 + * trans.h (OMPWS_SCALARIZER_BODY): Define. + (OMPWS_NOWAIT): Renumber. + * trans-stmt.c (gfc_trans_where_3): Only set OMPWS_SCALARIZER_WS + if OMPWS_SCALARIZER_BODY is not set already, and set also + OMPWS_SCALARIZER_BODY until the final loop creation. + * trans-expr.c (gfc_trans_assignment_1): Likewise. + * trans-openmp.c (gfc_trans_omp_workshare): Also clear + OMPWS_SCALARIZER_BODY. + * trans-array.c (gfc_trans_scalarized_loop_end): Don't create + OMP_FOR if OMPWS_SCALARIZER_BODY is set. + 2016-01-04 Jakub Jelinek <jakub@redhat.com> Update copyright years. diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index e8cc9d7..1c3768e 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3601,7 +3601,8 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n, tree init; tree incr; - if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)) + if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS + | OMPWS_SCALARIZER_BODY)) == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS) && n == loop->dimen - 1) { diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 9c824b6..1a6b7344 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -9160,6 +9160,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, bool scalar_to_array; tree string_length; int n; + bool maybe_workshare = false; /* Assignment of the form lhs = rhs. */ gfc_start_block (&block); @@ -9234,8 +9235,13 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, } /* Allow the scalarizer to workshare array assignments. */ - if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL) - ompws_flags |= OMPWS_SCALARIZER_WS; + if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY)) + == OMPWS_WORKSHARE_FLAG + && loop.temp_ss == NULL) + { + maybe_workshare = true; + ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY; + } /* Start the scalarized loop body. */ gfc_start_scalarized_body (&loop, &body); @@ -9384,6 +9390,9 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag, gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp); } + if (maybe_workshare) + ompws_flags &= ~OMPWS_SCALARIZER_BODY; + /* Generate the copying loops. */ gfc_trans_scalarizing_loops (&loop, &body); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 27706d2..5990202 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -4297,7 +4297,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses) /* By default, every gfc_code is a single unit of work. */ ompws_flags |= OMPWS_CURR_SINGLEUNIT; - ompws_flags &= ~OMPWS_SCALARIZER_WS; + ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY); switch (code->op) { diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index ac0c148..70a61cc 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -5057,10 +5057,15 @@ gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock) gfc_loopinfo loop; gfc_ss *edss = 0; gfc_ss *esss = 0; + bool maybe_workshare = false; /* Allow the scalarizer to workshare simple where loops. */ - if (ompws_flags & OMPWS_WORKSHARE_FLAG) - ompws_flags |= OMPWS_SCALARIZER_WS; + if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY)) + == OMPWS_WORKSHARE_FLAG) + { + maybe_workshare = true; + ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY; + } cond = cblock->expr1; tdst = cblock->next->expr1; @@ -5160,6 +5165,8 @@ gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock) gfc_add_expr_to_block (&body, tmp); gfc_add_block_to_block (&body, &cse.post); + if (maybe_workshare) + ompws_flags &= ~OMPWS_SCALARIZER_BODY; gfc_trans_scalarizing_loops (&loop, &body); gfc_add_block_to_block (&block, &loop.pre); gfc_add_block_to_block (&block, &loop.post); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index efca096..3026e3b 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -1039,7 +1039,9 @@ extern const char gfc_msg_wrong_return[]; construct is not workshared. */ #define OMPWS_SCALARIZER_WS 4 /* Set if scalarizer should attempt to create parallel loops. */ -#define OMPWS_NOWAIT 8 /* Use NOWAIT on OMP_FOR. */ +#define OMPWS_SCALARIZER_BODY 8 /* Set if handling body of potential + parallel loop. */ +#define OMPWS_NOWAIT 16 /* Use NOWAIT on OMP_FOR. */ extern int ompws_flags; #endif /* GFC_TRANS_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aaee559..b7f25eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-01-08 Jakub Jelinek <jakub@redhat.com> + PR fortran/69128 + * gfortran.dg/gomp/pr69128.f90: New test. + PR c++/69145 * g++.dg/ext/pr69145-1.C: New test. * g++.dg/ext/pr69145-2-very-long-filename.cc: New file. diff --git a/gcc/testsuite/gfortran.dg/gomp/pr69128.f90 b/gcc/testsuite/gfortran.dg/gomp/pr69128.f90 new file mode 100644 index 0000000..248c404 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr69128.f90 @@ -0,0 +1,23 @@ +! PR fortran/69128 +! { dg-do compile } + +program test + implicit none + interface + subroutine use(b, c) + real, allocatable :: b(:), c(:) + end subroutine + end interface + real, allocatable :: a(:,:), b(:), c(:) + integer :: dim1, dim2, i,j + dim1=10000 + dim2=500 + allocate(a(dim1,dim2),b(dim1),c(dim1)) + call random_number(a) + +!$omp parallel workshare + b(:) = maxval(a(:,:), dim=2) + c(:) = sum(a(:,:), dim=2) +!$omp end parallel workshare + call use(b, c) +end program |