+2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * 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.
+
2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
* gimplify.cc (enter_omp_iterator_loop_context): New function variant.
+2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * 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.
+
2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
* trans-openmp.cc (gfc_omp_deep_mapping_map): Remove const from ctx
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);
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, target_stmt);
data_expr = OMP_ITERATORS_ELEMS (data_iter);
if (TREE_CODE (TREE_TYPE (data_expr)) == ARRAY_TYPE)
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,
target_stmt);
data_addr_expr = OMP_ITERATORS_ELEMS (data_addr_iter);
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 *, tree);
+ gimple_seq *, gimple *, tree,
+ vec <tree> *);
/* Map allocatable components. */
static void
tree *token, unsigned HOST_WIDE_INT tkind,
tree data_array, tree sizes_array, tree kinds_array,
tree offset_data, tree offset, tree num,
- gimple_seq *seq, gimple *ctx, tree iterators)
+ gimple_seq *seq, gimple *ctx, tree iterators,
+ vec <tree> *new_iterators)
{
tree type = TREE_TYPE (decl);
if (TREE_CODE (type) != RECORD_TYPE)
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, iterators);
+ seq, ctx, iterators, new_iterators);
}
else if (GFC_DECL_GET_SCALAR_POINTER (field)
|| GFC_DESCRIPTOR_TYPE_P (type))
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, iterators);
+ seq, ctx, 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,
- iterators);
+ iterators, new_iterators);
}
}
}
unsigned HOST_WIDE_INT tkind, tree data_array,
tree sizes_array, tree kinds_array, tree offset_data,
tree offset, tree num, gimple_seq *seq,
- gimple *ctx, tree iterators)
+ gimple *ctx, tree iterators,
+ vec<tree> *new_iterators)
{
static tree map_fn = NULL_TREE;
static tree cnt_fn = NULL_TREE;
tkind2 = GOMP_MAP_TOFROM;
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);
}
else if (do_copy)
{
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);
}
/* Handle allocatable components. */
gfc_omp_deep_mapping_comps (is_cnt, loc, decl, token, tkind,
data_array, sizes_array, kinds_array,
offset_data, offset, num, seq, ctx,
- iterators);
+ iterators, new_iterators);
gimple_seq_add_seq (seq, seq2);
}
if (end_label)
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);
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,
- 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,
- 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,
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. */
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
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> *);
tree gfc_omp_finish_mapper_clauses (tree);
tree gfc_omp_extract_mapper_directive (tree);
tree gfc_omp_map_array_section (location_t, tree);
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_finish_mapper_clauses (tree);
extern tree lhd_omp_mapper_lookup (tree, tree);
extern tree lhd_omp_extract_mapper_directive (tree);
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> *)
{
}
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. */
}
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
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)
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 (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_GRID
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)
+2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * testsuite/libgomp.fortran/allocatable-comp-iterators.f90: Add test
+ for non-const iterator boundaries.
+
2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
* testsuite/libgomp.fortran/allocatable-comp-iterators.f90: New.
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
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