On Fri, Jan 15, 2021 at 03:07:56PM +0000, Kwok Cheung Yeung wrote:
> +     {
> +       tree detach_decl = OMP_CLAUSE_DECL (*detach_seen);
> +
> +       for (pc = &clauses, c = clauses; c ; c = *pc)
> +         {
> +           bool remove = false;
> +           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
> +                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
> +                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
> +                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
> +               && OMP_CLAUSE_DECL (c) == detach_decl)
> +             {
> +               error_at (OMP_CLAUSE_LOCATION (c),
> +                         "the event handle of a %<detach%> clause "
> +                         "should not be in a data-sharing clause");
> +               remove = true;
> +             }

I think you don't need this loop, instead you could just check
                if (bitmap_bit_p (&generic_head, DECL_UID (detach_decl))
                    || bitmap_bit_p (&firstprivate_head, DECL_UID (detach_decl))
                    || bitmap_bit_p (&lastprivate_head, DECL_UID (detach_decl)))

> +                   || TREE_CODE (type) != ENUMERAL_TYPE
                      || DECL_NAME (TYPE_NAME (type))
                           != get_identifier ("omp_event_handle_t")))

The formatting is off, and I think as a service to Emacs users we are
usually formatting it as:
                      || (DECL_NAME (TYPE_NAME (type))
                          != get_identifier ("omp_event_handle_t"))))

> +
> +  detach = detach
> +        ? build_fold_addr_expr (OMP_CLAUSE_DECL (detach))
> +        : null_pointer_node;

Again formatting nit, please write:
  detach = (detach
            ? build_fold_addr_expr (OMP_CLAUSE_DECL (detach))
            : null_pointer_node);

> @@ -2416,6 +2421,64 @@ finish_taskreg_scan (omp_context *ctx)
>             TYPE_FIELDS (ctx->srecord_type) = f1;
>           }
>       }
> +      if (detach_clause)
> +     {
> +       tree c, field;
> +
> +       /* Look for a firstprivate clause with the detach event handle.  */
> +       for (c = gimple_omp_taskreg_clauses (ctx->stmt);
> +            c; c = OMP_CLAUSE_CHAIN (c))
> +         {
> +           if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
> +             continue;
> +           if (maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c), ctx)
> +               == OMP_CLAUSE_DECL (detach_clause))
> +             break;
> +         }
> +
> +       if (c)
> +         field = lookup_field (OMP_CLAUSE_DECL (c), ctx);
> +       else
> +         {
> +           /* The detach event handle is not referenced within the
> +              task context, so add a temporary field for it here.  */
> +           field = build_decl (OMP_CLAUSE_LOCATION (detach_clause),
> +                               FIELD_DECL, NULL_TREE, ptr_type_node);
> +           insert_field_into_struct (ctx->record_type, field);

Can't you just force the firstprivate clause during gimplification, so that
it doesn't go away even if not referenced?
That would mean just forcing in | GOVD_SEEN when it is added.
If not, not a big deal, just thought it could be easier.

> +
> +           if (ctx->srecord_type)
> +             {
> +               tree sfield
> +                 = build_decl (OMP_CLAUSE_LOCATION (detach_clause),
> +                               FIELD_DECL, NULL_TREE, ptr_type_node);
> +               insert_field_into_struct (ctx->srecord_type, sfield);
> +             }
> +         }
> +
> +       /* Move field corresponding to the detach clause first.
> +          This is filled by GOMP_task and needs to be in a
> +          specific position.  */
> +       p = &TYPE_FIELDS (ctx->record_type);
> +       while (*p)
> +         if (*p == field)
> +           *p = DECL_CHAIN (*p);
> +         else
> +           p = &DECL_CHAIN (*p);
> +       DECL_CHAIN (field) = TYPE_FIELDS (ctx->record_type);
> +       TYPE_FIELDS (ctx->record_type) = field;
> +       if (ctx->srecord_type)
> +         {
> +           field = lookup_sfield (OMP_CLAUSE_DECL (detach_clause), ctx);
> +           p = &TYPE_FIELDS (ctx->srecord_type);
> +           while (*p)
> +             if (*p == field)
> +               *p = DECL_CHAIN (*p);
> +             else
> +               p = &DECL_CHAIN (*p);
> +           DECL_CHAIN (field) = TYPE_FIELDS (ctx->srecord_type);
> +           TYPE_FIELDS (ctx->srecord_type) = field;
> +         }
> +     }
>        layout_type (ctx->record_type);
>        fixup_child_record_type (ctx);
>        if (ctx->srecord_type)
> diff --git a/gcc/testsuite/c-c++-common/gomp/task-detach-1.c 
> b/gcc/testsuite/c-c++-common/gomp/task-detach-1.c
> new file mode 100644
> index 0000000..c7dda82
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/gomp/task-detach-1.c
> @@ -0,0 +1,32 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fopenmp" } */
> +
> +#include <omp.h>
> +
> +void f (omp_event_handle_t x, omp_event_handle_t y, int z)
> +{
> +  #pragma omp task detach (x) detach (y) /* { dg-error "there can be at most 
> one 'detach' clause in a task construct" } */

It would be on a task construct rather than in a task construct, but the
common wording for this diagnostics is
"too many %qs clauses", "detach"
Please use that wording.
> +
> +template <typename T>
> +void func ()
> +{
> +  T t;
> +  #pragma omp task detach (t) // { dg-error "'detach' clause event handle 
> has type 'int' rather than 'omp_event_handle_t'" }
> +    ;
> +}
> +
> +void f()
> +{
> +  func <omp_event_handle_t> ();
> +  func <int> (); // { dg-message "required from here" }
> +}

I'd suggest two different templates with the same content, because the
dg-error is in the template and splitting them might make it clearer in
which one it is from.  The required from here message is I think ignored by
default, so if it incorrectly diagnosed both spots, one wouldn't notice.
> +  
> +  !$omp task detach (x) firstprivate (x) ! { dg-error "DETACH event handle 
> 'x' in FIRSTPRIVATE clause at \\\(1\\\)" }
> +  !$omp end task
> +
> +  !$omp task detach (x) shared (x) ! { dg-error "DETACH event handle 'x' in 
> SHARED clause at \\\(1\\\)" }
> +  !$omp end task
> +end program
> \ No newline at end of file

Please add newline.
> +
> +  gomp_debug(0, "omp_fulfill_event: %p\n", sem);

Space before (.

Otherwise LGTM, thanks.

        Jakub

Reply via email to