aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-01-08 07:45:18 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-01-08 07:45:18 +0100
commit57bf30726cf3695077cde97bd3fd396cb1262eeb (patch)
treee9a3324b824366e319e9512c7ab45e0a701976ad
parent53290e072ae4d8e5d61f82d651b6fba309fed6f1 (diff)
downloadgcc-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/ChangeLog14
-rw-r--r--gcc/fortran/trans-array.c3
-rw-r--r--gcc/fortran/trans-expr.c13
-rw-r--r--gcc/fortran/trans-openmp.c2
-rw-r--r--gcc/fortran/trans-stmt.c11
-rw-r--r--gcc/fortran/trans.h4
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr69128.f9023
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