openmp: Add OMPT variants of GOMP_scope_start GOMP_scope_start is emitted only for task reductions without -fopenmp-ompt (unchanged). With -fopenmp-ompt, both GOMP_scope_start_with_end and GOMP_scope_end are emitted, whether a task reduction is specified or not. gcc/ChangeLog: * omp-builtins.def (BUILT_IN_GOMP_SCOPE_START_WITH_END): New builtin. (BUILT_IN_GOMP_SCOPE_END): Likewise. * omp-low.cc (lower_omp_scope): Emit calls to GOMP_scope_start_with_end and GOMP_scope_end when -fopenmp-ompt. libgomp/ChangeLog: * libgomp.map: Add GOMP_scope_start_with_end and GOMP_scope_end. * libgomp_g.h (GOMP_scope_start_with_end): Declare. (GOMP_scope_end): Likewise. * scope.c (GOMP_scope_start_with_end): New function. (GOMP_scope_end): New stub. gcc/testsuite/ChangeLog: * c-c++-common/gomp/scope-7.c: New test. * c-c++-common/gomp/scope-8.c: New test.
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def index 29b3b72..6b5e231 100644 --- a/gcc/omp-builtins.def +++ b/gcc/omp-builtins.def
@@ -456,6 +456,10 @@ 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,
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index d87b6b6..19ec304 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc
@@ -9035,10 +9035,18 @@ 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); @@ -9068,6 +9076,13 @@ 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);
diff --git a/gcc/testsuite/c-c++-common/gomp/scope-7.c b/gcc/testsuite/c-c++-common/gomp/scope-7.c new file mode 100644 index 0000000..9db2fd1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/scope-7.c
@@ -0,0 +1,26 @@ +/* { 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" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/scope-8.c b/gcc/testsuite/c-c++-common/gomp/scope-8.c new file mode 100644 index 0000000..2a36b1a --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/scope-8.c
@@ -0,0 +1,25 @@ +/* { 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" } } */
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map index 81bad4d..8a59d49 100644 --- a/libgomp/libgomp.map +++ b/libgomp/libgomp.map
@@ -501,6 +501,8 @@ 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 {
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h index be3e349..bc05896 100644 --- a/libgomp/libgomp_g.h +++ b/libgomp/libgomp_g.h
@@ -357,6 +357,8 @@ /* 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 */
diff --git a/libgomp/scope.c b/libgomp/scope.c index df52e47..00a8701 100644 --- a/libgomp/scope.c +++ b/libgomp/scope.c
@@ -60,3 +60,35 @@ 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) +{}