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] Allow taskloop cancellation


Hi!

Taskloop cancellation which OpenMP 5.0 explicitly allows worked fine on the
library side and on the compiler side if the cancel taskgroup or
cancellation point taskgroup is inside of explicit task and there is no
outer parallel/teams etc. in that function, taskloop is in another function
that calls it.  The following adjusts the nesting checking, so that we
handle it properly and adds testsuite coverage.

Bootstrapped/regtested on powerpc64{,le}-linux, committed to trunk.

2018-12-02  Jakub Jelinek  <jakub@redhat.com>

	* omp-low.c (check_omp_nesting_restrictions): Allow cancel or
	cancellation point with taskgroup clause inside of taskloop.  Consider
	a taskloop construct without nogroup clause as implicit taskgroup for
	diagnostics if cancel/cancellation point with taskgroup clause is
	closely nested inside of taskgroup region.

	* c-c++-common/gomp/cancel-1.c (f2): Add various taskloop related
	tests.

	* testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c: New test.

--- gcc/omp-low.c.jj	2018-12-01 15:04:34.000000000 +0100
+++ gcc/omp-low.c	2018-12-01 15:38:47.237454873 +0100
@@ -2744,7 +2744,10 @@ check_omp_nesting_restrictions (gimple *
 	      kind = "sections";
 	      break;
 	    case 8:
-	      if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
+	      if (!is_task_ctx (ctx)
+		  && (!is_taskloop_ctx (ctx)
+		      || ctx->outer == NULL
+		      || !is_task_ctx (ctx->outer)))
 		bad = "#pragma omp task";
 	      else
 		{
@@ -2767,6 +2770,17 @@ check_omp_nesting_restrictions (gimple *
 				    "nested inside of %<taskgroup%> region",
 				    construct);
 			  return false;
+			case GIMPLE_OMP_TASK:
+			  if (gimple_omp_task_taskloop_p (octx->stmt)
+			      && octx->outer
+			      && is_taskloop_ctx (octx->outer))
+			    {
+			      tree clauses
+				= gimple_omp_for_clauses (octx->outer->stmt);
+			      if (!omp_find_clause (clauses, OMP_CLAUSE_NOGROUP))
+				break;
+			    }
+			  continue;
 			default:
 			  continue;
 			}
--- gcc/testsuite/c-c++-common/gomp/cancel-1.c.jj	2016-07-22 15:55:28.000000000 +0200
+++ gcc/testsuite/c-c++-common/gomp/cancel-1.c	2018-12-01 17:01:07.993603645 +0100
@@ -95,6 +95,40 @@ f2 (void)
       #pragma omp cancellation point sections	/* { dg-error "not closely nested inside" } */
       #pragma omp cancellation point taskgroup
     }
+    #pragma omp taskloop
+    for (i = 0; i < 10; i++)
+      {
+        #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
+        #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
+        #pragma omp cancel sections		/* { dg-error "not closely nested inside" } */
+        #pragma omp cancel taskgroup
+        #pragma omp cancellation point parallel	/* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point for	/* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point sections	/* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point taskgroup
+	#pragma omp task
+	{
+	  #pragma omp cancellation point taskgroup
+	  #pragma omp cancel taskgroup
+	}
+      }
+    #pragma omp taskloop nogroup
+    for (i = 0; i < 10; i++)
+      {
+        #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
+        #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
+        #pragma omp cancel sections		/* { dg-error "not closely nested inside" } */
+        #pragma omp cancel taskgroup		/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+        #pragma omp cancellation point parallel	/* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point for	/* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point sections	/* { dg-error "not closely nested inside" } */
+        #pragma omp cancellation point taskgroup/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	#pragma omp task
+	{
+	  #pragma omp cancellation point taskgroup/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  #pragma omp cancel taskgroup		/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	}
+      }
     #pragma omp taskgroup
     {
       #pragma omp task
@@ -105,6 +139,17 @@ f2 (void)
 	  #pragma omp cancel taskgroup
 	}
       }
+      #pragma omp taskloop nogroup
+      for (i = 0; i < 10; i++)
+	{
+	  #pragma omp task
+	  {
+	    #pragma omp cancellation point taskgroup
+	    #pragma omp cancel taskgroup
+	  }
+	  #pragma omp cancellation point taskgroup
+	  #pragma omp cancel taskgroup
+	}
     }
     #pragma omp taskgroup
     {
@@ -115,6 +160,18 @@ f2 (void)
 	  #pragma omp cancel taskgroup		/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
 	  #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
 	}
+	#pragma omp taskloop
+	for (i = 0; i < 10; i++)
+	  {
+	    #pragma omp cancel taskgroup
+	    #pragma omp cancellation point taskgroup
+	  }
+	#pragma omp taskloop nogroup
+	for (i = 0; i < 10; i++)
+	  {
+	    #pragma omp cancel taskgroup	     /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	    #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  }
       }
       #pragma omp target
       {
@@ -144,6 +201,45 @@ f2 (void)
 	}
       }
     }
+    #pragma omp taskloop
+    for (i = 0; i < 10; i++)
+      {
+	#pragma omp parallel
+	{
+	  #pragma omp task
+	  {
+	    #pragma omp cancel taskgroup	     /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	    #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  }
+	}
+        #pragma omp target
+	{
+	  #pragma omp task
+	  {
+	    #pragma omp cancel taskgroup	     /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	    #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	  }
+	}
+	#pragma omp target
+	#pragma omp teams
+	#pragma omp distribute
+	for (j = 0; j < 10; j++)
+	  {
+	    #pragma omp task
+	    {
+	      #pragma omp cancel taskgroup	/* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	      #pragma omp cancellation point taskgroup /* { dg-error "construct not closely nested inside of .taskgroup. region" } */
+	    }
+	  }
+	#pragma omp target data map(i)
+	{
+	  #pragma omp task
+	  {
+	    #pragma omp cancel taskgroup
+	    #pragma omp cancellation point taskgroup
+	  }
+	}
+      }
     #pragma omp for
     for (i = 0; i < 10; i++)
       {
--- libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c.jj	2018-12-01 15:17:36.637005863 +0100
+++ libgomp/testsuite/libgomp.c-c++-common/cancel-taskgroup-4.c	2018-12-01 15:47:47.000000000 +0100
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var OMP_CANCELLATION "true" } */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <omp.h>
+
+int
+main ()
+{
+  int i;
+  #pragma omp parallel
+  {
+    int c = 0;
+    #pragma omp barrier
+    #pragma omp master taskloop num_tasks (25) firstprivate (c)
+    for (i = 0; i < 50; i++)
+      {
+        if (c && omp_get_cancellation ())
+	  abort ();
+	#pragma omp cancellation point taskgroup
+	usleep (30);
+	if (i > 10)
+	  c = 1;
+	#pragma omp cancel taskgroup if (i > 10)
+	if (i > 10 && omp_get_cancellation ())
+	  abort ();
+      }
+    usleep (10);
+  }
+  return 0;
+}

	Jakub


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