public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] Add lastprivate(conditional:) support for the sections construct
@ 2019-05-28  2:34 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2019-05-28  2:34 UTC (permalink / raw)
  To: gcc-patches

Hi!

This adds support for the sections construct, similarly to the worksharing loop
construct only supported when not combined with parallel for now.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

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.
libgomp/
	* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.

--- gcc/gimplify.c.jj	2019-05-24 23:30:35.925880550 +0200
+++ gcc/gimplify.c	2019-05-27 16:00:23.476677962 +0200
@@ -8143,7 +8143,7 @@ gimplify_scan_omp_clauses (tree *list_p,
 	    }
 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
 	    {
-	      if (code == OMP_FOR)
+	      if (code == OMP_FOR || code == OMP_SECTIONS)
 		flags |= GOVD_LASTPRIVATE_CONDITIONAL;
 	      else
 		{
--- gcc/omp-low.c.jj	2019-05-27 15:49:29.055288052 +0200
+++ gcc/omp-low.c	2019-05-27 17:21:20.260557994 +0200
@@ -5370,7 +5370,6 @@ lower_rec_input_clauses (tree clauses, g
 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 (t
       {
 	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
   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
   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
 	{
 	  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
 
   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
   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
 	  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_);
--- gcc/omp-expand.c.jj	2019-05-24 23:30:35.928880501 +0200
+++ gcc/omp-expand.c	2019-05-27 18:11:22.837471127 +0200
@@ -6386,21 +6386,62 @@ expand_omp_sections (struct omp_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 *
       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 *
       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;
--- libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c.jj	2019-05-27 18:36:50.809879601 +0200
+++ libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c	2019-05-27 18:27:16.353123168 +0200
@@ -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;
+}

	Jakub

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-05-27 21:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-28  2:34 [committed] Add lastprivate(conditional:) support for the sections construct Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).