This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix two omp loop issues


Hi!

While starting to work on OpenMP 4.0 Fortran stuff, I've noticed
some issues in C/C++ too.
One problem is that when some variable other than the iteration var
is linear on a combined for simd or parallel for simd loop, we weren't
adding a barrier between read of the initial value and store of the final
value.  Fixed by making such vars firstprivate+lastprivate on the
omp for loop.
The second issue is that if there are lastprivate vars on combined for simd
loop, the outer assignment on last iteration was keyed on some fd->loop.v
iterator value which hasn't been ever assigned to.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk/4.9.

2014-05-02  Jakub Jelinek  <jakub@redhat.com>

	* gimplify.c (gimplify_adjust_omp_clauses_1): Handle
	GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE.
	(gimplify_adjust_omp_clauses): Simd region is never
	directly nested in combined parallel.  Instead, for linear
	with copyin/copyout, if in combined for simd loop, make decl
	firstprivate/lastprivate on OMP_FOR.
	* omp-low.c (expand_omp_for_generic, expand_omp_for_static_nochunk,
	expand_omp_for_static_chunk): When setting endvar, also set
	fd->loop.v to the same value.
libgomp/
	* testsuite/libgomp.c/simd-10.c: New test.
	* testsuite/libgomp.c/simd-11.c: New test.
	* testsuite/libgomp.c/simd-12.c: New test.
	* testsuite/libgomp.c/simd-13.c: New test.

--- gcc/gimplify.c.jj	2014-04-30 19:06:11.000000000 +0200
+++ gcc/gimplify.c	2014-05-02 11:38:07.908463543 +0200
@@ -6294,9 +6294,17 @@ gimplify_adjust_omp_clauses_1 (splay_tre
 	  OMP_CLAUSE_CHAIN (clause) = nc;
 	}
     }
+  if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
+    {
+      tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
+      OMP_CLAUSE_DECL (nc) = decl;
+      OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
+      OMP_CLAUSE_CHAIN (nc) = *list_p;
+      OMP_CLAUSE_CHAIN (clause) = nc;
+      lang_hooks.decls.omp_finish_clause (nc);
+    }
   *list_p = clause;
   lang_hooks.decls.omp_finish_clause (clause);
-
   return 0;
 }
 
@@ -6335,18 +6343,17 @@ gimplify_adjust_omp_clauses (tree *list_
 	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
 		  && ctx->outer_context
 		  && !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
-		       && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
-		  && !is_global_var (decl))
+		       && OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
 		{
-		  if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+		  if (ctx->outer_context->combined_loop
+		      && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
 		    {
 		      n = splay_tree_lookup (ctx->outer_context->variables,
 					     (splay_tree_key) decl);
 		      if (n == NULL
 			  || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
 			{
-			  int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
-				      ? GOVD_LASTPRIVATE : GOVD_SHARED;
+			  int flags = GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE;
 			  if (n == NULL)
 			    omp_add_variable (ctx->outer_context, decl,
 					      flags | GOVD_SEEN);
@@ -6354,7 +6361,7 @@ gimplify_adjust_omp_clauses (tree *list_
 			    n->value |= flags | GOVD_SEEN;
 			}
 		    }
-		  else
+		  else if (!is_global_var (decl))
 		    omp_notice_variable (ctx->outer_context, decl, true);
 		}
 	    }
--- gcc/omp-low.c.jj	2014-04-30 09:13:22.000000000 +0200
+++ gcc/omp-low.c	2014-05-01 15:18:05.368771615 +0200
@@ -5584,6 +5584,12 @@ expand_omp_for_generic (struct omp_regio
     {
       stmt = gimple_build_assign (endvar, iend);
       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+      if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (iend)))
+	stmt = gimple_build_assign (fd->loop.v, iend);
+      else
+	stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, iend,
+					     NULL_TREE);
+      gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
     }
   if (fd->collapse > 1)
     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
@@ -6000,6 +6006,12 @@ expand_omp_for_static_nochunk (struct om
     {
       stmt = gimple_build_assign (endvar, e);
       gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+      if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
+	stmt = gimple_build_assign (fd->loop.v, e);
+      else
+	stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
+					     NULL_TREE);
+      gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
     }
   if (fd->collapse > 1)
     expand_omp_for_init_vars (fd, &gsi, counts, inner_stmt, startvar);
@@ -6385,6 +6397,12 @@ expand_omp_for_static_chunk (struct omp_
     {
       stmt = gimple_build_assign (endvar, e);
       gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
+      if (useless_type_conversion_p (TREE_TYPE (fd->loop.v), TREE_TYPE (e)))
+	stmt = gimple_build_assign (fd->loop.v, e);
+      else
+	stmt = gimple_build_assign_with_ops (NOP_EXPR, fd->loop.v, e,
+					     NULL_TREE);
+      gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
     }
   if (fd->collapse > 1)
     expand_omp_for_init_vars (fd, &si, counts, inner_stmt, startvar);
--- libgomp/testsuite/libgomp.c/simd-10.c.jj	2014-05-01 14:09:25.716138836 +0200
+++ libgomp/testsuite/libgomp.c/simd-10.c	2014-05-01 14:09:44.081053684 +0200
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int s = 0, i, u;
+
+void
+foo ()
+{
+  #pragma omp for simd schedule(static, 32) reduction(+:s) lastprivate(u)
+  for (i = 0; i < 128; i++)
+    {
+      s++;
+      u = i;
+    }
+  if (i != 128 || s != 128 || u != 127)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-11.c.jj	2014-05-01 14:09:28.547127103 +0200
+++ libgomp/testsuite/libgomp.c/simd-11.c	2014-05-01 14:09:52.813014645 +0200
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int s = 0, i, j, u;
+
+void
+foo ()
+{
+  #pragma omp for simd schedule(static, 32) reduction(+:s) lastprivate(u) collapse(2)
+  for (i = 0; i < 16; i++)
+    for (j = 0; j < 16; j++)
+      {
+	s++;
+	u = i + j;
+      }
+  if (i != 16 || j != 16 || s != 256 || u != 30)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-12.c.jj	2014-05-02 11:41:08.481513881 +0200
+++ libgomp/testsuite/libgomp.c/simd-12.c	2014-05-02 11:43:12.999852945 +0200
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int
+main ()
+{
+  int k = 0, i, s = 0;
+  #pragma omp parallel
+  #pragma omp for simd linear(k : 3) reduction(+: s) schedule (static, 16)
+  for (i = 0; i < 128; i++)
+    {
+      k = k + 3;
+      s = s + k;
+    }
+  if (s != 128 * 129 / 2 * 3) __builtin_abort ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/simd-13.c.jj	2014-03-19 15:57:57.735114622 +0100
+++ libgomp/testsuite/libgomp.c/simd-13.c	2014-05-02 13:55:25.184041803 +0200
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+int
+main ()
+{
+  int k = 0, i, s = 0;
+  #pragma omp parallel for simd linear(k : 3) reduction(+: s) schedule (static, 16)
+  for (i = 0; i < 128; i++)
+    {
+      k = k + 3;
+      s = s + k;
+    }
+  if (s != 128 * 129 / 2 * 3) __builtin_abort ();
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]