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