This patch adds support for non-constant iterator bounds to the Fortran
deep-mapping iterator support.
To do this, we need to keep track of the new iterator entries generated
during by the deep mapping. Code is generated by lower_omp_target to
allocate memory for each of these entries one-by-one, then freed after
the target code. allocate_omp_iterator_elems and free_omp_iterator_elems
are modified so that they work on a per-iterator basis rather than
per-clause.From a9236e9350dbe1c51d92c8301118fe7f36a371db Mon Sep 17 00:00:00 2001
From: Kwok Cheung Yeung <kcye...@baylibre.com>
Date: Sat, 3 May 2025 21:10:47 +0000
Subject: [PATCH 11/11] openmp, fortran: Add support for non-constant iterator
bounds in Fortran deep-mapping iterator support
gcc/fortran/
* trans-openmp.cc (gfc_omp_deep_mapping_map): Add new argument for
vector of newly created iterators. Push new iterators onto the
vector.
(gfc_omp_deep_mapping_comps): Add new argument for vector of new
iterators. Pass argument in calls to gfc_omp_deep_mapping_item and
gfc_omp_deep_mapping_comps.
(gfc_omp_deep_mapping_item): Add new argument for vector of new
iterators. Pass argument in calls to gfc_omp_deep_mapping_map and
gfc_omp_deep_mapping_comps.
(gfc_omp_deep_mapping_do): Add new argument for vector of new
iterators. Pass argument in calls to gfc_omp_deep_mapping_item.
(gfc_omp_deep_mapping_cnt): Pass NULL to new argument for
gfc_omp_deep_mapping_do.
(gfc_omp_deep_mapping): Add new argument for vector of new
iterators. Pass argument in calls to gfc_omp_deep_mapping_do.
* trans.h (gfc_omp_deep_mapping): Add new argument.
gcc/
* langhooks-def.h (lhd_omp_deep_mapping): Add new argument.
* langhooks.cc (lhd_omp_deep_mapping): Likewise.
* langhooks.h (omp_deep_mapping): Likewise.
* omp-low.cc (allocate_omp_iterator_elems): Work on the supplied
iterator set instead of the iterators in a supplied set of clauses.
(free_omp_iterator_elems): Likewise.
(lower_omp_target): Maintain vector of new iterators generated by
deep-mapping. Allocate and free iterator element arrays using
iterators found in clauses and in the new iterator vector.
libgomp/
* testsuite/libgomp.fortran/allocatable-comp-iterators.f90: Add test
for non-const iterator boundaries.
---
gcc/fortran/trans-openmp.cc | 38 ++++---
gcc/fortran/trans.h | 3 +-
gcc/langhooks-def.h | 3 +-
gcc/langhooks.cc | 2 +-
gcc/langhooks.h | 3 +-
gcc/omp-low.cc | 103 +++++++++---------
.../allocatable-comp-iterators.f90 | 3 +-
7 files changed, 83 insertions(+), 72 deletions(-)
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 96a9c63665b..7b0996b03e6 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1854,7 +1854,8 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned
HOST_WIDE_INT tkind,
location_t loc, tree data_array, tree sizes_array,
tree kinds_array, tree offset_data, tree offset,
gimple_seq *seq, gimple *ctx,
- tree iterators, gimple_seq loops_pre_seq)
+ tree iterators, gimple_seq loops_pre_seq,
+ vec<tree> *new_iterators)
{
tree one = build_int_cst (size_type_node, 1);
@@ -1880,6 +1881,7 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned
HOST_WIDE_INT tkind,
if (iterators)
{
data_iter = add_new_omp_iterators_entry (iterators, loops_seq_p);
+ new_iterators->safe_push (data_iter);
assign_to_iterator_elems_array (data_expr, data_iter, ctx);
data_expr = OMP_ITERATORS_ELEMS (data_iter);
if (TREE_CODE (TREE_TYPE (data_expr)) == ARRAY_TYPE)
@@ -1900,6 +1902,7 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned
HOST_WIDE_INT tkind,
if (iterators)
{
data_addr_iter = add_new_omp_iterators_entry (iterators, loops_seq_p);
+ new_iterators->safe_push (data_addr_iter);
assign_to_iterator_elems_array (data_addr_expr, data_addr_iter, ctx);
data_addr_expr = OMP_ITERATORS_ELEMS (data_addr_iter);
if (TREE_CODE (TREE_TYPE (data_addr_expr)) == ARRAY_TYPE)
@@ -1990,7 +1993,7 @@ static void gfc_omp_deep_mapping_item (bool, bool, bool,
location_t, tree,
tree *, unsigned HOST_WIDE_INT, tree,
tree, tree, tree, tree, tree,
gimple_seq *, gimple *, bool *,
- tree);
+ tree, vec <tree> *);
/* Map allocatable components. */
static void
@@ -1999,7 +2002,8 @@ gfc_omp_deep_mapping_comps (bool is_cnt, location_t loc,
tree decl,
tree data_array, tree sizes_array, tree kinds_array,
tree offset_data, tree offset, tree num,
gimple_seq *seq, gimple *ctx,
- bool *poly_warned, tree iterators)
+ bool *poly_warned, tree iterators,
+ vec <tree> *new_iterators)
{
tree type = TREE_TYPE (decl);
if (TREE_CODE (type) != RECORD_TYPE)
@@ -2017,7 +2021,8 @@ gfc_omp_deep_mapping_comps (bool is_cnt, location_t loc,
tree decl,
gfc_omp_deep_mapping_item (is_cnt, true, true, loc, tmp, token,
tkind, data_array, sizes_array,
kinds_array, offset_data, offset, num,
- seq, ctx, poly_warned, iterators);
+ seq, ctx, poly_warned, iterators,
+ new_iterators);
}
else if (GFC_DECL_GET_SCALAR_POINTER (field)
|| GFC_DESCRIPTOR_TYPE_P (type))
@@ -2030,12 +2035,13 @@ gfc_omp_deep_mapping_comps (bool is_cnt, location_t
loc, tree decl,
gfc_omp_deep_mapping_item (is_cnt, false, false, loc, tmp,
token, tkind, data_array, sizes_array,
kinds_array, offset_data, offset, num,
- seq, ctx, poly_warned, iterators);
+ seq, ctx, poly_warned, iterators,
+ new_iterators);
else
gfc_omp_deep_mapping_comps (is_cnt, loc, tmp, token, tkind,
data_array, sizes_array, kinds_array,
offset_data, offset, num, seq, ctx,
- poly_warned, iterators);
+ poly_warned, iterators, new_iterators);
}
}
}
@@ -2179,7 +2185,7 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy,
bool do_alloc_check,
tree sizes_array, tree kinds_array, tree offset_data,
tree offset, tree num, gimple_seq *seq,
gimple *ctx, bool *poly_warned,
- tree iterators)
+ tree iterators, vec<tree> *new_iterators)
{
tree tmp;
tree type = TREE_TYPE (decl);
@@ -2286,7 +2292,8 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy,
bool do_alloc_check,
gfc_omp_deep_mapping_map (tmp, bytesize, tkind2, loc, data_array,
sizes_array, kinds_array, offset_data,
- offset, seq, ctx, iterators, loops_pre_seq);
+ offset, seq, ctx, iterators, loops_pre_seq,
+ new_iterators);
}
tmp = decl;
@@ -2326,7 +2333,7 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy,
bool do_alloc_check,
gfc_omp_deep_mapping_comps (is_cnt, loc, decl, token, tkind,
data_array, sizes_array, kinds_array,
offset_data, offset, num, seq, ctx,
- poly_warned, iterators);
+ poly_warned, iterators, new_iterators);
gimple_seq_add_seq (seq, seq2);
}
if (end_label)
@@ -2474,7 +2481,7 @@ static tree
gfc_omp_deep_mapping_do (bool is_cnt, gimple *ctx, tree clause,
unsigned HOST_WIDE_INT tkind, tree data, tree sizes,
tree kinds, tree offset_data, tree offset,
- gimple_seq *seq)
+ gimple_seq *seq, vec<tree> *new_iterators)
{
tree num = NULL_TREE;
location_t loc = OMP_CLAUSE_LOCATION (clause);
@@ -2590,14 +2597,15 @@ gfc_omp_deep_mapping_do (bool is_cnt, gimple *ctx, tree
clause,
&token, tkind, data, sizes, kinds,
offset_data, offset, num, seq, ctx,
&poly_warned,
- OMP_CLAUSE_ITERATORS (clause));
+ OMP_CLAUSE_ITERATORS (clause),
+ new_iterators);
gimple_seq_add_stmt (seq, gimple_build_label (end_label));
}
else
gfc_omp_deep_mapping_item (is_cnt, do_copy, do_alloc_check, loc, decl,
&token, tkind, data, sizes, kinds, offset_data,
offset, num, seq, ctx, &poly_warned,
- OMP_CLAUSE_ITERATORS (clause));
+ OMP_CLAUSE_ITERATORS (clause), new_iterators);
/* Multiply by 2 as there are two mappings: data + pointer assign. */
if (is_cnt)
gimplify_assign (num,
@@ -2613,7 +2621,7 @@ tree
gfc_omp_deep_mapping_cnt (gimple *ctx, tree clause, gimple_seq *seq)
{
return gfc_omp_deep_mapping_do (true, ctx, clause, 0, NULL_TREE, NULL_TREE,
- NULL_TREE, NULL_TREE, NULL_TREE, seq);
+ NULL_TREE, NULL_TREE, NULL_TREE, seq, NULL);
}
/* Does the actual deep mapping. */
@@ -2621,10 +2629,10 @@ void
gfc_omp_deep_mapping (gimple *ctx, tree clause,
unsigned HOST_WIDE_INT tkind, tree data,
tree sizes, tree kinds, tree offset_data, tree offset,
- gimple_seq *seq)
+ gimple_seq *seq, vec<tree> *new_iterators)
{
(void) gfc_omp_deep_mapping_do (false, ctx, clause, tkind, data, sizes,
kinds,
- offset_data, offset, seq);
+ offset_data, offset, seq, new_iterators);
}
/* Return true if DECL is a scalar variable (for the purpose of
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 746f77cb458..197704b7098 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -843,7 +843,8 @@ void gfc_omp_finish_clause (tree, gimple_seq *, bool);
bool gfc_omp_deep_mapping_p (const gimple *, tree);
tree gfc_omp_deep_mapping_cnt (gimple *, tree, gimple_seq *);
void gfc_omp_deep_mapping (gimple *, tree, unsigned HOST_WIDE_INT, tree,
- tree, tree, tree, tree, gimple_seq *);
+ tree, tree, tree, tree, gimple_seq *,
+ vec<tree> *);
bool gfc_omp_allocatable_p (tree);
bool gfc_omp_scalar_p (tree, bool);
bool gfc_omp_scalar_target_p (tree);
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 4b013af09f8..71290ef815f 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -89,7 +89,8 @@ extern tree lhd_omp_array_size (tree, gimple_seq *);
extern bool lhd_omp_deep_mapping_p (const gimple *, tree);
extern tree lhd_omp_deep_mapping_cnt (gimple *, tree, gimple_seq *);
extern void lhd_omp_deep_mapping (gimple *, tree, unsigned HOST_WIDE_INT,
- tree, tree, tree, tree, tree, gimple_seq *);
+ tree, tree, tree, tree, tree, gimple_seq *,
+ vec<tree> *);
extern tree lhd_omp_mapper_lookup (tree, tree);
extern tree lhd_omp_extract_mapper_directive (tree);
extern tree lhd_omp_map_array_section (location_t, tree);
diff --git a/gcc/langhooks.cc b/gcc/langhooks.cc
index 2c62a077451..1695aed911b 100644
--- a/gcc/langhooks.cc
+++ b/gcc/langhooks.cc
@@ -665,7 +665,7 @@ lhd_omp_deep_mapping_cnt (gimple *, tree, gimple_seq *)
void
lhd_omp_deep_mapping (gimple *, tree, unsigned HOST_WIDE_INT, tree, tree,
- tree, tree, tree, gimple_seq *)
+ tree, tree, tree, gimple_seq *, vec<tree> *)
{
}
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index d6b51263d85..d95e5cb109a 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -326,7 +326,8 @@ struct lang_hooks_for_decls
void (*omp_deep_mapping) (gimple *stmt, tree clause,
unsigned HOST_WIDE_INT tkind,
tree data, tree sizes, tree kinds,
- tree offset_data, tree offset, gimple_seq *seq);
+ tree offset_data, tree offset, gimple_seq *seq,
+ vec<tree> *);
/* Finish language-specific processing on mapping nodes after expanding
user-defined mappers. */
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index 3c4835ab9bc..172845f84cf 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -12688,60 +12688,46 @@ lower_omp_map_iterator_size (tree size, tree c,
gomp_target *stmt)
}
static void
-allocate_omp_iterator_elems (tree clauses, gimple_seq loops_seq)
+allocate_omp_iterator_elems (tree iters, gimple_seq loops_seq)
{
- for (tree c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
- {
- if (!OMP_CLAUSE_HAS_ITERATORS (c))
- continue;
- tree iters = OMP_CLAUSE_ITERATORS (c);
- tree elems = OMP_ITERATORS_ELEMS (iters);
- if (!POINTER_TYPE_P (TREE_TYPE (elems)))
- continue;
- tree arr_length
- = omp_iterator_elems_length (OMP_ITERATORS_COUNT (iters));
- tree call = builtin_decl_explicit (BUILT_IN_MALLOC);
- tree size = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR,
- size_type_node, arr_length,
- TYPE_SIZE_UNIT (ptr_type_node));
- tree tmp = build_call_expr_loc (OMP_CLAUSE_LOCATION (c), call, 1,
- size);
-
- /* Find the first statement '<index> = -1' in the pre-loop statements.
*/
- tree index = OMP_ITERATORS_INDEX (iters);
- gimple_stmt_iterator gsi;
- for (gsi = gsi_start (loops_seq); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- if (gimple_code (stmt) == GIMPLE_ASSIGN
- && gimple_assign_lhs (stmt) == index
- && gimple_assign_rhs1 (stmt) == size_int (-1))
- break;
- }
- gcc_assert (!gsi_end_p (gsi));
+ tree elems = OMP_ITERATORS_ELEMS (iters);
+ if (!POINTER_TYPE_P (TREE_TYPE (elems)))
+ return;
+ tree arr_length = omp_iterator_elems_length (OMP_ITERATORS_COUNT (iters));
+ tree call = builtin_decl_explicit (BUILT_IN_MALLOC);
+ tree size = fold_build2 (MULT_EXPR, size_type_node, arr_length,
+ TYPE_SIZE_UNIT (ptr_type_node));
+ tree tmp = build_call_expr (call, 1, size);
+
+ /* Find the first statement '<index> = -1' in the pre-loop statements. */
+ tree index = OMP_ITERATORS_INDEX (iters);
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start (loops_seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_ASSIGN
+ && gimple_assign_lhs (stmt) == index
+ && gimple_assign_rhs1 (stmt) == size_int (-1))
+ break;
+ }
+ gcc_assert (!gsi_end_p (gsi));
- gimple_seq alloc_seq = NULL;
- gimplify_assign (elems, tmp, &alloc_seq);
- gsi_insert_seq_before (&gsi, alloc_seq, GSI_SAME_STMT);
- }
+ gimple_seq alloc_seq = NULL;
+ gimplify_assign (elems, tmp, &alloc_seq);
+ gsi_insert_seq_before (&gsi, alloc_seq, GSI_SAME_STMT);
}
static void
-free_omp_iterator_elems (tree clauses, gimple_seq *seq)
+free_omp_iterator_elems (tree iters, gimple_seq *seq)
{
- for (tree c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
- {
- if (!OMP_CLAUSE_HAS_ITERATORS (c))
- continue;
- tree elems = OMP_ITERATORS_ELEMS (OMP_CLAUSE_ITERATORS (c));
- if (!POINTER_TYPE_P (TREE_TYPE (elems)))
- continue;
- tree call = builtin_decl_explicit (BUILT_IN_FREE);
- call = build_call_expr_loc (OMP_CLAUSE_LOCATION (c), call, 1, elems);
- gimplify_and_add (call, seq);
- tree clobber = build_clobber (TREE_TYPE (elems));
- gimple_seq_add_stmt (seq, gimple_build_assign (elems, clobber));
- }
+ tree elems = OMP_ITERATORS_ELEMS (iters);
+ if (!POINTER_TYPE_P (TREE_TYPE (elems)))
+ return;
+ tree call = builtin_decl_explicit (BUILT_IN_FREE);
+ call = build_call_expr (call, 1, elems);
+ gimplify_and_add (call, seq);
+ tree clobber = build_clobber (TREE_TYPE (elems));
+ gimple_seq_add_stmt (seq, gimple_build_assign (elems, clobber));
}
/* Lower the GIMPLE_OMP_TARGET in the current statement
@@ -13147,6 +13133,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p,
omp_context *ctx)
record_vars_into (gimple_bind_vars (tgt_bind), child_fn);
}
+ auto_vec<tree> new_iterators;
+
if (ctx->record_type)
{
if (deep_map_cnt && TREE_CODE (deep_map_cnt) == INTEGER_CST)
@@ -13280,7 +13268,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p,
omp_context *ctx)
TREE_VEC_ELT (t, 1),
TREE_VEC_ELT (t, 2),
deep_map_offset_data,
- deep_map_offset, &ilist);
+ deep_map_offset, &ilist,
+ &new_iterators);
}
if (!DECL_P (ovar))
{
@@ -14424,12 +14413,22 @@ lower_omp_target (gimple_stmt_iterator *gsi_p,
omp_context *ctx)
gimple_omp_set_body (stmt, new_body);
}
- allocate_omp_iterator_elems (clauses,
- gimple_omp_target_iterator_loops (stmt));
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_HAS_ITERATORS (c))
+ allocate_omp_iterator_elems (OMP_CLAUSE_ITERATORS (c),
+ gimple_omp_target_iterator_loops (stmt));
+ unsigned i;
+ tree it;
+ FOR_EACH_VEC_ELT (new_iterators, i, it)
+ allocate_omp_iterator_elems (it, gimple_omp_target_iterator_loops (stmt));
gsi_insert_seq_before (gsi_p, gimple_omp_target_iterator_loops (stmt),
GSI_SAME_STMT);
gimple_omp_target_set_iterator_loops (stmt, NULL);
- free_omp_iterator_elems (clauses, &olist);
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_HAS_ITERATORS (c))
+ free_omp_iterator_elems (OMP_CLAUSE_ITERATORS (c), &olist);
+ FOR_EACH_VEC_ELT (new_iterators, i, it)
+ free_omp_iterator_elems (it, &olist);
bind = gimple_build_bind (NULL, NULL,
tgt_bind ? gimple_bind_block (tgt_bind)
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90
b/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90
index 483ab0c335b..120236ac3de 100644
--- a/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90
+++ b/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90
@@ -5,6 +5,7 @@ type t
end type t
type(t) :: x(N), y(N), z(N)
integer :: i, j
+integer :: lo = 3, hi = N
!$omp target map(iterator (it=1:N), to: x(it))
do i = 1, N
@@ -50,7 +51,7 @@ end do
end do
!$omp end target
-!$omp target map(iterator (it=3:N), always, tofrom: z(it))
+!$omp target map(iterator (it=lo:hi), always, tofrom: z(it))
do i = 3, N
if (.not.allocated(z(i)%b)) stop 12
if (any (z(i)%b /= 99)) stop 13
--
2.43.0