]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
task.c (GOMP_taskgroup_reduction_register): If team is NULL...
authorJakub Jelinek <jakub@redhat.com>
Mon, 8 Oct 2018 17:56:14 +0000 (19:56 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 8 Oct 2018 17:56:14 +0000 (19:56 +0200)
* task.c (GOMP_taskgroup_reduction_register): If team is NULL, create
implicit team with 1 thread and call GOMP_taskgroup_start again.  Don't
mix declarations with statements.
* team.c (gomp_team_end): Determine nesting by thr->ts.level != 0
rather than thr->ts.team != NULL.
* testsuite/libgomp.c-c++-common/task-reduction-4.c: New test.

From-SVN: r264940

libgomp/ChangeLog.gomp
libgomp/task.c
libgomp/team.c
libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c [new file with mode: 0644]

index 6e8b30c779d90b9fa03bf7ce00d23312645b6c84..555f5a08bc3e064f1752754c0182692615ddb530 100644 (file)
@@ -1,5 +1,12 @@
 2018-10-08  Jakub Jelinek  <jakub@redhat.com>
 
+       * task.c (GOMP_taskgroup_reduction_register): If team is NULL, create
+       implicit team with 1 thread and call GOMP_taskgroup_start again.  Don't
+       mix declarations with statements.
+       * team.c (gomp_team_end): Determine nesting by thr->ts.level != 0
+       rather than thr->ts.team != NULL.
+       * testsuite/libgomp.c-c++-common/task-reduction-4.c: New test.
+
        * testsuite/libgomp.c-c++-common/task-reduction-5.c: New test.
 
        * env.c (gomp_affinity_format_var): Use %i instead of %T and
index c5f77b002737510ca741636d38d2215775dd5ab6..fcb7e9e7103c5ff1fe1a849aa6d3fa226bae8ae9 100644 (file)
@@ -1968,11 +1968,45 @@ GOMP_taskgroup_reduction_register (uintptr_t *data)
 {
   struct gomp_thread *thr = gomp_thread ();
   struct gomp_team *team = thr->ts.team;
-  struct gomp_task *task = thr->task;
-  unsigned nthreads = team ? team->nthreads : 1;
+  struct gomp_task *task;
+  if (__builtin_expect (team == NULL, 0))
+    {
+      /* The task reduction code needs a team and task, so for
+        orphaned taskgroups just create the implicit team.  */
+      struct gomp_task_icv *icv;
+      team = gomp_new_team (1);
+      task = thr->task;
+      icv = task ? &task->icv : &gomp_global_icv;
+      team->prev_ts = thr->ts;
+      thr->ts.team = team;
+      thr->ts.team_id = 0;
+      thr->ts.work_share = &team->work_shares[0];
+      thr->ts.last_work_share = NULL;
+#ifdef HAVE_SYNC_BUILTINS
+      thr->ts.single_count = 0;
+#endif
+      thr->ts.static_trip = 0;
+      thr->task = &team->implicit_task[0];
+      gomp_init_task (thr->task, NULL, icv);
+      if (task)
+       {
+         thr->task = task;
+         gomp_end_task ();
+         free (task);
+         thr->task = &team->implicit_task[0];
+       }
+#ifdef LIBGOMP_USE_PTHREADS
+      else
+       pthread_setspecific (gomp_thread_destructor, thr);
+#endif
+      GOMP_taskgroup_start ();
+    }
+  unsigned nthreads = team->nthreads;
   size_t total_cnt = 0;
-  uintptr_t *d = data;
-  uintptr_t *old = task->taskgroup->reductions;
+  uintptr_t *d = data, *old;
+  struct htab *old_htab = NULL, *new_htab;
+  task = thr->task;
+  old = task->taskgroup->reductions;
   do
     {
       size_t sz = d[1] * nthreads;
@@ -1992,13 +2026,12 @@ GOMP_taskgroup_reduction_register (uintptr_t *data)
        d = (uintptr_t *) d[4];
     }
   while (1);
-  struct htab *old_htab = NULL;
   if (old && old[5])
     {
       old_htab = (struct htab *) old[5];
       total_cnt += htab_elements (old_htab);
     }
-  struct htab *new_htab = htab_create (total_cnt);
+  new_htab = htab_create (total_cnt);
   if (old_htab)
     {
       /* Copy old hash table, like in htab_expand.  */
index c73a349b56f9965f739c50e0fc46b8e679c150d5..186637b4dbfdc818924a13e5788b7fde9f150543 100644 (file)
@@ -945,7 +945,7 @@ gomp_team_end (void)
   gomp_end_task ();
   thr->ts = team->prev_ts;
 
-  if (__builtin_expect (thr->ts.team != NULL, 0))
+  if (__builtin_expect (thr->ts.level != 0, 0))
     {
 #ifdef HAVE_SYNC_BUILTINS
       __sync_fetch_and_add (&gomp_managed_threads, 1L - team->nthreads);
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-4.c
new file mode 100644 (file)
index 0000000..b0e5197
--- /dev/null
@@ -0,0 +1,70 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+
+void
+bar (long long int *p)
+{
+  p[0] *= 2;
+  #pragma omp task in_reduction (*: p[0])
+  p[0] *= 3;
+}
+
+void
+foo (long long int *p, long long int *q)
+{
+  #pragma omp taskgroup task_reduction (*: p[0])
+  {
+    #pragma omp task in_reduction (*: p[0])
+    bar (p);
+    #pragma omp task in_reduction (*: p[0])
+    bar (p);
+    bar (p);
+    #pragma omp taskgroup task_reduction (*: q[0])
+    {
+      #pragma omp task in_reduction (*: q[0])
+      bar (q);
+      #pragma omp task in_reduction (*: q[0])
+      bar (q);
+      #pragma omp task in_reduction (*: q[0])
+      bar (q);
+      bar (q);
+      #pragma omp task in_reduction (*: p[0])
+      {
+       #pragma omp taskgroup task_reduction (*: p[0])
+       {
+         #pragma omp task in_reduction (*: p[0])
+         bar (p);
+         p[0] *= 2;
+         #pragma omp task in_reduction (*: p[0])
+         bar (p);
+       }
+      }
+    }
+  }
+}
+
+int
+main ()
+{
+  long long int p = 1LL, q = 1LL;
+  foo (&p, &q);
+  if (p != 6LL * 6LL * 6LL * 6LL * 6LL * 2LL || q != 6LL * 6LL * 6LL * 6LL)
+    abort ();
+  p = 1LL;
+  q = 1LL;
+  #pragma omp taskgroup
+  foo (&p, &q);
+  if (p != 6LL * 6LL * 6LL * 6LL * 6LL * 2LL || q != 6LL * 6LL * 6LL * 6LL)
+    abort ();
+  p = 1LL;
+  q = 1LL;
+  #pragma omp parallel
+  #pragma omp single
+  foo (&p, &q);
+  if (p != 6LL * 6LL * 6LL * 6LL * 6LL * 2LL || q != 6LL * 6LL * 6LL * 6LL)
+    abort ();
+  return 0;
+}