aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c/c-parser.cc3
-rw-r--r--gcc/cp/parser.cc3
-rw-r--r--gcc/gimplify.cc31
-rw-r--r--gcc/omp-builtins.def3
-rw-r--r--gcc/omp-expand.cc8
-rw-r--r--gcc/testsuite/c-c++-common/gomp/taskwait-depend-nowait-1.c17
-rw-r--r--libgomp/libgomp.map5
-rw-r--r--libgomp/libgomp_g.h1
-rw-r--r--libgomp/task.c47
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-nowait-1.c39
10 files changed, 143 insertions, 14 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 8df8f60..492d995 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -20453,7 +20453,8 @@ c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
*/
#define OMP_TASKWAIT_CLAUSE_MASK \
- (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static void
c_parser_omp_taskwait (c_parser *parser)
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 24585c1..868b861 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -43793,7 +43793,8 @@ cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
# pragma omp taskwait taskwait-clause[opt] new-line */
#define OMP_TASKWAIT_CLAUSE_MASK \
- (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static void
cp_parser_omp_taskwait (cp_parser *parser, cp_token *pragma_tok)
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 98f5544..cd17966 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -12319,17 +12319,34 @@ gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
tree expr = *expr_p;
gimple *g;
gimple_seq body = NULL;
+ bool nowait = false;
+ bool has_depend = false;
if (OMP_TASK_BODY (expr) == NULL_TREE)
- for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
- && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
+ {
+ for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
+ {
+ has_depend = true;
+ if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<mutexinoutset%> kind in %<depend%> clause on a "
+ "%<taskwait%> construct");
+ break;
+ }
+ }
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
+ nowait = true;
+ if (nowait && !has_depend)
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "%<mutexinoutset%> kind in %<depend%> clause on a "
- "%<taskwait%> construct");
- break;
+ error_at (EXPR_LOCATION (expr),
+ "%<taskwait%> construct with %<nowait%> clause but no "
+ "%<depend%> clauses");
+ *expr_p = NULL_TREE;
+ return;
}
+ }
gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
omp_find_clause (OMP_TASK_CLAUSES (expr),
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
index cfa6483..ee5213e 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -89,6 +89,9 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT, "GOMP_taskwait",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT_DEPEND, "GOMP_taskwait_depend",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT_DEPEND_NOWAIT,
+ "GOMP_taskwait_depend_nowait",
+ BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKYIELD, "GOMP_taskyield",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKGROUP_START, "GOMP_taskgroup_start",
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index 5729a20..0821b8d 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -916,10 +916,12 @@ expand_taskwait_call (basic_block bb, gomp_task *entry_stmt)
depend = OMP_CLAUSE_DECL (depend);
+ bool nowait = omp_find_clause (clauses, OMP_CLAUSE_NOWAIT) != NULL_TREE;
gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
- tree t
- = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT_DEPEND),
- 1, depend);
+ enum built_in_function f = (nowait
+ ? BUILT_IN_GOMP_TASKWAIT_DEPEND_NOWAIT
+ : BUILT_IN_GOMP_TASKWAIT_DEPEND);
+ tree t = build_call_expr (builtin_decl_explicit (f), 1, depend);
force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
diff --git a/gcc/testsuite/c-c++-common/gomp/taskwait-depend-nowait-1.c b/gcc/testsuite/c-c++-common/gomp/taskwait-depend-nowait-1.c
new file mode 100644
index 0000000..54df023
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/taskwait-depend-nowait-1.c
@@ -0,0 +1,17 @@
+void
+foo (int *p)
+{
+ #pragma omp taskwait depend(iterator(i = 0:16) , in : p[i]) nowait depend(out : p[32])
+}
+
+void
+bar (int *p)
+{
+ #pragma omp taskwait depend(mutexinoutset : p[0]) nowait /* { dg-error "'mutexinoutset' kind in 'depend' clause on a 'taskwait' construct" } */
+}
+
+void
+baz (void)
+{
+ #pragma omp taskwait nowait /* { dg-error "'taskwait' construct with 'nowait' clause but no 'depend' clauses" } */
+}
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index 6334fdc..46d5f10 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -410,6 +410,11 @@ GOMP_5.1 {
GOMP_teams4;
} GOMP_5.0.1;
+GOMP_5.1.1 {
+ global:
+ GOMP_taskwait_depend_nowait;
+} GOMP_5.1;
+
OACC_2.0 {
global:
acc_get_num_devices;
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index 09674a1..84b9f2c 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -305,6 +305,7 @@ extern void GOMP_taskloop_ull (void (*) (void *), void *,
unsigned long long);
extern void GOMP_taskwait (void);
extern void GOMP_taskwait_depend (void **);
+extern void GOMP_taskwait_depend_nowait (void **);
extern void GOMP_taskyield (void);
extern void GOMP_taskgroup_start (void);
extern void GOMP_taskgroup_end (void);
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.
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-nowait-1.c b/libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-nowait-1.c
new file mode 100644
index 0000000..3d1519e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/taskwait-depend-nowait-1.c
@@ -0,0 +1,39 @@
+#ifdef __cplusplus
+extern "C"
+#endif
+void abort (void);
+
+int
+main ()
+{
+ int a[64], b = 1;
+ #pragma omp parallel num_threads (4)
+ #pragma omp single
+ {
+ int i;
+ #pragma omp taskwait depend(in: a) nowait
+ #pragma omp taskwait depend(in: a) nowait
+ #pragma omp taskwait
+ #pragma omp taskgroup
+ {
+ #pragma omp taskwait depend(in: a) nowait
+ #pragma omp taskwait depend(in: a) nowait
+ }
+ for (i = 0; i < 64; ++i)
+ #pragma omp task depend(in: a) shared(a)
+ a[i] = i;
+ #pragma omp taskwait depend(inout: a) nowait
+ for (i = 0; i < 64; ++i)
+ #pragma omp task depend(inoutset: a) shared(a)
+ if (a[i] != i)
+ abort ();
+ else
+ a[i] = 2 * i + 1;
+ #pragma omp taskwait nowait depend(out: a) depend(in: b)
+ #pragma omp taskwait depend(inout: b)
+ for (i = 0; i < 64; ++i)
+ if (a[i] != 2 * i + 1)
+ abort ();
+ }
+ return 0;
+}