https://gcc.gnu.org/g:8576d0b2134f8ff0449e50813034db4c18a4b6ae
commit r17-3188-g8576d0b2134f8ff0449e50813034db4c18a4b6ae Author: Paul-Antoine Arras <[email protected]> Date: Fri Aug 7 15:33:37 2026 +0200 openmp: Adjust calls to OMPT variants depending on loop-end call When the inscan modifier is present on a for construct, a call to GOMP_loop_end (or one of its variants) is already emitted. The extra call to one of the *_worksharing_end functions, enabled by -fopenmp-ompt, is therefore redundant. Furthermore, even without -fopenmp-ompt, the inscan modifier implies a call to GOMP_loop_end which requires the start variant of GOMP_loop_static_worksharing. gcc/ChangeLog: * omp-expand.cc (expand_omp_for_static_nochunk, expand_omp_for_static_chunk): Adjust calls to OMPT variants with GOMP_loop_end. gcc/testsuite/ChangeLog: * c-c++-common/gomp/scan-8.c: New test. * c-c++-common/gomp/scan-9.c: New test. libgomp/ChangeLog: * loop.c (GOMP_loop_static_worksharing_start, GOMP_loop_static_worksharing_end): Update comments. Diff: --- gcc/omp-expand.cc | 34 ++++++++++++++++++++++---------- gcc/testsuite/c-c++-common/gomp/scan-8.c | 22 +++++++++++++++++++++ gcc/testsuite/c-c++-common/gomp/scan-9.c | 21 ++++++++++++++++++++ libgomp/loop.c | 6 ++++-- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/gcc/omp-expand.cc b/gcc/omp-expand.cc index d6c44ebdbe21..50b9d9817d0c 100644 --- a/gcc/omp-expand.cc +++ b/gcc/omp-expand.cc @@ -5278,6 +5278,12 @@ expand_omp_for_static_nochunk (struct omp_region *region, t = fold_convert (itype, t); n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT); + /* When GOMP_loop_end (or one of its variants) is emitted (e.g. with the + inscan modifier), which already implies the end of the scope, _start + variants of GOMP builtin calls have to be used and _end can be skipped. */ + bool has_gomp_loop_end = fd->have_reductemp + || ((fd->have_pointer_condtemp || fd->have_scantemp) + && !fd->have_nonctrl_scantemp); { /* Fetch the thread/team id and the number of threads/teams in a single call to GOMP_loop_static_worksharing or @@ -5292,13 +5298,15 @@ expand_omp_for_static_nochunk (struct omp_region *region, { case GF_OMP_FOR_KIND_FOR: decl = builtin_decl_explicit ( - flag_openmp_ompt ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START - : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING); + flag_openmp_ompt || has_gomp_loop_end + ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START + : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING); break; case GF_OMP_FOR_KIND_DISTRIBUTE: decl = builtin_decl_explicit ( - flag_openmp_ompt ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START - : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING); + flag_openmp_ompt || has_gomp_loop_end + ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START + : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING); break; default: gcc_unreachable (); @@ -5663,7 +5671,7 @@ expand_omp_for_static_nochunk (struct omp_region *region, } gsi = gsi_last_nondebug_bb (exit_bb); - if (flag_openmp_ompt) + if (flag_openmp_ompt && !has_gomp_loop_end) { /* Insert call to GOMP_*_static_worksharing_end at the end of exit_bb. */ @@ -6109,6 +6117,10 @@ expand_omp_for_static_chunk (struct omp_region *region, n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT); + /* When GOMP_loop_end (or one of its variants) is emitted (e.g. with the + inscan modifier), which already implies the end of the scope, _start + variants of GOMP builtin calls have to be used and _end can be skipped. */ + bool has_gomp_loop_end = fd->have_reductemp || fd->have_pointer_condtemp; { /* Fetch the thread/team id and the number of threads/teams in a single call to GOMP_loop_static_worksharing or @@ -6123,13 +6135,15 @@ expand_omp_for_static_chunk (struct omp_region *region, { case GF_OMP_FOR_KIND_FOR: decl = builtin_decl_explicit ( - flag_openmp_ompt ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START - : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING); + flag_openmp_ompt || has_gomp_loop_end + ? BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING_START + : BUILT_IN_GOMP_LOOP_STATIC_WORKSHARING); break; case GF_OMP_FOR_KIND_DISTRIBUTE: decl = builtin_decl_explicit ( - flag_openmp_ompt ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START - : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING); + flag_openmp_ompt || has_gomp_loop_end + ? BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING_START + : BUILT_IN_GOMP_DISTRIBUTE_STATIC_WORKSHARING); break; default: gcc_unreachable (); @@ -6420,7 +6434,7 @@ expand_omp_for_static_chunk (struct omp_region *region, } gsi = gsi_last_nondebug_bb (exit_bb); - if (flag_openmp_ompt) + if (flag_openmp_ompt && !has_gomp_loop_end) { /* Insert call to GOMP_*_static_worksharing_end at the end of exit_bb. */ diff --git a/gcc/testsuite/c-c++-common/gomp/scan-8.c b/gcc/testsuite/c-c++-common/gomp/scan-8.c new file mode 100644 index 000000000000..cff8c03b3495 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/scan-8.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fopenmp-ompt -fdump-tree-ompexp" } */ + +/* Check that an extra, OMPT variant of GOMP_loop_end is not emitted when the + inscan modifier is present on the for construct. */ + +#define N 100 + +void f(void) { + int a[N], b[N]; + int x = 0; + +#pragma omp parallel for simd reduction(inscan, +: x) + for (int k = 0; k < N; k++) { + x += a[k]; +#pragma omp scan inclusive(x) + b[k] = x; + } +} + +/* { dg-final { scan-tree-dump "__builtin_GOMP_loop_end_nowait \\(" "ompexp" } } */ +/* { dg-final { scan-tree-dump-not "__builtin_GOMP_loop_end_nowait \\(\\);\[\t\n \]*__builtin_GOMP_loop_static_worksharing_end \\(\\);" "ompexp" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/scan-9.c b/gcc/testsuite/c-c++-common/gomp/scan-9.c new file mode 100644 index 000000000000..f03355363394 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/scan-9.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fdump-tree-ompexp" } */ + +/* Check that the start variant of GOMP_loop_static_worksharing is emitted + when the inscan modifier is present on the for construct. */ + +#define N 100 + +void f(void) { + int a[N], b[N]; + int x = 0; + +#pragma omp parallel for simd reduction(inscan, +: x) + for (int k = 0; k < N; k++) { + x += a[k]; +#pragma omp scan inclusive(x) + b[k] = x; + } +} + +/* { dg-final { scan-tree-dump "__builtin_GOMP_loop_static_worksharing_start \\(" "ompexp" } } */ diff --git a/libgomp/loop.c b/libgomp/loop.c index 0692663215fa..7474279fcd62 100644 --- a/libgomp/loop.c +++ b/libgomp/loop.c @@ -1201,7 +1201,8 @@ GOMP_loop_static_worksharing (unsigned long long niter return nthreads + tid * 1I; } -/* OMPT variant enabled by -fopenmp-ompt. */ +/* OMPT variant enabled by -fopenmp-ompt and when GOMP_loop_end is called + (e.g. with the inscan modifier). */ _Complex int GOMP_loop_static_worksharing_start (unsigned long long niter @@ -1224,7 +1225,8 @@ GOMP_loop_static_worksharing_dispatch (unsigned long long start __attribute__ ((unused))) {} -/* Stub for OMPT callback enabled by -fopenmp-ompt. */ +/* Stub for OMPT callback enabled by -fopenmp-ompt, except when GOMP_loop_end is + already called (e.g. with the inscan modifier). */ void GOMP_loop_static_worksharing_end (void)
