gcc/libgomp/splay-tree.h
Tobias Burnus d4b6d14792 OpenMP/Fortran: Implement omp allocators/allocate for ptr/allocatables
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.
2023-12-08 15:18:25 +01:00

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