diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-08-17 09:30:09 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-08-17 09:30:09 +0200 |
commit | e45483c7c4badc4bf2d6ced22360ce1ab172967f (patch) | |
tree | fabc4aa4e0eba482e7502c955508805984c4eb59 /libgomp/scope.c | |
parent | d56599979211266b2f7b7535311205dd758353ac (diff) | |
download | gcc-e45483c7c4badc4bf2d6ced22360ce1ab172967f.tar.gz |
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.
Diffstat (limited to 'libgomp/scope.c')
-rw-r--r-- | libgomp/scope.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/libgomp/scope.c b/libgomp/scope.c new file mode 100644 index 00000000000..8a4691c3493 --- /dev/null +++ b/libgomp/scope.c @@ -0,0 +1,62 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Jakub Jelinek <jakub@redhat.com>. + + This file is part of the GNU Offloading and Multi Processing Library + (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* This file handles the SCOPE construct with task reductions. */ + +#include "libgomp.h" +#include <string.h> + + +ialias_redirect (GOMP_taskgroup_reduction_register) + +/* This routine is called when first encountering a scope construct + with task reductions. While scope is not a work-sharing construct, + if it has task reductions on it, we treat it as one, but as if it is + nowait, so the work-sharing behavior is done solely to choose which + thread does the initial initialization of task reductions and which + threads follow. scope with task reductions must not be nowait, + but the barrier and GOMP_workshare_task_reduction_unregister are emitted + by the lowered code later. */ + +void +GOMP_scope_start (uintptr_t *reductions) +{ + struct gomp_thread *thr = gomp_thread (); + + gomp_workshare_taskgroup_start (); + if (gomp_work_share_start (0)) + { + GOMP_taskgroup_reduction_register (reductions); + thr->task->taskgroup->workshare = true; + thr->ts.work_share->task_reductions = reductions; + gomp_work_share_init_done (); + } + else + { + uintptr_t *first_reductions = thr->ts.work_share->task_reductions; + gomp_workshare_task_reduction_register (reductions, + first_reductions); + } +} |