diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 5a1cac157bebe51ba7804c0d29dfbb1e4ae7d5e1..fb70823cfcc44cf3de62a62c73eaee3e0f8f9d4b 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,12 @@
 2008-06-11  Jakub Jelinek  <jakub@redhat.com>
 
+	* libgomp.h (struct gomp_task): Add in_tied_task field.
+	* task.c (gomp_init_task): Initialize it.
+	(GOMP_task): Likewise.  Call gomp_team_barrier_set_task_pending
+	unconditionally.  Don't call gomp_team_barrier_wake if
+	current task is implicit or if(0) from implicit and number of
+	running tasks is equal to nthreads - 1.
+
 	PR libgomp/36471
 	* omp_lib.f90.in (omp_get_ancestor_thread_num_8,
 	omp_get_team_size_8): Fix pastos.
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index 66180122c1e81ae3b22fdfa1d7d60d1f1ae2f84f..7292358b9aa96e02f010ef1445db74827eec1b79 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -253,6 +253,7 @@ struct gomp_task
   void *fn_data;
   enum gomp_task_kind kind;
   bool in_taskwait;
+  bool in_tied_task;
   gomp_sem_t taskwait_sem;
 };
 
diff --git a/libgomp/task.c b/libgomp/task.c
index 903948ceca314631e3f30b81dbb880c7d610f7de..ce991b8dca26198e9ea76fd08c83a94cfbbfdb24 100644
--- a/libgomp/task.c
+++ b/libgomp/task.c
@@ -43,6 +43,7 @@ gomp_init_task (struct gomp_task *task, struct gomp_task *parent_task,
   task->icv = *prev_icv;
   task->kind = GOMP_TASK_IMPLICIT;
   task->in_taskwait = false;
+  task->in_tied_task = false;
   task->children = NULL;
   gomp_sem_init (&task->taskwait_sem, 0);
 }
@@ -103,6 +104,8 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
 
       gomp_init_task (&task, thr->task, gomp_icv (false));
       task.kind = GOMP_TASK_IFFALSE;
+      if (thr->task)
+	task.in_tied_task = thr->task->in_tied_task;
       thr->task = &task;
       if (__builtin_expect (cpyfn != NULL, 0))
 	{
@@ -134,6 +137,7 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
 		      & ~(uintptr_t) (arg_align - 1));
       gomp_init_task (task, parent, gomp_icv (false));
       task->kind = GOMP_TASK_IFFALSE;
+      task->in_tied_task = parent->in_tied_task;
       thr->task = task;
       if (cpyfn)
 	cpyfn (arg, data);
@@ -143,6 +147,7 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
       task->kind = GOMP_TASK_WAITING;
       task->fn = fn;
       task->fn_data = arg;
+      task->in_tied_task = true;
       gomp_mutex_lock (&team->task_lock);
       if (parent->children)
 	{
@@ -170,9 +175,10 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
 	  task->prev_queue = task;
 	  team->task_queue = task;
 	}
-      if (team->task_count++ == 0)
-	gomp_team_barrier_set_task_pending (&team->barrier);
-      do_wake = team->task_running_count < team->nthreads;
+      ++team->task_count;
+      gomp_team_barrier_set_task_pending (&team->barrier);
+      do_wake = team->task_running_count + !parent->in_tied_task
+		< team->nthreads;
       gomp_mutex_unlock (&team->task_lock);
       if (do_wake)
 	gomp_team_barrier_wake (&team->barrier, 1);