Hi Thomas,
See attached, updated patch and below.
On 08/07/2026 11:09, Thomas Schwinge wrote:
Hi Paul-Antoine!
On 2026-07-07T17:43:14+0200, Paul-Antoine Arras <[email protected]> wrote:
Thanks for the review. See the updated patch in attachment and my
comments below.
Thanks! OK to push with the following items addressed.
--- gcc/common.opt
+++ gcc/common.opt
+fopenmp-ompt
+Common Var(flag_openmp_ompt) EnabledBy(fopenmp-ompt-detailed)
+Emit additional entry points for OMPT before and after OpenMP worksharing
constructs.
Maybe:
Emit additional calls into libgomp, enabling OMPT callbacks before and
after [...]
Amended as suggested.
Is "OpenMP worksharing constructs" a good term for all the items touched
by '-fopenmp-ompt'?
I rephrased as "*some* OpenMP worksharing constructs" and included the
full list of affected constructs in invoke.texi.
+
+fopenmp-ompt-detailed
+Common Var(flag_openmp_ompt_detailed)
+Like -fopenmp-ompt, and also emit OMPT dispatch entry points.
[...], and emit additional calls into libgomp, enabling OMPT dispatch
callbacks.
That way, the user should be able to understand the cost ("additional
calls into libgomp") vs. what they get (additional OMPT callbacks)?
Amended as suggested.
--- gcc/doc/invoke.texi
+++ gcc/doc/invoke.texi
+@opindex fopenmp-ompt
+@opindex fno-openmp-ompt
+@cindex OpenMP OMPT
+@item -fopenmp-ompt
+Emit OMPT entry points around OpenMP worksharing constructs, so that an
+OMPT tool can observe their start and end. Requires @option{-fopenmp}.
+
+@opindex fopenmp-ompt-detailed
+@opindex fno-openmp-ompt-detailed
+@item -fopenmp-ompt-detailed
+Like @option{-fopenmp-ompt}, and additionally emit an OMPT dispatch
+entry point that gets called at the beginning of each workshare chunk.
+Requires @option{-fopenmp}.
Please update similarly to 'gcc/common.opt'.
Does '-fopenmp-ompt-detailed' also need '@cindex OpenMP OMPT'?
I guess it doesn't hurt: added '@cindex OpenMP OMPT detailed'.
I assume you'll have to regenerate 'gcc/common.opt.urls'?
Indeed, I missed that; done now.
Grüße
Thomas
--
PA
From 4f68bd2928925ad96c1c1a6a921efb8779487b1e Mon Sep 17 00:00:00 2001
From: Paul-Antoine Arras <[email protected]>
Date: Tue, 30 Jun 2026 11:06:44 +0200
Subject: [PATCH v3 1/2] openmp: Add OMPT entry points for worksharing-loop,
single, and masked constructs
Add two new compiler flags, -fopenmp-ompt and -fopenmp-ompt-detailed, that
cause the compiler to emit OMPT-aware runtime entry points around OpenMP
worksharing constructs. With -fopenmp-ompt, the _start and _end variants
are called instead of the plain worksharing functions; with
-fopenmp-ompt-detailed, a _dispatch stub is additionally called after the
chunk bounds are computed. New stubs are added to libgomp as placeholders
for future OMPT callback invocations.
gcc/ChangeLog:
* common.opt (fopenmp-ompt): New option.
(fopenmp-ompt-detailed): New option.
* common.opt.urls: Regenerate.
* doc/invoke.texi (Option Summary): Add -fopenmp-ompt and
-fopenmp-ompt-detailed.
(OpenMP and OpenACC Options): Document -fopenmp-ompt and
-fopenmp-ompt-detailed.
* omp-builtins.def (BUILT_IN_GOMP_SINGLE_START_WITH_END): New builtin.
(BUILT_IN_GOMP_SINGLE_END): New builtin.
(BUILT_IN_GOMP_MASKED_END): New builtin.
(BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START): New builtin.
(BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_END): New builtin.
(BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_DISPATCH): New builtin.
(BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START): New builtin.
(BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_END): New builtin.
(BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_DISPATCH): New builtin.
* omp-expand.cc (expand_omp_for_static_nochunk): With -fopenmp-ompt,
emit _start and _end variants instead of the plain worksharing call;
with -fopenmp-ompt-detailed, also emit _dispatch.
(expand_omp_for_static_chunk): Likewise.
* omp-low.cc (lower_omp_single_simple): With -fopenmp-ompt, use
GOMP_single_start_with_end instead of GOMP_single_start.
(lower_omp_single): With -fopenmp-ompt, emit GOMP_single_end.
(lower_omp_master): With -fopenmp-ompt, emit GOMP_masked_end.
* opts.cc (finish_options): Diagnose -fopenmp-ompt and
-fopenmp-ompt-detailed used without -fopenmp.
libgomp/ChangeLog:
* config/gcn/teams.c (GOMP_distribute_static_worksharing_start,
GOMP_distribute_static_worksharing_dispatch,
GOMP_distribute_static_worksharing_end): New functions.
* config/nvptx/teams.c (GOMP_distribute_static_worksharing_start,
GOMP_distribute_static_worksharing_dispatch,
GOMP_distribute_static_worksharing_end): Likewise.
* libgomp.map (GOMP_6.0.2): Export new entry points.
* libgomp_g.h: Add prototypes for GOMP_loop_static_worksharing,
GOMP_loop_static_worksharing_start, GOMP_loop_static_worksharing_dispatch,
GOMP_loop_static_worksharing_end, GOMP_has_masked_thread_num,
GOMP_masked_end, GOMP_single_start_with_end, GOMP_single_end,
GOMP_distribute_static_worksharing_start,
GOMP_distribute_static_worksharing_dispatch, and
GOMP_distribute_static_worksharing_end.
* loop.c (GOMP_loop_static_worksharing): Move here from parallel.c.
(GOMP_loop_static_worksharing_start): New function.
(GOMP_loop_static_worksharing_dispatch): New stub.
(GOMP_loop_static_worksharing_end): New stub.
(GOMP_has_masked_thread_num): Move here from parallel.c.
(GOMP_masked_end): New stub.
* parallel.c (GOMP_loop_static_worksharing): Move to loop.c.
(GOMP_has_masked_thread_num): Move to loop.c.
* single.c (GOMP_single_start_with_end): New function.
(GOMP_single_end): New stub.
(GOMP_single_copy_start): Fix trailing whitespace.
* teams.c (GOMP_distribute_static_worksharing_start): New function.
(GOMP_distribute_static_worksharing_dispatch): New stub.
(GOMP_distribute_static_worksharing_end): New stub.
* testsuite/libgomp.c-c++-common/for-static-1.c: New test.
* testsuite/libgomp.c-c++-common/for-static-2.c: New test.
* testsuite/libgomp.c-c++-common/for-static-3.c: New test.
* testsuite/libgomp.c-c++-common/for-static.h: New test.
gcc/testsuite/ChangeLog:
* c-c++-common/gomp/masked-1.c: Add scan-tree-dump-not check that
GOMP_masked_end is not emitted without -fopenmp-ompt.
* c-c++-common/gomp/for-8.c: Remove; superseded by for-static-*.c.
* c-c++-common/gomp/for-static-1.c: New test; checks that the plain
worksharing builtins are emitted without -fopenmp-ompt.
* c-c++-common/gomp/for-static-2.c: New test; checks that _start and
_end variants are emitted with -fopenmp-ompt.
* c-c++-common/gomp/for-static-3.c: New test; checks that _dispatch is
also emitted with -fopenmp-ompt-detailed.
* c-c++-common/gomp/for-static.h: New shared test header.
* c-c++-common/gomp/masked-3.c: New test for GOMP_masked_end emission
with -fopenmp-ompt.
* c-c++-common/gomp/openmp-ompt-1.c: New test; checks that
-fopenmp-ompt without -fopenmp is diagnosed.
* c-c++-common/gomp/openmp-ompt-2.c: New test; checks that
-fopenmp-ompt-detailed without -fopenmp is diagnosed.
* c-c++-common/gomp/single2.c: New test for GOMP_single_start_with_end
and GOMP_single_end emission with -fopenmp-ompt.
---
gcc/common.opt | 8 ++
gcc/common.opt.urls | 6 +
gcc/doc/invoke.texi | 21 +++-
gcc/omp-builtins.def | 25 ++++
gcc/omp-expand.cc | 111 +++++++++++++++++-
gcc/omp-low.cc | 21 +++-
gcc/opts.cc | 6 +
gcc/testsuite/c-c++-common/gomp/for-8.c | 67 -----------
.../c-c++-common/gomp/for-static-1.c | 17 +++
.../c-c++-common/gomp/for-static-2.c | 15 +++
.../c-c++-common/gomp/for-static-3.c | 14 +++
gcc/testsuite/c-c++-common/gomp/for-static.h | 51 ++++++++
gcc/testsuite/c-c++-common/gomp/masked-1.c | 1 +
gcc/testsuite/c-c++-common/gomp/masked-3.c | 15 +++
.../c-c++-common/gomp/openmp-ompt-1.c | 4 +
.../c-c++-common/gomp/openmp-ompt-2.c | 4 +
gcc/testsuite/c-c++-common/gomp/single2.c | 13 ++
libgomp/config/gcn/teams.c | 23 ++++
libgomp/config/nvptx/teams.c | 21 ++++
libgomp/libgomp.map | 9 ++
libgomp/libgomp_g.h | 12 +-
libgomp/loop.c | 35 ++++++
libgomp/parallel.c | 18 +--
libgomp/single.c | 33 +++++-
libgomp/teams.c | 23 ++++
.../libgomp.c-c++-common/for-static-1.c | 13 ++
.../libgomp.c-c++-common/for-static-2.c | 11 ++
.../libgomp.c-c++-common/for-static-3.c | 11 ++
.../libgomp.c-c++-common/for-static.h | 37 ++++++
29 files changed, 556 insertions(+), 89 deletions(-)
delete mode 100644 gcc/testsuite/c-c++-common/gomp/for-8.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/for-static-1.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/for-static-2.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/for-static-3.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/for-static.h
create mode 100644 gcc/testsuite/c-c++-common/gomp/masked-3.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/openmp-ompt-1.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/openmp-ompt-2.c
create mode 100644 gcc/testsuite/c-c++-common/gomp/single2.c
create mode 100644 libgomp/testsuite/libgomp.c-c++-common/for-static-1.c
create mode 100644 libgomp/testsuite/libgomp.c-c++-common/for-static-2.c
create mode 100644 libgomp/testsuite/libgomp.c-c++-common/for-static-3.c
create mode 100644 libgomp/testsuite/libgomp.c-c++-common/for-static.h
diff --git a/gcc/common.opt b/gcc/common.opt
index 218dddf5dfe..148d0ac3d17 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2503,6 +2503,14 @@ fomit-frame-pointer
Common Var(flag_omit_frame_pointer) Optimization
When possible do not generate stack frames.
+fopenmp-ompt
+Common Var(flag_openmp_ompt) EnabledBy(fopenmp-ompt-detailed)
+Emit additional calls into libgomp, enabling OMPT callbacks before and after some OpenMP worksharing constructs.
+
+fopenmp-ompt-detailed
+Common Var(flag_openmp_ompt_detailed)
+Like -fopenmp-ompt, and emit additional calls into libgomp, enabling OMPT dispatch callbacks.
+
fopenmp-target-simd-clone
Common Alias(fopenmp-target-simd-clone=,any,none)
diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index 490146dde8c..567a8dfc2d6 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -1336,6 +1336,12 @@ UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-foffload-options)
fomit-frame-pointer
UrlSuffix(gcc/Optimize-Options.html#index-fno-omit-frame-pointer)
+fopenmp-ompt
+UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fno-openmp-ompt)
+
+fopenmp-ompt-detailed
+UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fno-openmp-ompt-detailed)
+
fopenmp-target-simd-clone
UrlSuffix(gcc/OpenMP-and-OpenACC-Options.html#index-fno-openmp-target-simd-clone)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4fbd25e49dd..925ae7edd26 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -323,7 +323,8 @@ Objective-C and Objective-C++ Dialects}.
@xref{OpenMP and OpenACC Options,,Options Controlling OpenMP and OpenACC}.
@gccoptlist{-foffload=@var{arg} -foffload-options=@var{arg}
-fopenacc -fopenacc-dim=@var{geom}
--fopenmp -fopenmp-simd -fopenmp-target-simd-clone@r{[}=@var{device-type}@r{]}}
+-fopenmp -fopenmp-simd -fopenmp-ompt -fopenmp-ompt-detailed
+-fopenmp-target-simd-clone@r{[}=@var{device-type}@r{]}}
@item Diagnostic Message Formatting Options
@xref{Diagnostic Message Formatting Options,,Options to Control Diagnostic Messages Formatting}.
@@ -5600,6 +5601,24 @@ Fortran. In fixed source form Fortran, the sentinels can also start with
@option{-fopenmp} is additionally specified, the @code{loop} region binds
to the current task region, independent of the specified @code{bind} clause.
+@opindex fopenmp-ompt
+@opindex fno-openmp-ompt
+@cindex OpenMP OMPT
+@item -fopenmp-ompt
+Emit additional calls into libgomp, enabling OMPT callbacks around some OpenMP
+worksharing constructs (namely statically scheduled @code{for} and
+@code{distribute}, @code{single}, @code{masked} and @code{master}), so that an
+OMPT tool can observe their start and end. Requires @option{-fopenmp}.
+
+@opindex fopenmp-ompt-detailed
+@opindex fno-openmp-ompt-detailed
+@cindex OpenMP OMPT detailed
+@item -fopenmp-ompt-detailed
+Like @option{-fopenmp-ompt}, and additionally emit calls into libgomp, enabling
+OMPT dispatch callbacks that get called at the beginning of each workshare chunk
+for statically scheduled @code{for} and @code{distribute}. Requires
+@option{-fopenmp}.
+
@opindex fopenmp-target-simd-clone
@opindex fno-openmp-target-simd-clone
@cindex OpenMP target SIMD clone
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
index d7440a42761..465aeebefdb 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -445,6 +445,11 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END_NOWAIT,
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_START, "GOMP_single_start",
BT_FN_BOOL, ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_START_WITH_END,
+ "GOMP_single_start_with_end", BT_FN_BOOL,
+ ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_END, "GOMP_single_end", BT_FN_VOID,
+ ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_START, "GOMP_single_copy_start",
BT_FN_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_END, "GOMP_single_copy_end",
@@ -503,9 +508,29 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ERROR, "GOMP_error",
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_HAS_MASKED_THREAD_NUM,
"GOMP_has_masked_thread_num", BT_FN_BOOL_INT,
ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_MASKED_END, "GOMP_masked_end", BT_FN_VOID,
+ ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING,
"GOMP_loop_static_worksharing", BT_FN_COMPLEX_INT,
ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START,
+ "GOMP_loop_static_worksharing_start", BT_FN_COMPLEX_INT,
+ ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_END,
+ "GOMP_loop_static_worksharing_end", BT_FN_VOID,
+ ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_DISPATCH,
+ "GOMP_loop_static_worksharing_dispatch", BT_FN_VOID,
+ ATTR_NOTHROW_LEAF_LIST)
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING,
"GOMP_distribute_static_worksharing", BT_FN_COMPLEX_INT,
ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START,
+ "GOMP_distribute_static_worksharing_start", BT_FN_COMPLEX_INT,
+ ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_END,
+ "GOMP_distribute_static_worksharing_end", BT_FN_VOID,
+ ATTR_NOTHROW_LEAF_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_DISPATCH,
+ "GOMP_distribute_static_worksharing_dispatch", BT_FN_VOID,
+ ATTR_NOTHROW_LEAF_LIST)
diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc
index 3d799d28032..ad380b27d06 100644
--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -5201,10 +5201,14 @@ expand_omp_for_static_nochunk (struct omp_region *region,
switch (gimple_omp_for_kind (fd->for_stmt))
{
case GF_OMP_FOR_KIND_FOR:
- decl = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
+ decl = builtin_decl_explicit (
+ flag_openmp_ompt ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START
+ : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
- decl = builtin_decl_explicit (BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
+ decl = builtin_decl_explicit (
+ flag_openmp_ompt ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START
+ : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
break;
default:
gcc_unreachable ();
@@ -5576,8 +5580,53 @@ expand_omp_for_static_nochunk (struct omp_region *region,
cont_bb, body_bb);
}
- /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
+ if (flag_openmp_ompt_detailed)
+ {
+ /* Insert call to GOMP_*_static_worksharing_dispatch at the end of
+ seq_start_bb. */
+ gsi = gsi_last_nondebug_bb (seq_start_bb);
+ tree decl;
+ switch (gimple_omp_for_kind (fd->for_stmt))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ decl = builtin_decl_explicit (
+ BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_DISPATCH);
+ break;
+ case GF_OMP_FOR_KIND_DISTRIBUTE:
+ decl = builtin_decl_explicit (
+ BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_DISPATCH);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ gcall *g = gimple_build_call (decl, 0);
+ gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+ }
+
gsi = gsi_last_nondebug_bb (exit_bb);
+ if (flag_openmp_ompt)
+ {
+ /* Insert call to GOMP_*_static_worksharing_end at the end of exit_bb.
+ */
+ tree decl;
+ switch (gimple_omp_for_kind (fd->for_stmt))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ decl
+ = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_END);
+ break;
+ case GF_OMP_FOR_KIND_DISTRIBUTE:
+ decl = builtin_decl_explicit (
+ BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_END);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ gcall *g = gimple_build_call (decl, 0);
+ gsi_insert_after (&gsi, g, GSI_SAME_STMT);
+ }
+
+ /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
{
t = gimple_omp_return_lhs (gsi_stmt (gsi));
@@ -5646,6 +5695,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
exit3_bb = split_block (exit2_bb, g)->dest;
gsi = gsi_after_labels (exit3_bb);
}
+
gsi_remove (&gsi, true);
/* Connect all the blocks. */
@@ -5969,10 +6019,14 @@ expand_omp_for_static_chunk (struct omp_region *region,
switch (gimple_omp_for_kind (fd->for_stmt))
{
case GF_OMP_FOR_KIND_FOR:
- decl = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
+ decl = builtin_decl_explicit (
+ flag_openmp_ompt ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START
+ : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING);
break;
case GF_OMP_FOR_KIND_DISTRIBUTE:
- decl = builtin_decl_explicit (BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
+ decl = builtin_decl_explicit (
+ flag_openmp_ompt ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START
+ : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING);
break;
default:
gcc_unreachable ();
@@ -6303,8 +6357,30 @@ expand_omp_for_static_chunk (struct omp_region *region,
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
}
- /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
gsi = gsi_last_nondebug_bb (exit_bb);
+ if (flag_openmp_ompt)
+ {
+ /* Insert call to GOMP_*_static_worksharing_end at the end of exit_bb.
+ */
+ tree decl;
+ switch (gimple_omp_for_kind (fd->for_stmt))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ decl
+ = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_END);
+ break;
+ case GF_OMP_FOR_KIND_DISTRIBUTE:
+ decl = builtin_decl_explicit (
+ BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_END);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ gcall *g = gimple_build_call (decl, 0);
+ gsi_insert_after (&gsi, g, GSI_SAME_STMT);
+ }
+
+ /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
{
t = gimple_omp_return_lhs (gsi_stmt (gsi));
@@ -6340,6 +6416,29 @@ expand_omp_for_static_chunk (struct omp_region *region,
}
gsi_remove (&gsi, true);
+ if (flag_openmp_ompt_detailed)
+ {
+ /* Insert call to GOMP_*_static_worksharing_dispatch at the end of
+ seq_start_bb. */
+ gsi = gsi_last_nondebug_bb (seq_start_bb);
+ tree decl;
+ switch (gimple_omp_for_kind (fd->for_stmt))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ decl = builtin_decl_explicit (
+ BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_DISPATCH);
+ break;
+ case GF_OMP_FOR_KIND_DISTRIBUTE:
+ decl = builtin_decl_explicit (
+ BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_DISPATCH);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ gcall *g = gimple_build_call (decl, 0);
+ gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+ }
+
/* Connect the new blocks. */
find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index dbdbc4079f4..50da8581a8d 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -8786,7 +8786,9 @@ lower_omp_single_simple (gomp_single *single_stmt, gimple_seq *pre_p)
gimple *call, *cond;
tree lhs, decl;
- decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
+ decl = builtin_decl_explicit (flag_openmp_ompt
+ ? BUILT_IN_GOMP_SINGLE_START_WITH_END
+ : BUILT_IN_GOMP_SINGLE_START);
lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)));
call = gimple_build_call (decl, 0);
gimple_call_set_lhs (call, lhs);
@@ -8923,6 +8925,15 @@ lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple *g = gimple_build_omp_return (nowait);
gimple_seq_add_stmt (&bind_body_tail, g);
maybe_add_implicit_barrier_cancel (ctx, g, &bind_body_tail);
+
+ if (flag_openmp_ompt && !ctx->record_type)
+ {
+ /* Insert call to GOMP_single_end. */
+ tree decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_END);
+ gimple *stmt = gimple_build_call (decl, 0);
+ gimple_seq_add_stmt (&bind_body_tail, stmt);
+ }
+
if (ctx->record_type)
{
gimple_stmt_iterator gsi = gsi_start (bind_body_tail);
@@ -9099,6 +9110,14 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
+ if (flag_openmp_ompt)
+ {
+ /* Insert call to GOMP_masked_end at the end of the body. */
+ tree decl = builtin_decl_explicit (BUILT_IN_GOMP_MASKED_END);
+ gcall *g = gimple_build_call (decl, 0);
+ gimple_bind_add_stmt (bind, g);
+ }
+
gimple_bind_add_stmt (bind, gimple_build_label (lab));
gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 342517528e8..3dae57af0b4 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -1538,6 +1538,12 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
" %<-fstrict-flex-arrays%> is not present");
}
+ if ((opts->x_flag_openmp_ompt || opts->x_flag_openmp_ompt_detailed)
+ && !opts->x_flag_openmp)
+ error_at (
+ loc,
+ "%<-fopenmp-ompt%> and %<-fopenmp-ompt-detailed%> require %<-fopenmp%>");
+
diagnose_options (opts, opts_set, loc);
}
diff --git a/gcc/testsuite/c-c++-common/gomp/for-8.c b/gcc/testsuite/c-c++-common/gomp/for-8.c
deleted file mode 100644
index a894aaaaed1..00000000000
--- a/gcc/testsuite/c-c++-common/gomp/for-8.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* { dg-do compile } */
-/* { dg-additional-options "-fdump-tree-ompexp" } */
-
-/* Check that the static loop and distribute expanders fetch the thread/team
- id and count through a single GOMP_loop_static_worksharing /
- GOMP_distribute_static_worksharing call rather than separate
- omp_get_thread_num/omp_get_num_threads or omp_get_team_num/omp_get_num_teams
- calls. */
-
-void bar (int);
-
-/* Static schedule without a chunk size goes through
- expand_omp_for_static_nochunk. */
-
-void
-f1 (int n)
-{
- int i;
- #pragma omp for schedule(static)
- for (i = 0; i < n; ++i)
- bar (i);
-}
-
-/* Static schedule with a chunk size goes through
- expand_omp_for_static_chunk. */
-
-void
-f2 (int n)
-{
- int i;
- #pragma omp for schedule(static, 4)
- for (i = 0; i < n; ++i)
- bar (i);
-}
-
-/* Distribute without a chunk size goes through
- expand_omp_for_static_nochunk. */
-
-void
-f3 (int n)
-{
- int i;
-#pragma omp teams
-#pragma omp distribute
- for (i = 0; i < n; ++i)
- bar (i);
-}
-
-/* Distribute with a chunk size goes through
- expand_omp_for_static_chunk. */
-
-void
-f4 (int n)
-{
- int i;
-#pragma omp teams
-#pragma omp distribute dist_schedule(static, 4)
- for (i = 0; i < n; ++i)
- bar (i);
-}
-
-/* { dg-final { scan-tree-dump "GOMP_loop_static_worksharing" "ompexp" } } */
-/* { dg-final { scan-tree-dump "GOMP_distribute_static_worksharing" "ompexp" } } */
-/* { dg-final { scan-tree-dump-not "omp_get_num_threads" "ompexp" } } */
-/* { dg-final { scan-tree-dump-not "omp_get_thread_num" "ompexp" } } */
-/* { dg-final { scan-tree-dump-not "omp_get_num_teams" "ompexp" } } */
-/* { dg-final { scan-tree-dump-not "omp_get_team_num" "ompexp" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/for-static-1.c b/gcc/testsuite/c-c++-common/gomp/for-static-1.c
new file mode 100644
index 00000000000..50d4e176f3d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/for-static-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-ompexp" } */
+
+/* Check that the static loop and distribute expanders fetch the thread/team
+ id and count through a single GOMP_loop_static_worksharing /
+ GOMP_distribute_static_worksharing call rather than separate
+ omp_get_thread_num/omp_get_num_threads or omp_get_team_num/omp_get_num_teams
+ calls. */
+
+#include "for-static.h"
+
+/* { dg-final { scan-tree-dump-times "GOMP_loop_static_worksharing \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_distribute_static_worksharing \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "omp_get_num_threads" "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "omp_get_thread_num" "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "omp_get_num_teams" "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "omp_get_team_num" "ompexp" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/for-static-2.c b/gcc/testsuite/c-c++-common/gomp/for-static-2.c
new file mode 100644
index 00000000000..c3d25b97bed
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/for-static-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-ompt -fdump-tree-ompexp" } */
+
+/* Check that, with -fopenmp-ompt, the _start and _end variants are called. */
+
+#include "for-static.h"
+
+/* { dg-final { scan-tree-dump-times "GOMP_loop_static_worksharing_start \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_static_worksharing_end \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_distribute_static_worksharing_start \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_distribute_static_worksharing_end \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_loop_static_worksharing \\(" "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_loop_static_worksharing_dispatch" "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_distribute_static_worksharing \\(" "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_distribute_static_worksharing_dispatch" "ompexp" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/for-static-3.c b/gcc/testsuite/c-c++-common/gomp/for-static-3.c
new file mode 100644
index 00000000000..6fd1da6c407
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/for-static-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-ompt-detailed -fdump-tree-ompexp" } */
+
+/* Check that, with -fopenmp-ompt-detailed, _dispatch builtins are called along
+ with the _start and _end variants. */
+
+#include "for-static.h"
+
+/* { dg-final { scan-tree-dump-times "GOMP_loop_static_worksharing_start \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_static_worksharing_dispatch \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_loop_static_worksharing_end \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_distribute_static_worksharing_start \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_distribute_static_worksharing_dispatch \\(" 2 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_distribute_static_worksharing_end \\(" 2 "ompexp" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/for-static.h b/gcc/testsuite/c-c++-common/gomp/for-static.h
new file mode 100644
index 00000000000..6504c75a13e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/for-static.h
@@ -0,0 +1,51 @@
+void bar (int);
+
+/* Static schedule without a chunk size goes through
+ expand_omp_for_static_nochunk. */
+
+void
+f1 (int n)
+{
+ int i;
+ #pragma omp for schedule(static)
+ for (i = 0; i < n; ++i)
+ bar (i);
+}
+
+/* Static schedule with a chunk size goes through
+ expand_omp_for_static_chunk. */
+
+void
+f2 (int n)
+{
+ int i;
+ #pragma omp for schedule(static, 4)
+ for (i = 0; i < n; ++i)
+ bar (i);
+}
+
+/* Distribute without a chunk size goes through
+ expand_omp_for_static_nochunk. */
+
+void
+f3 (int n)
+{
+ int i;
+#pragma omp teams
+#pragma omp distribute
+ for (i = 0; i < n; ++i)
+ bar (i);
+}
+
+/* Distribute with a chunk size goes through
+ expand_omp_for_static_chunk. */
+
+void
+f4 (int n)
+{
+ int i;
+#pragma omp teams
+#pragma omp distribute dist_schedule(static, 4)
+ for (i = 0; i < n; ++i)
+ bar (i);
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/masked-1.c b/gcc/testsuite/c-c++-common/gomp/masked-1.c
index 8de87b551e3..28d2735d96e 100644
--- a/gcc/testsuite/c-c++-common/gomp/masked-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/masked-1.c
@@ -26,4 +26,5 @@ foo (int x, int *a)
}
/* { dg-final { scan-tree-dump "GOMP_has_masked_thread_num" "omplower" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_masked_end" "omplower" } } */
/* { dg-final { scan-tree-dump-not "omp_get_thread_num" "omplower" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/masked-3.c b/gcc/testsuite/c-c++-common/gomp/masked-3.c
new file mode 100644
index 00000000000..adea59fdb69
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/masked-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-ompt -fdump-tree-omplower" } */
+
+void bar (void);
+
+void
+foo (void)
+{
+ #pragma omp masked
+ bar ();
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_has_masked_thread_num" 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_masked_end" 1 "omplower" } } */
+/* { dg-final { scan-tree-dump-not "omp_get_thread_num" "omplower" } } */
diff --git a/gcc/testsuite/c-c++-common/gomp/openmp-ompt-1.c b/gcc/testsuite/c-c++-common/gomp/openmp-ompt-1.c
new file mode 100644
index 00000000000..0a45c2bd52c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/openmp-ompt-1.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-ompt" } */
+
+/* { dg-error ".-fopenmp-ompt. and .-fopenmp-ompt-detailed. require .-fopenmp." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/gomp/openmp-ompt-2.c b/gcc/testsuite/c-c++-common/gomp/openmp-ompt-2.c
new file mode 100644
index 00000000000..f93f6920327
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/openmp-ompt-2.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-ompt-detailed" } */
+
+/* { dg-error ".-fopenmp-ompt. and .-fopenmp-ompt-detailed. require .-fopenmp." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/c-c++-common/gomp/single2.c b/gcc/testsuite/c-c++-common/gomp/single2.c
new file mode 100644
index 00000000000..215f0368ce4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/single2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-ompt -fdump-tree-ompexp" } */
+
+void
+foo (void)
+{
+ #pragma omp single
+ ;
+}
+
+/* { dg-final { scan-tree-dump-times "GOMP_single_start_with_end" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-times "GOMP_single_end" 1 "ompexp" } } */
+/* { dg-final { scan-tree-dump-not "GOMP_single_start \\(" "ompexp" } } */
diff --git a/libgomp/config/gcn/teams.c b/libgomp/config/gcn/teams.c
index 5aa8b15502a..99f807ac876 100644
--- a/libgomp/config/gcn/teams.c
+++ b/libgomp/config/gcn/teams.c
@@ -50,6 +50,29 @@ GOMP_distribute_static_worksharing (void)
return nteams + tid * 1I;
}
+/* OMPT variant enabled by -fopenmp-ompt. */
+
+_Complex int
+GOMP_distribute_static_worksharing_start (void)
+{
+ int __lds *gomp_team_num = (int __lds *) GOMP_TEAM_NUM;
+ unsigned tid = *gomp_team_num;
+ unsigned nteams = gomp_num_teams_var + 1;
+ return nteams + tid * 1I;
+}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt-detailed. */
+
+void
+GOMP_distribute_static_worksharing_dispatch (void)
+{}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_distribute_static_worksharing_end (void)
+{}
+
int
omp_get_num_teams (void)
{
diff --git a/libgomp/config/nvptx/teams.c b/libgomp/config/nvptx/teams.c
index 9763f6f4108..3e6ea287276 100644
--- a/libgomp/config/nvptx/teams.c
+++ b/libgomp/config/nvptx/teams.c
@@ -52,6 +52,27 @@ GOMP_distribute_static_worksharing (void)
return nteams + tid * 1I;
}
+/* OMPT variant enabled by -fopenmp-ompt. */
+
+_Complex int
+GOMP_distribute_static_worksharing_start (void)
+{
+ unsigned tid = __gomp_team_num;
+ unsigned nteams = gomp_num_teams_var + 1;
+ return nteams + tid * 1I;
+}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt-detailed. */
+
+void
+GOMP_distribute_static_worksharing_dispatch (void)
+{}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_distribute_static_worksharing_end (void)
+{}
int
omp_get_num_teams (void)
{
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index e2985347bf7..3f465cc1491 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -485,12 +485,21 @@ GOMP_6.0.1 {
GOMP_6.0.2 {
global:
GOMP_has_masked_thread_num;
+ GOMP_masked_end;
GOMP_loop_static_worksharing;
+ GOMP_loop_static_worksharing_start;
+ GOMP_loop_static_worksharing_dispatch;
+ GOMP_loop_static_worksharing_end;
GOMP_distribute_static_worksharing;
+ GOMP_distribute_static_worksharing_start;
+ GOMP_distribute_static_worksharing_dispatch;
+ GOMP_distribute_static_worksharing_end;
GOMP_barrier_ext;
GOMP_barrier_cancel_ext;
GOMP_reduction_start;
GOMP_reduction_end;
+ GOMP_single_start_with_end;
+ GOMP_single_end;
} GOMP_6.0.1;
OACC_2.0 {
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index a3097d5b093..4a3565684cc 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -144,6 +144,11 @@ extern void GOMP_loop_end (void);
extern void GOMP_loop_end_nowait (void);
extern bool GOMP_loop_end_cancel (void);
+extern __complex__ int GOMP_loop_static_worksharing (void);
+extern __complex__ int GOMP_loop_static_worksharing_start (void);
+extern void GOMP_loop_static_worksharing_dispatch (void);
+extern void GOMP_loop_static_worksharing_end (void);
+
/* loop_ull.c */
extern bool GOMP_loop_ull_static_start (bool, unsigned long long,
@@ -298,7 +303,7 @@ extern unsigned GOMP_parallel_reductions (void (*) (void *), void *, unsigned,
extern bool GOMP_cancel (int, bool);
extern bool GOMP_cancellation_point (int);
extern bool GOMP_has_masked_thread_num (int);
-extern __complex__ int GOMP_loop_static_worksharing (void);
+extern void GOMP_masked_end (void);
/* task.c */
@@ -339,6 +344,8 @@ extern bool GOMP_sections_end_cancel (void);
/* single.c */
extern bool GOMP_single_start (void);
+extern bool GOMP_single_start_with_end (void);
+extern void GOMP_single_end (void);
extern void *GOMP_single_copy_start (void);
extern void GOMP_single_copy_end (void *);
@@ -380,6 +387,9 @@ extern void *GOMP_target_map_indirect_ptr (void *);
extern void GOMP_teams_reg (void (*) (void *), void *, unsigned, unsigned,
unsigned);
extern __complex__ int GOMP_distribute_static_worksharing (void);
+extern __complex__ int GOMP_distribute_static_worksharing_start (void);
+extern void GOMP_distribute_static_worksharing_dispatch (void);
+extern void GOMP_distribute_static_worksharing_end (void);
/* allocator.c */
diff --git a/libgomp/loop.c b/libgomp/loop.c
index e3fbeb1c4de..f286ce6b6db 100644
--- a/libgomp/loop.c
+++ b/libgomp/loop.c
@@ -1186,3 +1186,38 @@ GOMP_loop_ordered_guided_next (long *istart, long *iend)
return gomp_loop_ordered_guided_next (istart, iend);
}
#endif
+
+/* For a worksharing-loop construct with static schedule, return the thread ID
+ and number of threads packed into a single complex value. */
+
+_Complex int
+GOMP_loop_static_worksharing (void)
+{
+ struct gomp_team *team = gomp_thread ()->ts.team;
+ unsigned tid = gomp_thread ()->ts.team_id;
+ unsigned nthreads = team ? team->nthreads : 1;
+ return nthreads + tid * 1I;
+}
+
+/* OMPT variant enabled by -fopenmp-ompt. */
+
+_Complex int
+GOMP_loop_static_worksharing_start (void)
+{
+ struct gomp_team *team = gomp_thread ()->ts.team;
+ unsigned tid = gomp_thread ()->ts.team_id;
+ unsigned nthreads = team ? team->nthreads : 1;
+ return nthreads + tid * 1I;
+}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt-detailed. */
+
+void
+GOMP_loop_static_worksharing_dispatch (void)
+{}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_loop_static_worksharing_end (void)
+{}
diff --git a/libgomp/parallel.c b/libgomp/parallel.c
index 92472ecb4f0..bb522b39ecb 100644
--- a/libgomp/parallel.c
+++ b/libgomp/parallel.c
@@ -271,18 +271,6 @@ GOMP_cancel (int which, bool do_cancel)
return true;
}
-/* For a worksharing-loop construct with static schedule, return the thread ID
- and number of threads packed into a single complex value. */
-
-_Complex int
-GOMP_loop_static_worksharing (void)
-{
- struct gomp_team *team = gomp_thread ()->ts.team;
- unsigned tid = gomp_thread ()->ts.team_id;
- unsigned nthreads = team ? team->nthreads : 1;
- return nthreads + tid * 1I;
-}
-
/* Return true if the current thread number equals TID.
Used to implement the masked construct's filter clause. */
@@ -291,6 +279,12 @@ GOMP_has_masked_thread_num (int tid)
{
return tid == gomp_thread ()->ts.team_id;
}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_masked_end (void)
+{}
/* The public OpenMP API for thread and team related inquiries. */
diff --git a/libgomp/single.c b/libgomp/single.c
index 65126000ea9..00a84e1c9c1 100644
--- a/libgomp/single.c
+++ b/libgomp/single.c
@@ -55,6 +55,37 @@ GOMP_single_start (void)
#endif
}
+/* OMPT variant enabled by -fopenmp-ompt. */
+
+bool
+GOMP_single_start_with_end (void)
+{
+#ifdef HAVE_SYNC_BUILTINS
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+ unsigned long single_count;
+
+ if (__builtin_expect (team == NULL, 0))
+ return true;
+
+ single_count = thr->ts.single_count++;
+ return __sync_bool_compare_and_swap (&team->single_count, single_count,
+ single_count + 1L);
+#else
+ bool ret = gomp_work_share_start (0);
+ if (ret)
+ gomp_work_share_init_done ();
+ gomp_work_share_end_nowait ();
+ return ret;
+#endif
+}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_single_end (void)
+{}
+
/* This routine is called when first encountering a SINGLE construct that
does have a COPYPRIVATE clause. Returns NULL if this is the thread
that should execute the clause; otherwise the return value is pointer
@@ -69,7 +100,7 @@ GOMP_single_copy_start (void)
void *ret;
first = gomp_work_share_start (0);
-
+
if (first)
{
gomp_work_share_init_done ();
diff --git a/libgomp/teams.c b/libgomp/teams.c
index 7038623b2df..f501123d647 100644
--- a/libgomp/teams.c
+++ b/libgomp/teams.c
@@ -70,6 +70,29 @@ GOMP_distribute_static_worksharing (void)
return nteams + tid * 1I;
}
+/* OMPT variant enabled by -fopenmp-ompt. */
+
+_Complex int
+GOMP_distribute_static_worksharing_start (void)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ unsigned tid = thr->team_num;
+ unsigned nteams = thr->num_teams + 1;
+ return nteams + tid * 1I;
+}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt-detailed. */
+
+void
+GOMP_distribute_static_worksharing_dispatch (void)
+{}
+
+/* Stub for OMPT callback enabled by -fopenmp-ompt. */
+
+void
+GOMP_distribute_static_worksharing_end (void)
+{}
+
int
omp_get_num_teams (void)
{
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-static-1.c b/libgomp/testsuite/libgomp.c-c++-common/for-static-1.c
new file mode 100644
index 00000000000..b304c8c10ec
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-static-1.c
@@ -0,0 +1,13 @@
+/* { dg-do link { target offload_target_any } } */
+/* { dg-additional-options "-O0 -foffload=-fdump-tree-optimized" } */
+
+/* Check that the static distribute expanders fetch the team id and count
+ through a single GOMP_distribute_static_worksharing call rather than separate
+ omp_get_team_num and omp_get_num_teams calls, and that this function exists
+ on the target side. */
+
+#include "for-static.h"
+
+/* { dg-final { scan-offload-tree-dump-times "GOMP_distribute_static_worksharing \\(" 2 "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-not "omp_get_num_teams" "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-not "omp_get_team_num" "optimized" } } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-static-2.c b/libgomp/testsuite/libgomp.c-c++-common/for-static-2.c
new file mode 100644
index 00000000000..83e577a3298
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-static-2.c
@@ -0,0 +1,11 @@
+/* { dg-do link { target offload_target_any } } */
+/* { dg-additional-options "-O0 -foffload=-fdump-tree-optimized -fopenmp-ompt" } */
+
+/* Check that, with -fopenmp-ompt, the _start and _end variants are called. */
+
+#include "for-static.h"
+
+/* { dg-final { scan-offload-tree-dump-times "GOMP_distribute_static_worksharing_start \\(" 2 "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-times "GOMP_distribute_static_worksharing_end \\(" 2 "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-not "GOMP_distribute_static_worksharing \\(" "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-not "GOMP_distribute_static_worksharing_dispatch" "optimized" } } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-static-3.c b/libgomp/testsuite/libgomp.c-c++-common/for-static-3.c
new file mode 100644
index 00000000000..e7b904eedc3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-static-3.c
@@ -0,0 +1,11 @@
+/* { dg-do link { target offload_target_any } } */
+/* { dg-additional-options "-O0 -foffload=-fdump-tree-optimized -fopenmp-ompt-detailed" } */
+
+/* Check that, with -fopenmp-ompt-detailed, _dispatch builtins are called along
+ with the _start and _end variants. */
+
+#include "for-static.h"
+
+/* { dg-final { scan-offload-tree-dump-times "GOMP_distribute_static_worksharing_start \\(" 2 "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-times "GOMP_distribute_static_worksharing_dispatch \\(" 2 "optimized" } } */
+/* { dg-final { scan-offload-tree-dump-times "GOMP_distribute_static_worksharing_end \\(" 2 "optimized" } } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/for-static.h b/libgomp/testsuite/libgomp.c-c++-common/for-static.h
new file mode 100644
index 00000000000..a6c0e055b83
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/for-static.h
@@ -0,0 +1,37 @@
+void bar (int a)
+{}
+
+/* Distribute without a chunk size goes through
+ expand_omp_for_static_nochunk. */
+
+void
+f3 (int n)
+{
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute
+ for (i = 0; i < n; ++i)
+ bar (i);
+}
+
+/* Distribute with a chunk size goes through
+ expand_omp_for_static_chunk. */
+
+void
+f4 (int n)
+{
+ int i;
+#pragma omp target
+#pragma omp teams
+#pragma omp distribute dist_schedule(static, 4)
+ for (i = 0; i < n; ++i)
+ bar (i);
+}
+
+int main (void)
+{
+ f3(0);
+ f4(1);
+ return 0;
+}
--
2.53.0