BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SCOPE_START, "GOMP_scope_start",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SCOPE_START_WITH_END, "GOMP_scope_start_with_end",
+ BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SCOPE_END, "GOMP_scope_end",
+ BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_OFFLOAD_REGISTER, "GOMP_offload_register_ver",
BT_FN_VOID_UINT_PTR_INT_PTR, ATTR_NOTHROW_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_OFFLOAD_UNREGISTER,
gimple_omp_scope_clauses (scope_stmt),
&bind_body, &tred_dlist);
rclauses = c;
- tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_SCOPE_START);
+ tree fndecl = builtin_decl_explicit (
+ flag_openmp_ompt ? BUILT_IN_GOMP_SCOPE_START_WITH_END
+ : BUILT_IN_GOMP_SCOPE_START);
gimple *stmt = gimple_build_call (fndecl, 1, temp);
gimple_seq_add_stmt (&bind_body, stmt);
}
+ else if (flag_openmp_ompt)
+ {
+ tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_SCOPE_START_WITH_END);
+ gimple *stmt = gimple_build_call (fndecl, 1, null_pointer_node);
+ gimple_seq_add_stmt (&bind_body, stmt);
+ }
lower_rec_input_clauses (gimple_omp_scope_clauses (scope_stmt),
&bind_body, &dlist, ctx, NULL);
bind_body = maybe_catch_exception (bind_body);
+ if (flag_openmp_ompt)
+ {
+ tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_SCOPE_END);
+ gcall *g = gimple_build_call (fndecl, 0);
+ gimple_seq_add_stmt (&bind_body_tail, g);
+ }
+
bool nowait = omp_find_clause (gimple_omp_scope_clauses (scope_stmt),
OMP_CLAUSE_NOWAIT) != NULL_TREE;
gimple *g = gimple_build_omp_return (nowait);
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-ompt -fdump-tree-omplower" } */
+
+/* Check that OMPT variants of libgomp calls are emitted for the scope
+ construct, both with and without a task reduction clause. */
+
+int x;
+
+void
+f1 (void)
+{
+ #pragma omp scope
+ ;
+}
+
+void
+f2 (void)
+{
+#pragma omp scope reduction(task, + : x)
+ ;
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_scope_start_with_end \\(0B\\)" 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_scope_start_with_end \\(D\.\[0-9\]+\\)" 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_scope_end" 2 "omplower" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_scope_start \\(" "omplower" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-omplower" } */
+
+/* Check that a single, non-OMPT variant of libgomp call is emitted for the
+ scope construct, only with a task reduction clause. */
+
+int x;
+
+void
+f1 (void)
+{
+ #pragma omp scope
+ ;
+}
+
+void
+f2 (void)
+{
+ #pragma omp scope reduction(task, +:x)
+ ;
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_scope_start \\(" 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_scope_start_with_end" "omplower" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_scope_end" "omplower" } } */
GOMP_reduction_end;
GOMP_single_start_with_end;
GOMP_single_end;
+ GOMP_scope_start_with_end;
+ GOMP_scope_end;
} GOMP_6.0.1;
OACC_2.0 {
/* scope.c */
extern void GOMP_scope_start (uintptr_t *);
+extern void GOMP_scope_start_with_end (uintptr_t *);
+extern void GOMP_scope_end (void);
/* target.c */
first_reductions);
}
}
+
+/* OMPT variant enabled by -fopenmp-ompt. Called at the beginning of every scope
+ construct even without reduction. */
+
+void
+GOMP_scope_start_with_end (uintptr_t *reductions)
+{
+ if (!reductions)
+ return;
+
+ struct gomp_thread *thr = gomp_thread ();
+
+ gomp_workshare_taskgroup_start ();
+ if (gomp_work_share_start (0))
+ {
+ GOMP_taskgroup_reduction_register (reductions);
+ thr->task->taskgroup->workshare = true;
+ thr->ts.work_share->task_reductions = reductions;
+ gomp_work_share_init_done ();
+ }
+ else
+ {
+ uintptr_t *first_reductions = thr->ts.work_share->task_reductions;
+ gomp_workshare_task_reduction_register (reductions, first_reductions);
+ }
+}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_scope_end (void)
+{}