
This commit adds -fopenmp-allocators which enables support for 'omp allocators' and 'omp allocate' that are associated with a Fortran allocate-stmt. If such a construct is encountered, an error is shown, unless the -fopenmp-allocators flag is present. With -fopenmp -fopenmp-allocators, those constructs get turned into GOMP_alloc allocations, while -fopenmp-allocators (also without -fopenmp) ensures deallocation and reallocation (via intrinsic assignments) are properly directed to GOMP_free/omp_realloc - while normal Fortran allocations are processed by free/realloc. In order to distinguish a 'malloc'ed from a 'GOMP_alloc'ed memory, the version field of the Fortran array discriptor is (mis)used: 0 indicates the normal Fortran allocation while 1 denotes GOMP_alloc. For scalars, there is record keeping in libgomp: GOMP_add_alloc(ptr) will add the pointer address to a splay_tree while GOMP_is_alloc(ptr) will return true it was previously added but also removes it from the list. Besides Fortran FE work, BUILT_IN_GOMP_REALLOC is no part of omp-builtins.def and libgomp gains the mentioned two new function. gcc/ChangeLog: * builtin-types.def (BT_FN_PTR_PTR_SIZE_PTRMODE_PTRMODE): New. * omp-builtins.def (BUILT_IN_GOMP_REALLOC): New. * builtins.cc (builtin_fnspec): Handle it. * gimple-ssa-warn-access.cc (fndecl_alloc_p, matching_alloc_calls_p): Likewise. * gimple.cc (nonfreeing_call_p): Likewise. * predict.cc (expr_expected_value_1): Likewise. * tree-ssa-ccp.cc (evaluate_stmt): Likewise. * tree.cc (fndecl_dealloc_argno): Likewise. gcc/fortran/ChangeLog: * dump-parse-tree.cc (show_omp_node): Handle EXEC_OMP_ALLOCATE and EXEC_OMP_ALLOCATORS. * f95-lang.cc (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LIST): Add 'ECF_LEAF | ECF_MALLOC' to existing 'ECF_NOTHROW'. (ATTR_ALLOC_WARN_UNUSED_RESULT_SIZE_2_NOTHROW_LEAF_LIST): Define. * gfortran.h (gfc_omp_clauses): Add contained_in_target_construct. * invoke.texi (-fopenacc, -fopenmp): Update based on C version. (-fopenmp-simd): New, based on C version. (-fopenmp-allocators): New. * lang.opt (fopenmp-allocators): Add. * openmp.cc (resolve_omp_clauses): For allocators/allocate directive, add target and no dynamic_allocators diagnostic and more invalid diagnostic. * parse.cc (decode_omp_directive): Set contains_teams_construct. * trans-array.h (gfc_array_allocate): Update prototype. (gfc_conv_descriptor_version): New prototype. * trans-decl.cc (gfc_init_default_dt): Fix comment. * trans-array.cc (gfc_conv_descriptor_version): New. (gfc_array_allocate): Support GOMP_alloc allocation. (gfc_alloc_allocatable_for_assignment, structure_alloc_comps): Handle GOMP_free/omp_realloc as needed. * trans-expr.cc (gfc_conv_procedure_call): Likewise. (alloc_scalar_allocatable_for_assignment): Likewise. * trans-intrinsic.cc (conv_intrinsic_move_alloc): Likewise. * trans-openmp.cc (gfc_trans_omp_allocators, gfc_trans_omp_directive): Handle allocators/allocate directive. (gfc_omp_call_add_alloc, gfc_omp_call_is_alloc): New. * trans-stmt.h (gfc_trans_allocate): Update prototype. * trans-stmt.cc (gfc_trans_allocate): Support GOMP_alloc. * trans-types.cc (gfc_get_dtype_rank_type): Set version field. * trans.cc (gfc_allocate_using_malloc, gfc_allocate_allocatable): Update to handle GOMP_alloc. (gfc_deallocate_with_status, gfc_deallocate_scalar_with_status): Handle GOMP_free. (trans_code): Update call. * trans.h (gfc_allocate_allocatable, gfc_allocate_using_malloc): Update prototype. (gfc_omp_call_add_alloc, gfc_omp_call_is_alloc): New prototype. * types.def (BT_FN_PTR_PTR_SIZE_PTRMODE_PTRMODE): New. libgomp/ChangeLog: * allocator.c (struct fort_alloc_splay_tree_key_s, fort_alloc_splay_compare, GOMP_add_alloc, GOMP_is_alloc): New. * libgomp.h: Define splay_tree_static for 'reverse' splay tree. * libgomp.map (GOMP_5.1.2): New; add GOMP_add_alloc and GOMP_is_alloc; move GOMP_target_map_indirect_ptr from ... (GOMP_5.1.1): ... here. * libgomp.texi (Impl. Status, Memory management): Update for allocators/allocate directives. * splay-tree.c: Handle splay_tree_static define to declare all functions as static. (splay_tree_lookup_node): New. * splay-tree.h: Handle splay_tree_decl_only define. (splay_tree_lookup_node): New prototype. * target.c: Define splay_tree_static for 'reverse'. * testsuite/libgomp.fortran/allocators-1.f90: New test. * testsuite/libgomp.fortran/allocators-2.f90: New test. * testsuite/libgomp.fortran/allocators-3.f90: New test. * testsuite/libgomp.fortran/allocators-4.f90: New test. * testsuite/libgomp.fortran/allocators-5.f90: New test. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/allocate-14.f90: Add coarray and not-listed tests. * gfortran.dg/gomp/allocate-5.f90: Remove sorry dg-message. * gfortran.dg/bind_c_array_params_2.f90: Update expected dump for dtype '.version=0'. * gfortran.dg/gomp/allocate-16.f90: New test. * gfortran.dg/gomp/allocators-3.f90: New test. * gfortran.dg/gomp/allocators-4.f90: New test.
155 lines
5.7 KiB
C
155 lines
5.7 KiB
C
/* A splay-tree datatype.
|
|
Copyright (C) 1998-2023 Free Software Foundation, Inc.
|
|
Contributed by Mark Mitchell (mark@markmitchell.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/>. */
|
|
|
|
/* The splay tree code copied from include/splay-tree.h and adjusted,
|
|
so that all the data lives directly in splay_tree_node_s structure
|
|
and no extra allocations are needed.
|
|
|
|
Files including this header should before including it add:
|
|
typedef struct splay_tree_node_s *splay_tree_node;
|
|
typedef struct splay_tree_s *splay_tree;
|
|
typedef struct splay_tree_key_s *splay_tree_key;
|
|
define splay_tree_key_s structure, and define
|
|
splay_compare inline function.
|
|
|
|
Define splay_tree_static to mark all functions as static.
|
|
|
|
Alternatively, they can define splay_tree_prefix macro before
|
|
including this header and then all the above types, the
|
|
splay_compare function and the splay_tree_{lookup,insert_remove}
|
|
function will be prefixed by that prefix. If splay_tree_prefix
|
|
macro is defined, this header must be included twice: once where
|
|
you need the header file definitions, and once where you need the
|
|
.c implementation routines. In the latter case, you must also
|
|
define the macro splay_tree_c. See the include of splay-tree.h in
|
|
priority_queue.[hc] for an example. */
|
|
|
|
/* For an easily readable description of splay-trees, see:
|
|
|
|
Lewis, Harry R. and Denenberg, Larry. Data Structures and Their
|
|
Algorithms. Harper-Collins, Inc. 1991.
|
|
|
|
The major feature of splay trees is that all basic tree operations
|
|
are amortized O(log n) time for a tree with n nodes. */
|
|
|
|
#ifdef splay_tree_prefix
|
|
# define splay_tree_name_1(prefix, name) prefix ## _ ## name
|
|
# define splay_tree_name(prefix, name) splay_tree_name_1 (prefix, name)
|
|
# define splay_tree_node_s \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_node_s)
|
|
# define splay_tree_s \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_s)
|
|
# define splay_tree_key_s \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_key_s)
|
|
# define splay_tree_node \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_node)
|
|
# define splay_tree \
|
|
splay_tree_name (splay_tree_prefix, splay_tree)
|
|
# define splay_tree_key \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_key)
|
|
# define splay_compare \
|
|
splay_tree_name (splay_tree_prefix, splay_compare)
|
|
# define splay_tree_lookup \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_lookup)
|
|
# define splay_tree_lookup_node \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_lookup_node)
|
|
# define splay_tree_insert \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_insert)
|
|
# define splay_tree_remove \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_remove)
|
|
# define splay_tree_foreach \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_foreach)
|
|
# define splay_tree_foreach_lazy \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_foreach_lazy)
|
|
# define splay_tree_callback \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_callback)
|
|
# define splay_tree_callback_stop \
|
|
splay_tree_name (splay_tree_prefix, splay_tree_callback_stop)
|
|
#endif
|
|
|
|
#ifndef splay_tree_c
|
|
/* Header file definitions and prototypes. */
|
|
|
|
/* The nodes in the splay tree. */
|
|
struct splay_tree_node_s {
|
|
struct splay_tree_key_s key;
|
|
/* The left and right children, respectively. */
|
|
splay_tree_node left;
|
|
splay_tree_node right;
|
|
};
|
|
|
|
/* The splay tree. */
|
|
struct splay_tree_s {
|
|
splay_tree_node root;
|
|
};
|
|
|
|
typedef void (*splay_tree_callback) (splay_tree_key, void *);
|
|
typedef int (*splay_tree_callback_stop) (splay_tree_key, void *);
|
|
|
|
#ifndef splay_tree_static
|
|
extern splay_tree_key splay_tree_lookup (splay_tree, splay_tree_key);
|
|
extern splay_tree_node splay_tree_lookup_node (splay_tree, splay_tree_key);
|
|
extern void splay_tree_insert (splay_tree, splay_tree_node);
|
|
extern void splay_tree_remove (splay_tree, splay_tree_key);
|
|
extern void splay_tree_foreach (splay_tree, splay_tree_callback, void *);
|
|
extern void splay_tree_foreach_lazy (splay_tree, splay_tree_callback_stop, void *);
|
|
#endif
|
|
|
|
#ifdef splay_tree_static_unused_attr
|
|
# undef splay_tree_static_unused_attr
|
|
#endif
|
|
|
|
#else /* splay_tree_c */
|
|
# ifdef splay_tree_prefix
|
|
# include "splay-tree.c"
|
|
# endif
|
|
# undef splay_tree_c
|
|
#endif /* #ifndef splay_tree_c */
|
|
|
|
#ifdef splay_tree_static
|
|
# undef splay_tree_static
|
|
#endif
|
|
|
|
#ifdef splay_tree_prefix
|
|
# undef splay_tree_name_1
|
|
# undef splay_tree_name
|
|
# undef splay_tree_node_s
|
|
# undef splay_tree_s
|
|
# undef splay_tree_key_s
|
|
# undef splay_tree_node
|
|
# undef splay_tree
|
|
# undef splay_tree_key
|
|
# undef splay_compare
|
|
# undef splay_tree_lookup
|
|
# undef splay_tree_lookup_node
|
|
# undef splay_tree_insert
|
|
# undef splay_tree_remove
|
|
# undef splay_tree_foreach
|
|
# undef splay_tree_foreach_lazy
|
|
# undef splay_tree_callback
|
|
# undef splay_tree_callback_stop
|
|
# undef splay_tree_prefix
|
|
#endif
|