diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-05-24 09:12:44 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-05-24 09:12:44 +0200 |
commit | b43836914bdc2a37563cf31359b2c4803bfe4374 (patch) | |
tree | b46c9fd3a7988e119e9dc60919b0866efdd6c52e /libgomp/task.c | |
parent | 1adf11822bd48f4d65156b7642514630c08c4d00 (diff) | |
download | gcc-b43836914bdc2a37563cf31359b2c4803bfe4374.zip gcc-b43836914bdc2a37563cf31359b2c4803bfe4374.tar.gz gcc-b43836914bdc2a37563cf31359b2c4803bfe4374.tar.bz2 |
openmp: Add taskwait nowait depend support [PR105378]
This patch adds support for (so far C/C++)
#pragma omp taskwait nowait depend(...)
directive, which is like
#pragma omp task depend(...)
;
but slightly optimized on the library side, so that it creates
the task only for the purpose of dependency tracking and doesn't actually
schedule it and wait for it when the dependencies are satisfied, instead
makes its dependencies satisfied right away.
2022-05-24 Jakub Jelinek <jakub@redhat.com>
PR c/105378
gcc/
* omp-builtins.def (BUILT_IN_GOMP_TASKWAIT_DEPEND_NOWAIT): New
builtin.
* gimplify.cc (gimplify_omp_task): Diagnose taskwait with nowait
clause but no depend clauses.
* omp-expand.cc (expand_taskwait_call): Use
BUILT_IN_GOMP_TASKWAIT_DEPEND_NOWAIT rather than
BUILT_IN_GOMP_TASKWAIT_DEPEND if nowait clause is present.
gcc/c/
* c-parser.cc (OMP_TASKWAIT_CLAUSE_MASK): Add nowait clause.
gcc/cp/
* parser.cc (OMP_TASKWAIT_CLAUSE_MASK): Add nowait clause.
gcc/testsuite/
* c-c++-common/gomp/taskwait-depend-nowait-1.c: New test.
libgomp/
* libgomp_g.h (GOMP_taskwait_depend_nowait): Declare.
* libgomp.map (GOMP_taskwait_depend_nowait): Export at GOMP_5.1.1.
* task.c (empty_task): New function.
(gomp_task_run_post_handle_depend_hash): Declare earlier.
(gomp_task_run_post_handle_depend): Declare.
(GOMP_task): Optimize fn == empty_task if there is nothing to wait
for.
(gomp_task_run_post_handle_dependers): Optimize task->fn == empty_task.
(GOMP_taskwait_depend_nowait): New function.
* testsuite/libgomp.c-c++-common/taskwait-depend-nowait-1.c: New test.
Diffstat (limited to 'libgomp/task.c')
-rw-r--r-- | libgomp/task.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/libgomp/task.c b/libgomp/task.c index 6b11a8f..7925e58 100644 --- a/libgomp/task.c +++ b/libgomp/task.c @@ -460,6 +460,17 @@ gomp_task_handle_depend (struct gomp_task *task, struct gomp_task *parent, } } +/* Body of empty task like taskwait nowait depend. */ + +static void +empty_task (void *data __attribute__((unused))) +{ +} + +static void gomp_task_run_post_handle_depend_hash (struct gomp_task *); +static inline size_t gomp_task_run_post_handle_depend (struct gomp_task *, + struct gomp_team *); + /* Called when encountering an explicit task directive. If IF_CLAUSE is false, then we must not delay in executing the task. If UNTIED is true, then the task may be executed by any member of the team. @@ -681,6 +692,18 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), gomp_mutex_unlock (&team->task_lock); return; } + /* Check for taskwait nowait depend which doesn't need to wait for + anything. */ + if (__builtin_expect (fn == empty_task, 0)) + { + if (taskgroup) + taskgroup->num_children--; + gomp_task_run_post_handle_depend_hash (task); + gomp_mutex_unlock (&team->task_lock); + gomp_finish_task (task); + free (task); + return; + } } priority_queue_insert (PQ_CHILDREN, &parent->children_queue, @@ -839,8 +862,6 @@ GOMP_PLUGIN_target_task_completion (void *data) gomp_mutex_unlock (&team->task_lock); } -static void gomp_task_run_post_handle_depend_hash (struct gomp_task *); - /* Called for nowait target tasks. */ bool @@ -1357,6 +1378,18 @@ gomp_task_run_post_handle_dependers (struct gomp_task *child_task, continue; struct gomp_taskgroup *taskgroup = task->taskgroup; + if (__builtin_expect (task->fn == empty_task, 0)) + { + if (!parent) + task->parent = NULL; + if (gomp_task_run_post_handle_depend (task, team)) + ++ret; + if (taskgroup) + taskgroup->num_children--; + gomp_finish_task (task); + free (task); + continue; + } if (parent) { priority_queue_insert (PQ_CHILDREN, &parent->children_queue, @@ -1832,6 +1865,16 @@ GOMP_taskwait_depend (void **depend) gomp_task_maybe_wait_for_dependencies (depend); } +/* Called when encountering a taskwait directive with nowait and depend + clause(s). Create a possibly deferred task construct with empty body. */ + +void +GOMP_taskwait_depend_nowait (void **depend) +{ + ialias_call (GOMP_task) (empty_task, "", NULL, 0, 1, true, + GOMP_TASK_FLAG_DEPEND, depend, 0, NULL); +} + /* An undeferred task is about to run. Wait for all tasks that this undeferred task depends on. |