Commit Graph

2 Commits

Author SHA1 Message Date
Jakub Jelinek 7adcbafe45 Update copyright years. 2022-01-03 10:42:10 +01:00
Jakub Jelinek e45483c7c4 openmp: Implement OpenMP 5.1 scope construct
This patch implements the OpenMP 5.1 scope construct, which is similar
to worksharing constructs in many regards, but isn't one of them.
The body of the construct is encountered by all threads though, it can
be nested in itself or intermixed with taskgroup and worksharing etc.
constructs can appear inside of it (but it can't be nested in
worksharing etc. constructs).  The main purpose of the construct
is to allow reductions (normal and task ones) without the need to
close the parallel and reopen another one.

If it doesn't have task reductions, it can be implemented without
any new library support, with nowait it just does the privatizations
at the start if any and reductions before the end of the body, with
without nowait emits a normal GOMP_barrier{,_cancel} at the end too.

For task reductions, we need to ensure only one thread initializes
the task reduction library data structures and other threads copy from that,
so a new GOMP_scope_start routine is added to the library for that.
It acts as if the start of the scope construct is a nowait worksharing
construct (that is ok, it can't be nested in other worksharing
constructs and all threads need to encounter the start in the same
order) which does the task reduction initialization, but as the body
can have other scope constructs and/or worksharing constructs, that is
all where we use this dummy worksharing construct.  With task reductions,
the construct must not have nowait and ends with a GOMP_barrier{,_cancel},
followed by task reductions followed by GOMP_workshare_task_reduction_unregister.

Only C/C++ FE support is done.

2021-08-17  Jakub Jelinek  <jakub@redhat.com>

gcc/
	* tree.def (OMP_SCOPE): New tree code.
	* tree.h (OMP_SCOPE_BODY, OMP_SCOPE_CLAUSES): Define.
	* tree-nested.c (convert_nonlocal_reference_stmt,
	convert_local_reference_stmt, convert_gimple_call): Handle
	GIMPLE_OMP_SCOPE.
	* tree-pretty-print.c (dump_generic_node): Handle OMP_SCOPE.
	* gimple.def (GIMPLE_OMP_SCOPE): New gimple code.
	* gimple.c (gimple_build_omp_scope): New function.
	(gimple_copy): Handle GIMPLE_OMP_SCOPE.
	* gimple.h (gimple_build_omp_scope): Declare.
	(gimple_has_substatements): Handle GIMPLE_OMP_SCOPE.
	(gimple_omp_scope_clauses, gimple_omp_scope_clauses_ptr,
	gimple_omp_scope_set_clauses): New inline functions.
	(CASE_GIMPLE_OMP): Add GIMPLE_OMP_SCOPE.
	* gimple-pretty-print.c (dump_gimple_omp_scope): New function.
	(pp_gimple_stmt_1): Handle GIMPLE_OMP_SCOPE.
	* gimple-walk.c (walk_gimple_stmt): Likewise.
	* gimple-low.c (lower_stmt): Likewise.
	* gimplify.c (is_gimple_stmt): Handle OMP_MASTER.
	(gimplify_scan_omp_clauses): For task reductions, handle OMP_SCOPE
	like ORT_WORKSHARE constructs.  Adjust diagnostics for %<scope%>
	allowing task reductions.  Reject inscan reductions on scope.
	(omp_find_stores_stmt): Handle GIMPLE_OMP_SCOPE.
	(gimplify_omp_workshare, gimplify_expr): Handle OMP_SCOPE.
	* tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_SCOPE.
	(estimate_num_insns): Likewise.
	* omp-low.c (build_outer_var_ref): Look through GIMPLE_OMP_SCOPE
	contexts if var isn't privatized there.
	(check_omp_nesting_restrictions): Handle GIMPLE_OMP_SCOPE.
	(scan_omp_1_stmt): Likewise.
	(maybe_add_implicit_barrier_cancel): Look through outer
	scope constructs.
	(lower_omp_scope): New function.
	(lower_omp_task_reductions): Handle OMP_SCOPE.
	(lower_omp_1): Handle GIMPLE_OMP_SCOPE.
	(diagnose_sb_1, diagnose_sb_2): Likewise.
	* omp-expand.c (expand_omp_single): Support also GIMPLE_OMP_SCOPE.
	(expand_omp): Handle GIMPLE_OMP_SCOPE.
	(omp_make_gimple_edges): Likewise.
	* omp-builtins.def (BUILT_IN_GOMP_SCOPE_START): New built-in.
gcc/c-family/
	* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_SCOPE.
	* c-pragma.c (omp_pragmas): Add scope construct.
	* c-omp.c (omp_directives): Uncomment scope directive entry.
gcc/c/
	* c-parser.c (OMP_SCOPE_CLAUSE_MASK): Define.
	(c_parser_omp_scope): New function.
	(c_parser_omp_construct): Handle PRAGMA_OMP_SCOPE.
gcc/cp/
	* parser.c (OMP_SCOPE_CLAUSE_MASK): Define.
	(cp_parser_omp_scope): New function.
	(cp_parser_omp_construct, cp_parser_pragma): Handle PRAGMA_OMP_SCOPE.
	* pt.c (tsubst_expr): Handle OMP_SCOPE.
gcc/testsuite/
	* c-c++-common/gomp/nesting-2.c (foo): Add scope and masked
	construct tests.
	* c-c++-common/gomp/scan-1.c (f3): Add scope construct test..
	* c-c++-common/gomp/cancel-1.c (f2): Add scope and masked
	construct tests.
	* c-c++-common/gomp/reduction-task-2.c (bar): Add scope construct
	test.  Adjust diagnostics for the addition of scope.
	* c-c++-common/gomp/loop-1.c (f5): Add master, masked and scope
	construct tests.
	* c-c++-common/gomp/clause-dups-1.c (f1): Add scope construct test.
	* gcc.dg/gomp/nesting-1.c (f1, f2, f3): Add scope construct tests.
	* c-c++-common/gomp/scope-1.c: New test.
	* c-c++-common/gomp/scope-2.c: New test.
	* g++.dg/gomp/attrs-1.C (bar): Add scope construct tests.
	* g++.dg/gomp/attrs-2.C (bar): Likewise.
	* gfortran.dg/gomp/reduction4.f90: Adjust expected diagnostics.
	* gfortran.dg/gomp/reduction7.f90: Likewise.
libgomp/
	* Makefile.am (libgomp_la_SOURCES): Add scope.c
	* Makefile.in: Regenerated.
	* libgomp_g.h (GOMP_scope_start): Declare.
	* libgomp.map: Add GOMP_scope_start@@GOMP_5.1.
	* scope.c: New file.
	* testsuite/libgomp.c-c++-common/scope-1.c: New test.
	* testsuite/libgomp.c-c++-common/task-reduction-16.c: New test.
2021-08-17 09:30:09 +02:00