re PR fortran/69128 (OpenMP workshare problem with SUM())
authorJakub Jelinek <jakub@redhat.com>
Fri, 8 Jan 2016 06:45:18 +0000 (07:45 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 8 Jan 2016 06:45:18 +0000 (07:45 +0100)
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

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/fortran/trans-expr.c
gcc/fortran/trans-openmp.c
gcc/fortran/trans-stmt.c
gcc/fortran/trans.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/gomp/pr69128.f90 [new file with mode: 0644]

index e6ebe43..485a4ae 100644 (file)
@@ -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.
index e8cc9d7..1c3768e 100644 (file)
@@ -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)
     {
index 9c824b6..1a6b734 100644 (file)
@@ -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);
 
index 27706d2..5990202 100644 (file)
@@ -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)
        {
index ac0c148..70a61cc 100644 (file)
@@ -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);
index efca096..3026e3b 100644 (file)
@@ -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 */
index aaee559..b7f25eb 100644 (file)
@@ -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 (file)
index 0000000..248c404
--- /dev/null
@@ -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