diff options
author | Tobias Burnus <tburnus@baylibre.com> | 2024-10-07 10:45:14 +0200 |
---|---|---|
committer | Tobias Burnus <tburnus@baylibre.com> | 2024-10-07 10:45:14 +0200 |
commit | a8caeaacf499d58ba7ceabc311b7b71ca806f740 (patch) | |
tree | e37c465657b7d057ea35929116672d3e29aa4104 /gcc/gimplify.cc | |
parent | b137e4bbcc488b44a037baad62a8da90659d7468 (diff) | |
download | gcc-a8caeaacf499d58ba7ceabc311b7b71ca806f740.zip gcc-a8caeaacf499d58ba7ceabc311b7b71ca806f740.tar.gz gcc-a8caeaacf499d58ba7ceabc311b7b71ca806f740.tar.bz2 |
OpenMP: Allocate directive for static vars, clean up
For the 'allocate' directive, remove the sorry for static variables and
just keep using normal memory, but honor the requested alignment and set
a DECL_ATTRIBUTE in case a target may want to make use of this later on.
The documentation is updated accordingly.
The C diagnostic to check for predefined allocators (req. for static vars)
failed to accept GCC's ompx_gnu_... allocator, now fixed. (Fortran was
already okay; but both now use new common #defined value for checking.)
And while Fortran common block variables are still rejected, the check
has been improved as before the sorry diagnostic did not work for
common blocks in modules.
Finally, for 'allocate' clause on the target/task/taskloop directives,
there is now a warning for omp_thread_mem_alloc (i.e. predefined allocator
with access = thread), which is undefined behavior according to the
OpenMP specification.
And, last, testing showed that var decl + static_assert sets TREE_USED
but does not produce a statement list in C, which did run into an assert
in gimplify. This special case is now also handled.
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_allocate): Set alignment for alignof;
accept static variables and fix predef allocator check.
gcc/fortran/ChangeLog:
* openmp.cc (is_predefined_allocator): Use gomp-constants.h consts.
* trans-common.cc (translate_common): Reject OpenMP allocate directives.
* trans-decl.cc (gfc_finish_var_decl): Handle allocate directive
for static variables.
(gfc_trans_deferred_vars): Update for the latter.
gcc/ChangeLog:
* gimplify.cc (gimplify_bind_expr): Fix corner case for OpenMP
allocate directive.
(gimplify_scan_omp_clauses): Warn if omp_thread_mem_alloc is used
as allocator with the target/task/taskloop directive.
include/ChangeLog:
* gomp-constants.h (GOMP_OMP_PREDEF_ALLOC_MAX,
GOMP_OMPX_PREDEF_ALLOC_MIN, GOMP_OMPX_PREDEF_ALLOC_MAX,
GOMP_OMP_PREDEF_ALLOC_THREADS): New defines.
libgomp/ChangeLog:
* allocator.c: Add static asserts for news
GOMP_OMP{,X}_PREDEF_ALLOC_{MIN,MAX} range values.
* libgomp.texi (OpenMP Impl. Status): Allocate directive for
static vars is now supported. Refer to PR for allocate clause.
(Memory allocation): Update for static vars; minor word tweaking.
gcc/testsuite/ChangeLog:
* c-c++-common/gomp/allocate-9.c: Update for removed sorry.
* gfortran.dg/gomp/allocate-15.f90: Likewise.
* gfortran.dg/gomp/allocate-pinned-1.f90: Likewise.
* gfortran.dg/gomp/allocate-4.f90: Likewise; add dg-error for
previously missing diagnostic.
* c-c++-common/gomp/allocate-18.c: New test.
* c-c++-common/gomp/allocate-19.c: New test.
* gfortran.dg/gomp/allocate-clause.f90: New test.
* gfortran.dg/gomp/allocate-static-2.f90: New test.
* gfortran.dg/gomp/allocate-static.f90: New test.
Diffstat (limited to 'gcc/gimplify.cc')
-rw-r--r-- | gcc/gimplify.cc | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 6cdc70d..3f60246 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -1396,6 +1396,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) if (flag_openmp && !is_global_var (t) + && !TREE_STATIC (t) && DECL_CONTEXT (t) == current_function_decl && TREE_USED (t) && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t))) @@ -1427,11 +1428,17 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p) "%<allocate%> directive for %qD inside a target " "region must specify an %<allocator%> clause", t); /* Skip for omp_default_mem_alloc (= 1), - unless align is present. */ + unless align is present. For C/C++, there should be always a + statement list following if TREE_USED, except for, e.g., using + this decl in a static_assert; in that case, only a single + DECL_EXPR remains, which can be skipped here. */ else if (!errorcount && (align != NULL_TREE || alloc == NULL_TREE - || !integer_onep (alloc))) + || !integer_onep (alloc)) + && (lang_GNU_Fortran () + || (TREE_CODE (BIND_EXPR_BODY (bind_expr)) + != DECL_EXPR))) { /* Fortran might already use a pointer type internally; use that pointer except for type(C_ptr) and type(C_funptr); @@ -13326,6 +13333,17 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, break; case OMP_CLAUSE_ALLOCATE: + decl = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); + if (decl + && TREE_CODE (decl) == INTEGER_CST + && wi::eq_p (wi::to_widest (decl), GOMP_OMP_PREDEF_ALLOC_THREADS) + && (code == OMP_TARGET || code == OMP_TASK || code == OMP_TASKLOOP)) + warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp, + "allocator with access trait set to %<thread%> " + "results in undfined behavior for %qs directive", + code == OMP_TARGET ? "target" + : (code == OMP_TASK + ? "task" : "taskloop")); decl = OMP_CLAUSE_DECL (c); if (error_operand_p (decl)) { |