gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional on sections...
authorJakub Jelinek <jakub@redhat.com>
Mon, 27 May 2019 21:33:37 +0000 (23:33 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 27 May 2019 21:33:37 +0000 (23:33 +0200)
* gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional
on sections construct.
* omp-low.c (lower_lastprivate_conditional_clauses): Handle sections
construct.
(lower_omp_sections): Handle lastprivate conditional.
(lower_omp_1) <case GIMPLE_ASSIGN>: Handle sections construct with
lastprivate_conditional_map.
* omp-expand.c (expand_omp_sections): Handle lastprivate conditional.
libgomp/
* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.

From-SVN: r271673

gcc/ChangeLog
gcc/gimplify.c
gcc/omp-expand.c
gcc/omp-low.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c [new file with mode: 0644]

index ce0004358ce42e7a9afb5f034da54192f3aacf90..03b549601f0a7751ebb7f1ee6c5a185a63f3e8f9 100644 (file)
@@ -1,5 +1,14 @@
 2019-05-27  Jakub Jelinek  <jakub@redhat.com>
 
+       * gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional
+       on sections construct.
+       * omp-low.c (lower_lastprivate_conditional_clauses): Handle sections
+       construct.
+       (lower_omp_sections): Handle lastprivate conditional.
+       (lower_omp_1) <case GIMPLE_ASSIGN>: Handle sections construct with
+       lastprivate_conditional_map.
+       * omp-expand.c (expand_omp_sections): Handle lastprivate conditional.
+
        * omp-low.c (lower_omp_1) <case GIMPLE_ASSIGN>: Look through ordered,
        critical, taskgroup and section regions when looking for a region
        with non-NULL lastprivate_conditional_map.
index b8b7e803990a71fdacf37f9a09d8121b40173d97..a0177b25f563160aa6f993ec218dc272523a9423 100644 (file)
@@ -8143,7 +8143,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
            }
          if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
            {
-             if (code == OMP_FOR)
+             if (code == OMP_FOR || code == OMP_SECTIONS)
                flags |= GOVD_LASTPRIVATE_CONDITIONAL;
              else
                {
index dfac4b075e5bdc25653476f97912b1b59170d4b2..038781c918ccd9b902c85461255b59a8e2b41c9b 100644 (file)
@@ -6386,21 +6386,62 @@ expand_omp_sections (struct omp_region *region)
   vin = gimple_omp_sections_control (sections_stmt);
   tree clauses = gimple_omp_sections_clauses (sections_stmt);
   tree reductmp = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
-  if (reductmp)
-    {
-      tree reductions = OMP_CLAUSE_DECL (reductmp);
-      gcc_assert (TREE_CODE (reductions) == SSA_NAME);
-      gimple *g = SSA_NAME_DEF_STMT (reductions);
-      reductions = gimple_assign_rhs1 (g);
-      OMP_CLAUSE_DECL (reductmp) = reductions;
-      gimple_stmt_iterator gsi = gsi_for_stmt (g);
+  tree condtmp = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
+  tree cond_var = NULL_TREE;
+  if (reductmp || condtmp)
+    {
+      tree reductions = null_pointer_node, mem = null_pointer_node;
+      tree memv = NULL_TREE, condtemp = NULL_TREE;
+      gimple_stmt_iterator gsi = gsi_none ();
+      gimple *g = NULL;
+      if (reductmp)
+       {
+         reductions = OMP_CLAUSE_DECL (reductmp);
+         gcc_assert (TREE_CODE (reductions) == SSA_NAME);
+         g = SSA_NAME_DEF_STMT (reductions);
+         reductions = gimple_assign_rhs1 (g);
+         OMP_CLAUSE_DECL (reductmp) = reductions;
+         gsi = gsi_for_stmt (g);
+       }
+      else
+       gsi = si;
+      if (condtmp)
+       {
+         condtemp = OMP_CLAUSE_DECL (condtmp);
+         tree c = omp_find_clause (OMP_CLAUSE_CHAIN (condtmp),
+                                   OMP_CLAUSE__CONDTEMP_);
+         cond_var = OMP_CLAUSE_DECL (c);
+         tree type = TREE_TYPE (condtemp);
+         memv = create_tmp_var (type);
+         TREE_ADDRESSABLE (memv) = 1;
+         unsigned cnt = 0;
+         for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+               && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
+             ++cnt;
+         unsigned HOST_WIDE_INT sz
+           = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type))) * cnt;
+         expand_omp_build_assign (&gsi, memv, build_int_cst (type, sz),
+                                  false);
+         mem = build_fold_addr_expr (memv);
+       }
       t = build_int_cst (unsigned_type_node, len - 1);
       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS2_START);
-      stmt = gimple_build_call (u, 3, t, reductions, null_pointer_node);
+      stmt = gimple_build_call (u, 3, t, reductions, mem);
       gimple_call_set_lhs (stmt, vin);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
-      gsi_remove (&gsi, true);
-      release_ssa_name (gimple_assign_lhs (g));
+      if (condtmp)
+       {
+         expand_omp_build_assign (&gsi, condtemp, memv, false);
+         tree t = build2 (PLUS_EXPR, TREE_TYPE (cond_var),
+                          vin, build_one_cst (TREE_TYPE (cond_var)));
+         expand_omp_build_assign (&gsi, cond_var, t, false);
+       }
+      if (reductmp)
+       {
+         gsi_remove (&gsi, true);
+         release_ssa_name (gimple_assign_lhs (g));
+       }
     }
   else if (!is_combined_parallel (region))
     {
@@ -6416,7 +6457,7 @@ expand_omp_sections (struct omp_region *region)
       u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
       stmt = gimple_build_call (u, 0);
     }
-  if (!reductmp)
+  if (!reductmp && !condtmp)
     {
       gimple_call_set_lhs (stmt, vin);
       gsi_insert_after (&si, stmt, GSI_SAME_STMT);
@@ -6508,7 +6549,13 @@ expand_omp_sections (struct omp_region *region)
       bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
       stmt = gimple_build_call (bfn_decl, 0);
       gimple_call_set_lhs (stmt, vnext);
-      gsi_insert_after (&si, stmt, GSI_SAME_STMT);
+      gsi_insert_before (&si, stmt, GSI_SAME_STMT);
+      if (cond_var)
+       {
+         tree t = build2 (PLUS_EXPR, TREE_TYPE (cond_var),
+                          vnext, build_one_cst (TREE_TYPE (cond_var)));
+         expand_omp_build_assign (&si, cond_var, t, false);
+       }
       gsi_remove (&si, true);
 
       single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
index db9f5047c72d667f80eb1674c59aefebc6b23059..e673abaf4a2e6e03f0140844eb49c1d221d56944 100644 (file)
@@ -5370,7 +5370,6 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 static void
 lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
 {
-  struct omp_for_data fd;
   tree iter_type = NULL_TREE;
   tree cond_ptr = NULL_TREE;
   tree iter_var = NULL_TREE;
@@ -5380,8 +5379,15 @@ lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
       {
        if (iter_type == NULL)
          {
-           omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd, NULL);
-           iter_type = unsigned_type_for (fd.iter_type);
+           if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR)
+             {
+               struct omp_for_data fd;
+               omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd,
+                                     NULL);
+               iter_type = unsigned_type_for (fd.iter_type);
+             }
+           else if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
+             iter_type = unsigned_type_node;
            cond_ptr = create_tmp_var_raw (build_pointer_type (iter_type));
            DECL_CONTEXT (cond_ptr) = current_function_decl;
            DECL_SEEN_IN_BIND_EXPR_P (cond_ptr) = 1;
@@ -6739,7 +6745,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gomp_sections *stmt;
   gimple *t;
   gbind *new_stmt, *bind;
-  gimple_seq ilist, dlist, olist, tred_dlist = NULL, new_body;
+  gimple_seq ilist, dlist, olist, tred_dlist = NULL, clist = NULL, new_body;
 
   stmt = as_a <gomp_sections *> (gsi_stmt (*gsi_p));
 
@@ -6771,6 +6777,12 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
                           &ilist, &dlist, ctx, NULL);
 
+  control = create_tmp_var (unsigned_type_node, ".section");
+  gimple_omp_sections_set_control (stmt, control);
+
+  tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
+  lower_lastprivate_conditional_clauses (clauses_ptr, ctx);
+
   new_body = gimple_omp_body (stmt);
   gimple_omp_set_body (stmt, NULL);
   tgsi = gsi_start (new_body);
@@ -6792,7 +6804,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
        {
          gimple_seq l = NULL;
          lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
-                                    NULL, &l, NULL, ctx);
+                                    &ilist, &l, &clist, ctx);
          gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
          gimple_omp_section_set_last (sec_start);
        }
@@ -6806,7 +6818,17 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   olist = NULL;
   lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist,
-                          NULL, ctx);
+                          &clist, ctx);
+  if (clist)
+    {
+      tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
+      gcall *g = gimple_build_call (fndecl, 0);
+      gimple_seq_add_stmt (&olist, g);
+      gimple_seq_add_seq (&olist, clist);
+      fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
+      g = gimple_build_call (fndecl, 0);
+      gimple_seq_add_stmt (&olist, g);
+    }
 
   block = make_node (BLOCK);
   new_stmt = gimple_build_bind (NULL, NULL, block);
@@ -6824,9 +6846,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
   gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
   gimple_seq_add_stmt (&new_body, bind);
 
-  control = create_tmp_var (unsigned_type_node, ".section");
   t = gimple_build_omp_continue (control, control);
-  gimple_omp_sections_set_control (stmt, control);
   gimple_seq_add_stmt (&new_body, t);
 
   gimple_seq_add_seq (&new_body, olist);
@@ -10640,8 +10660,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
          if (DECL_P (lhs))
            if (tree *v = up->lastprivate_conditional_map->get (lhs))
              {
-               tree clauses
-                 = gimple_omp_for_clauses (as_a <gomp_for *> (up->stmt));
+               tree clauses;
+               if (gimple_code (up->stmt) == GIMPLE_OMP_FOR)
+                 clauses = gimple_omp_for_clauses (up->stmt);
+               else
+                 clauses = gimple_omp_sections_clauses (up->stmt);
                tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
                c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
                                     OMP_CLAUSE__CONDTEMP_);
index 33906ededc7e298de50bdbad86ee4207b42111a8..e6cda724fbd2fe2ea9d258f7142193dafbde14f9 100644 (file)
@@ -1,5 +1,7 @@
 2019-05-27  Jakub Jelinek  <jakub@redhat.com>
 
+       * testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.
+
        * testsuite/libgomp.c-c++-common/lastprivate-conditional-3.c: New test.
 
        PR libgomp/90641
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c
new file mode 100644 (file)
index 0000000..bc102a1
--- /dev/null
@@ -0,0 +1,161 @@
+#include <stdlib.h>
+
+int x;
+long long y;
+int r, s, t;
+
+void
+foo (const char *a)
+{
+  #pragma omp sections lastprivate (conditional: x, y)
+  {
+    if (a[0])
+      x = a[0];
+    #pragma omp section
+    {
+      if (a[1])
+       x = a[1];
+      if (a[2])
+       y = a[2];
+    }
+    #pragma omp section
+    if (a[3])
+      y = a[3];
+    #pragma omp section
+    if (a[4])
+      x = a[4];
+    #pragma omp section
+    {
+      if (a[5])
+       x = a[5];
+      if (a[6])
+       y = a[6];
+    }
+  }
+}
+
+void
+bar (const char *a)
+{
+  #pragma omp sections lastprivate (conditional: x, y) reduction (task, +: t)
+  {
+    if (a[0])
+      x = a[0];
+    #pragma omp section
+    {
+      if (a[1])
+       x = a[1];
+      if (a[2])
+       y = a[2];
+      #pragma omp task in_reduction (+: t)
+      t++;
+    }
+    #pragma omp section
+    if (a[3])
+      y = a[3];
+    #pragma omp section
+    if (a[4])
+      x = a[4];
+    #pragma omp section
+    {
+      #pragma omp task in_reduction (+: t)
+      ++t;
+      if (a[5])
+       x = a[5];
+      if (a[6])
+       y = a[6];
+    }
+  }
+}
+
+void
+baz (const char *a)
+{
+  #pragma omp sections lastprivate (conditional: x, y) reduction (+: r, s)
+  {
+    if (a[0])
+      x = a[0];
+    #pragma omp section
+    {
+      if (a[1])
+       x = a[1];
+      ++r;
+      ++s;
+      if (a[2])
+       y = a[2];
+    }
+    #pragma omp section
+    if (a[3])
+      y = a[3];
+    #pragma omp section
+    {
+      ++s;
+      if (a[4])
+       x = a[4];
+    }
+    #pragma omp section
+    {
+      if (a[5])
+       x = a[5];
+      if (a[6])
+       y = a[6];
+      ++s;
+    }
+  }
+}
+
+int
+main ()
+{
+  #pragma omp parallel
+  {
+    foo ("\0\1\2\3\0\5");
+    if (x != 5 || y != 3)
+      abort ();
+    #pragma omp barrier
+    foo ("\6\0\0\0\0\0\7");
+    if (x != 6 || y != 7)
+      abort ();
+    #pragma omp barrier
+    foo ("\7\6\5\4\3\2\1");
+    if (x != 2 || y != 1)
+      abort ();
+    #pragma omp barrier
+    foo ("\0\0\4\3\0\7");
+    if (x != 7 || y != 3)
+      abort ();
+    #pragma omp barrier
+    bar ("\0\1\2\4\0\5");
+    if (x != 5 || y != 4 || t != 2)
+      abort ();
+    #pragma omp barrier
+    bar ("\6\0\0\0\0\0\7");
+    if (x != 6 || y != 7 || t != 4)
+      abort ();
+    #pragma omp barrier
+    bar ("\7\6\5\4\3\2\1");
+    if (x != 2 || y != 1 || t != 6)
+      abort ();
+    #pragma omp barrier
+    bar ("\0\0\4\3\0\7");
+    if (x != 7 || y != 3 || t != 8)
+      abort ();
+    #pragma omp barrier
+    baz ("\0\1\2\4\0\5");
+    if (x != 5 || y != 4 || r != 1 || s != 3)
+      abort ();
+    #pragma omp barrier
+    baz ("\6\0\0\0\0\0\7");
+    if (x != 6 || y != 7 || r != 2 || s != 6)
+      abort ();
+    #pragma omp barrier
+    baz ("\7\6\5\4\3\2\1");
+    if (x != 2 || y != 1 || r != 3 || s != 9)
+      abort ();
+    #pragma omp barrier
+    baz ("\0\0\4\3\0\7");
+    if (x != 7 || y != 3 || r != 4 || s != 12)
+      abort ();
+  }
+  return 0;
+}