Hi Paul-Antoine!

On 2026-07-01T16:57:43+0200, Paul-Antoine Arras <[email protected]> wrote:
> While working on a follow-up patch, I realised that I did not include 
> target-side versions of GOMP_distribute_static_worksharing_start et al. 
> The attached fixup patch does so and adds testcases.

ACK.

> On 30/06/2026 14:56, Paul-Antoine Arras wrote:
>> 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.

Thanks!  I've not verified your implementation vs. what OpenMP/OMPT
requires -- I assume you and Tobias have sorted that out.

>> --- gcc/common.opt
>> +++ gcc/common.opt
>> @@ -2503,6 +2503,13 @@ 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)
>> +
>> +
>> +fopenmp-ompt-detailed
>> +Common Var(flag_openmp_ompt_detailed)
>> +
>>   fopenmp-target-simd-clone
>>   Common Alias(fopenmp-target-simd-clone=,any,none)

Some short "help text" for the new options, please.

Also, need documenting in 'gcc/doc/invoke.texi', in the "Option Summary"
as well as "OpenMP and OpenACC Options".  Probably don't need anything
additional in 'gcc/fortran/gfortran.texi'.

We have '-fopenmp', '-fopenmp-simd' defined in 'gcc/c-family/c.opt',
'gcc/fortran/lang.opt', as, from the user perspective, they only apply to
those respective front ends.  I did wonder whether we shouldn't handle
'-fopenmp-ompt', '-fopenmp-ompt-detailed' similarly?  But on the other
head, those are 'Common' infrastructure, in the sense that OpenMP/OMPT
functionality also applies if OpenMP is used "as an implementation
detail" in GCC, such as when 'Common' '-ftree-parallelize-loops'
synthesizes OpenMP constructs (and therefore implicitly enables OpenMP
support) to parallelize Algol 68 code, for example.  In that case, it's
then certainly valid to expect to see OpenMP/OMPT events reported, and
'-fopenmp-ompt', '-fopenmp-ompt-detailed' than likewise apply.
Therefore, it appears correct to have those 'Common' options.  (We shall
add a corresponding Algol 68 test case (or other non-C, C++, Fortran, of
course), once that's feasible to do.)

>> --- gcc/omp-builtins.def
>> +++ 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)

All these need prototypes in 'libgomp/libgomp_g.h', too.  (This is
especially important for my libgomp/C++ work.)  In 'libgomp/libgomp_g.h',
please sort them in the right place: in sections corresponding to their
libgomp implementation file, in order of definition therein.

'GOMP_loop_static_worksharing_dispatch',
'GOMP_distribute_static_worksharing_dispatch' are really just a signal,
but don't transmit any further data into libgomp/OMPT?

>> --- gcc/omp-expand.cc
>> +++ gcc/omp-expand.cc

>> @@ -5201,10 +5201,14 @@ expand_omp_for_static_nochunk (struct omp_region 
>> *region,

>> @@ -5969,10 +6019,14 @@ expand_omp_for_static_chunk (struct omp_region 
>> *region,

I've not verified the positions of the individual 'GOMP_[...]' calls that
you're synthesizing.

Let me know if anything needs more in-depth review.

>> --- gcc/omp-low.cc
>> +++ gcc/omp-low.cc

>> @@ -8786,7 +8786,9 @@ lower_omp_single_simple (gomp_single *single_stmt, 
>> gimple_seq *pre_p)

>> @@ -8923,6 +8925,15 @@ lower_omp_single (gimple_stmt_iterator *gsi_p, 
>> omp_context *ctx)

>> @@ -9099,6 +9110,14 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, 
>> omp_context *ctx)

Likewise.

>> --- gcc/opts.cc
>> +++ 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);
>>   }

Looks like the appropriate place for these diagnostics.

>> --- libgomp/loop.c
>> +++ libgomp/loop.c
>> @@ -1186,3 +1186,53 @@ 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)
>> +{}
>> +
>> +/* Return true if the current thread number equals TID.
>> +   Used to implement the masked construct's filter clause.  */
>> +
>> +bool
>> +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)
>> +{}

Please update 'libgomp/libgomp_g.h' also for the functions you're moving
into 'libgomp/loop.c' from:

>> --- libgomp/parallel.c
>> +++ libgomp/parallel.c
>> @@ -271,27 +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.  */
>> -
>> -bool
>> -GOMP_has_masked_thread_num (int tid)
>> -{
>> -  return tid == gomp_thread ()->ts.team_id;
>> -}

... here.

(I'm not disagreeing -- but was there any specific reason for moving
them?)

>> -

Keep the page break, I guess?

>>   /* The public OpenMP API for thread and team related inquiries.  */
>>   
>>   int

> Subject: [PATCH] libgomp: Add target-side versions of
>  GOMP_distribute_static_worksharing

ACK.


Grüße
 Thomas

Reply via email to