+2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * gimplify.cc (enter_omp_iterator_loop_context): New function variant.
+ (enter_omp_iterator_loop_context): Delegate to new variant.
+ (exit_omp_iterator_loop_context): New function variant.
+ (exit_omp_iterator_loop_context): Delegate to new variant.
+ (assign_to_iterator_elems_array): New.
+ (add_new_omp_iterators_entry): New.
+ (add_new_omp_iterators_clause): Delegate to
+ add_new_omp_iterators_entry.
+ * gimplify.h (enter_omp_iterator_loop_context): New prototype.
+ (enter_omp_iterator_loop_context): Remove default argument.
+ (exit_omp_iterator_loop_context): Remove argument.
+ (assign_to_iterator_elems_array): New prototype.
+ (add_new_omp_iterators_entry): New prototype.
+ (add_new_omp_iterators_clause): New prototype.
+ * langhooks-def.h (lhd_omp_deep_mapping_cnt): Remove const from
+ argument.
+ (lhd_omp_deep_mapping): Likewise.
+ * langhooks.h (omp_deep_mapping_cnt): Likewise.
+ (omp_deep_mapping): Likewise.
+ * omp-low.cc (lower_omp_map_iterator_expr): Delegate to
+ assign_to_iterator_elems_array.
+ (lower_omp_map_iterator_size): Likewise.
+ (lower_omp_target): Remove sorry for deep mapping.
+
2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
* gimplify.cc (add_new_omp_iterators_clause): New.
+2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * trans-openmp.cc (gfc_omp_deep_mapping_map): Remove const from ctx
+ argument. Add arguments for iterators and the statement sequence to
+ go into the iterator loop. Add statement sequence to iterator loop
+ body. Generate iterator loop entries for generated maps, insert
+ the map decls and sizes into the iterator element arrays, replace
+ original decls with the address of the element arrays, and
+ sizes/biases with SIZE_INT.
+ (gfc_omp_deep_mapping_comps): Remove const from ctx. Add argument for
+ iterators. Pass iterators to calls to gfc_omp_deep_mapping_item and
+ gfc_omp_deep_mapping_comps.
+ (gfc_omp_deep_mapping_item): Remove const from ctx. Add argument for
+ iterators. Collect generated side-effect statements and pass to
+ gfc_omp_deep_mapping_map along with the iterators. Pass iterators
+ to gfc_omp_deep_mapping_comps.
+ (gfc_omp_deep_mapping_do): Remove const from ctx. Pass iterators to
+ gfc_omp_deep_mapping_item.
+ (gfc_omp_deep_mapping_cnt): Remove const from ctx.
+ (gfc_omp_deep_mapping): Likewise.
+ * trans.h (gfc_omp_deep_mapping_cnt): Likewise.
+ (gfc_omp_deep_mapping): Likewise.
+
2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
* openmp.cc (gfc_omp_instantiate_mapper): Add argument for namespace.
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, const gimple *ctx)
+ gimple_seq *seq, gimple *ctx,
+ tree iterators, gimple_seq loops_pre_seq)
{
tree one = build_int_cst (size_type_node, 1);
data = TREE_OPERAND (data, 0);
}
+ gomp_target *target_stmt = as_a<gomp_target *> (ctx);
+ gimple_seq *loops_seq_p = gimple_omp_target_iterator_loops_ptr (target_stmt);
+
+ if (loops_pre_seq)
+ {
+ gimple_seq *loop_body_p
+ = enter_omp_iterator_loop_context (iterators, loops_seq_p);
+ gimple_seq_add_seq (loop_body_p, loops_pre_seq);
+ exit_omp_iterator_loop_context ();
+ }
+
+ tree data_expr = data;
+ tree data_iter = NULL_TREE;
+ if (iterators)
+ {
+ data_iter = add_new_omp_iterators_entry (iterators, loops_seq_p);
+ 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)
+ data_expr = build_fold_addr_expr_with_type (data_expr, ptr_type_node);
+ }
/* data_array[offset_data] = data; */
tree tmp = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (data_array)),
unshare_expr (data_array), offset_data,
NULL_TREE, NULL_TREE);
- gimplify_assign (tmp, data, seq);
+ gimplify_assign (tmp, data_expr, seq);
/* offset_data++ */
tmp = build2_loc (loc, PLUS_EXPR, size_type_node, offset_data, one);
gimplify_assign (offset_data, tmp, seq);
+ tree data_addr_expr = build_fold_addr_expr (data);
+ tree data_addr_iter = NULL_TREE;
+ if (iterators)
+ {
+ data_addr_iter = add_new_omp_iterators_entry (iterators, loops_seq_p);
+ assign_to_iterator_elems_array (data_addr_expr, data_addr_iter,
+ target_stmt);
+ data_addr_expr = OMP_ITERATORS_ELEMS (data_addr_iter);
+ if (TREE_CODE (TREE_TYPE (data_addr_expr)) == ARRAY_TYPE)
+ data_addr_expr = build_fold_addr_expr_with_type (data_addr_expr,
+ ptr_type_node);
+ }
/* data_array[offset_data] = &data; */
tmp = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (data_array)),
unshare_expr (data_array),
offset_data, NULL_TREE, NULL_TREE);
- gimplify_assign (tmp, build_fold_addr_expr (data), seq);
+ gimplify_assign (tmp, data_addr_expr, seq);
/* offset_data++ */
tmp = build2_loc (loc, PLUS_EXPR, size_type_node, offset_data, one);
gimplify_assign (offset_data, tmp, seq);
+ tree size_expr = size;
+ if (iterators)
+ {
+ assign_to_iterator_elems_array (size_expr, data_iter, target_stmt, 1);
+ size_expr = size_int (SIZE_MAX);
+ }
/* sizes_array[offset] = size */
tmp = build2_loc (loc, MULT_EXPR, size_type_node,
TYPE_SIZE_UNIT (size_type_node), offset);
tmp = force_gimple_operand (tmp, &seq2, true, NULL_TREE);
gimple_seq_add_seq (seq, seq2);
tmp = build_fold_indirect_ref_loc (loc, tmp);
- gimplify_assign (tmp, size, seq);
+ gimplify_assign (tmp, size_expr, seq);
/* FIXME: tkind |= talign << talign_shift; */
/* kinds_array[offset] = tkind. */
tmp = build2_loc (loc, PLUS_EXPR, size_type_node, offset, one);
gimplify_assign (offset, tmp, seq);
+ tree bias_expr = build_zero_cst (size_type_node);
+ if (iterators)
+ {
+ assign_to_iterator_elems_array (bias_expr, data_addr_iter, target_stmt, 1);
+ bias_expr = size_int (SIZE_MAX);
+ }
/* sizes_array[offset] = bias (= 0). */
tmp = build2_loc (loc, MULT_EXPR, size_type_node,
TYPE_SIZE_UNIT (size_type_node), offset);
tmp = force_gimple_operand (tmp, &seq2, true, NULL_TREE);
gimple_seq_add_seq (seq, seq2);
tmp = build_fold_indirect_ref_loc (loc, tmp);
- gimplify_assign (tmp, build_zero_cst (size_type_node), seq);
+ gimplify_assign (tmp, bias_expr, seq);
gcc_assert (gimple_code (ctx) == GIMPLE_OMP_TARGET);
tkind = (gimple_omp_target_kind (ctx) == GF_OMP_TARGET_KIND_EXIT_DATA
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 *, const gimple *);
+ gimple_seq *, gimple *, 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, const gimple *ctx)
+ gimple_seq *seq, gimple *ctx, tree 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);
+ seq, ctx, 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);
+ seq, ctx, 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);
+ offset_data, offset, num, seq, ctx,
+ 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,
- const gimple *ctx)
+ gimple *ctx, tree iterators)
{
static tree map_fn = NULL_TREE;
static tree cnt_fn = NULL_TREE;
field = gfc_omp_get_token_flags (*token);
tmp = build_int_cstu (short_unsigned_type_node, tkind);
gimplify_assign (fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field),
- *token, field, NULL_TREE), tmp, seq);
+ *token, field, NULL_TREE), tmp,
+ seq);
/* token.detach = (ctx == EXIT_DATA) */
field = gfc_omp_get_token_detach (*token);
gimplify_assign (fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field),
map_fn = build_fold_addr_expr (gfc_omp_gen_deep_map_fn (false));
}
+ gimple_seq loops_pre_seq = NULL;
+ gimple_seq *loops_pre_seq_p = iterators ? &loops_pre_seq : seq;
+
if (is_cnt && do_copy)
{
tree tmp = fold_build2_loc (input_location, PLUS_EXPR, size_type_node,
if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
{
elem_len = bytesize;
- size = gfc_omp_get_array_size (loc, tmp, seq);
+ size = gfc_omp_get_array_size (loc, tmp, loops_pre_seq_p);
bytesize = fold_build2_loc (loc, MULT_EXPR, size_type_node,
size, elem_len);
tmp = gfc_conv_descriptor_data_get (tmp);
tkind2 = GOMP_MAP_TOFROM;
gfc_omp_deep_mapping_map (tmp, bytesize, tkind2, loc, data_array,
sizes_array, kinds_array, offset_data,
- offset, seq, ctx);
+ offset, seq, ctx, iterators, loops_pre_seq);
}
else if (do_copy)
{
elem_len = gfc_conv_descriptor_elem_len (decl);
tmp = (POINTER_TYPE_P (TREE_TYPE (decl))
? build_fold_indirect_ref (decl) : decl);
- size = gfc_omp_get_array_size (loc, tmp, seq);
+ size = gfc_omp_get_array_size (loc, tmp, loops_pre_seq_p);
bytesize = fold_build2_loc (loc, MULT_EXPR, size_type_node,
size, elem_len);
tmp = gfc_conv_descriptor_data_get (decl);
gfc_omp_deep_mapping_map (tmp, bytesize, tkind2, loc, data_array,
sizes_array, kinds_array, offset_data,
- offset, seq, ctx);
+ offset, seq, ctx, iterators, loops_pre_seq);
}
/* Handle allocatable components. */
decl = build_fold_indirect_ref (decl);
gfc_omp_deep_mapping_comps (is_cnt, loc, decl, token, tkind,
data_array, sizes_array, kinds_array,
- offset_data, offset, num, seq, ctx);
+ offset_data, offset, num, seq, ctx,
+ iterators);
gimple_seq_add_seq (seq, seq2);
}
if (end_label)
/* Handle gfc_omp_deep_mapping{,_cnt} */
static tree
-gfc_omp_deep_mapping_do (bool is_cnt, const gimple *ctx, tree clause,
+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_add_stmt (seq, gimple_build_label (then_label));
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);
+ offset_data, offset, num, seq, ctx,
+ OMP_CLAUSE_ITERATORS (clause));
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);
+ offset, num, seq, ctx,
+ OMP_CLAUSE_ITERATORS (clause));
/* Multiply by 2 as there are two mappings: data + pointer assign. */
if (is_cnt)
gimplify_assign (num,
/* Return tree with a variable which contains the count of deep-mappyings
(value depends, e.g., on allocation status) */
tree
-gfc_omp_deep_mapping_cnt (const gimple *ctx, tree clause, gimple_seq *seq)
+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);
/* Does the actual deep mapping. */
void
-gfc_omp_deep_mapping (const gimple *ctx, tree clause,
+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)
tree gfc_omp_clause_dtor (tree, tree);
void gfc_omp_finish_clause (tree, gimple_seq *, bool);
bool gfc_omp_deep_mapping_p (const gimple *, tree);
-tree gfc_omp_deep_mapping_cnt (const gimple *, tree, gimple_seq *);
-void gfc_omp_deep_mapping (const gimple *, tree, unsigned HOST_WIDE_INT, 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 gfc_omp_finish_mapper_clauses (tree);
tree gfc_omp_extract_mapper_directive (tree);
return NULL;
}
+gimple_seq *
+enter_omp_iterator_loop_context (tree iterator, gimple_seq *loops_seq_p)
+{
+ push_gimplify_context ();
+
+ gimple_seq *seq = enter_omp_iterator_loop_context_1 (iterator, loops_seq_p);
+ gcc_assert (seq);
+ return seq;
+}
+
/* Enter the Gimplification context in LOOPS_SEQ_P for the iterator loop
associated with OpenMP clause C. Returns the gimple_seq for the loop body
if C has OpenMP iterators, or ALT_SEQ_P if not. */
if (!OMP_CLAUSE_HAS_ITERATORS (c))
return alt_seq_p;
- push_gimplify_context ();
-
- gimple_seq *seq = enter_omp_iterator_loop_context_1 (OMP_CLAUSE_ITERATORS (c),
- loops_seq_p);
- gcc_assert (seq);
- return seq;
+ return enter_omp_iterator_loop_context (OMP_CLAUSE_ITERATORS (c),
+ loops_seq_p);
}
/* Enter the Gimplification context in STMT for the iterator loop associated
return enter_omp_iterator_loop_context (c, loops_seq_p, alt_seq_p);
}
+void
+exit_omp_iterator_loop_context (void)
+{
+ while (!gimplify_ctxp->bind_expr_stack.is_empty ())
+ gimple_pop_bind_expr ();
+ pop_gimplify_context (NULL);
+}
+
/* Exit the Gimplification context for the OpenMP clause C. */
void
{
if (!OMP_CLAUSE_HAS_ITERATORS (c))
return;
- while (!gimplify_ctxp->bind_expr_stack.is_empty ())
- gimple_pop_bind_expr ();
- pop_gimplify_context (NULL);
+ exit_omp_iterator_loop_context ();
}
-/* Insert new OpenMP clause C into pre-existing iterator loop LOOPS_SEQ_P.
- If the clause has an iterator, then that iterator is assumed to be in
- the expanded form (i.e. it has info regarding the loop, expanded elements
- etc.). */
-
void
-add_new_omp_iterators_clause (tree c, gimple_seq *loops_seq_p)
+assign_to_iterator_elems_array (tree t, tree iterator, gomp_target *stmt,
+ int index_offset)
+{
+ tree index = OMP_ITERATORS_INDEX (iterator);
+ if (index_offset)
+ index = size_binop (PLUS_EXPR, index, size_int (index_offset));
+ tree elems = OMP_ITERATORS_ELEMS (iterator);
+ gimple_seq *loop_body_p = gimple_omp_target_iterator_loops_ptr (stmt);
+ loop_body_p = enter_omp_iterator_loop_context (iterator, loop_body_p);
+
+ /* IN LOOP BODY: */
+ /* elems[index+index_offset] = t; */
+ tree lhs;
+ if (TREE_CODE (TREE_TYPE (elems)) == ARRAY_TYPE)
+ lhs = build4 (ARRAY_REF, ptr_type_node, elems, index, NULL_TREE, NULL_TREE);
+ else
+ {
+ tree tmp = size_binop (MULT_EXPR, index, TYPE_SIZE_UNIT (ptr_type_node));
+ tmp = size_binop (POINTER_PLUS_EXPR, elems, tmp);
+ lhs = build1 (INDIRECT_REF, ptr_type_node, tmp);
+ }
+ gimplify_assign (lhs, t, loop_body_p);
+ exit_omp_iterator_loop_context ();
+}
+
+tree
+add_new_omp_iterators_entry (tree iters, gimple_seq *loops_seq_p)
{
gimple_stmt_iterator gsi;
- tree iters = OMP_CLAUSE_ITERATORS (c);
- if (!iters)
- return;
gcc_assert (OMP_ITERATORS_EXPANDED_P (iters));
/* Search for <index> = -1. */
gsi_insert_seq_after (&gsi, assign_seq, GSI_SAME_STMT);
/* Update iterator information. */
- tree new_iterator = copy_omp_iterator (OMP_CLAUSE_ITERATORS (c));
+ tree new_iterator = copy_omp_iterator (iters);
OMP_ITERATORS_ELEMS (new_iterator) = elems;
- TREE_CHAIN (new_iterator) = TREE_CHAIN (OMP_CLAUSE_ITERATORS (c));
- OMP_CLAUSE_ITERATORS (c) = new_iterator;
+ TREE_CHAIN (new_iterator) = TREE_CHAIN (iters);
+
+ return new_iterator;
+}
+
+/* Insert new OpenMP clause C into pre-existing iterator loop LOOPS_SEQ_P.
+ If the clause has an iterator, then that iterator is assumed to be in
+ the expanded form (i.e. it has info regarding the loop, expanded elements
+ etc.). */
+
+void
+add_new_omp_iterators_clause (tree c, gimple_seq *loops_seq_p)
+{
+ tree iters = OMP_CLAUSE_ITERATORS (c);
+ if (!iters)
+ return;
+ OMP_CLAUSE_ITERATORS (c) = add_new_omp_iterators_entry (iters, loops_seq_p);
}
/* If *LIST_P contains any OpenMP depend clauses with iterators,
int omp_has_novariants (void);
extern tree omp_iterator_elems_length (tree count);
+extern gimple_seq *enter_omp_iterator_loop_context (tree, gimple_seq *);
extern gimple_seq *enter_omp_iterator_loop_context (tree, gomp_target *,
- gimple_seq * = NULL);
-extern void exit_omp_iterator_loop_context (tree);
+ gimple_seq *);
+extern void exit_omp_iterator_loop_context (void);
+extern void assign_to_iterator_elems_array (tree, tree, gomp_target *, int = 0);
+extern tree add_new_omp_iterators_entry (tree, gimple_seq *);
+extern void add_new_omp_iterators_clause (tree c, gimple_seq *);
extern void gimplify_type_sizes (tree, gimple_seq *);
extern void gimplify_one_sizepos (tree *, gimple_seq *);
extern void lhd_omp_finish_clause (tree, gimple_seq *, bool);
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 (const gimple *, tree, gimple_seq *);
-extern void lhd_omp_deep_mapping (const gimple *, tree, unsigned HOST_WIDE_INT,
+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 *);
extern tree lhd_omp_finish_mapper_clauses (tree);
extern tree lhd_omp_mapper_lookup (tree, tree);
/* Returns number of additional mappings for a decl. */
tree
-lhd_omp_deep_mapping_cnt (const gimple *, tree, gimple_seq *)
+lhd_omp_deep_mapping_cnt (gimple *, tree, gimple_seq *)
{
return NULL_TREE;
}
/* Do the additional mappings. */
void
-lhd_omp_deep_mapping (const gimple *, tree, unsigned HOST_WIDE_INT, tree, tree,
+lhd_omp_deep_mapping (gimple *, tree, unsigned HOST_WIDE_INT, tree, tree,
tree, tree, tree, gimple_seq *)
{
}
/* Additional language-specific mappings for a decl; returns the
number of additional mappings needed. */
- tree (*omp_deep_mapping_cnt) (const gimple *ctx_stmt, tree clause,
+ tree (*omp_deep_mapping_cnt) (gimple *ctx_stmt, tree clause,
gimple_seq *seq);
/* Do the actual additional language-specific mappings for a decl. */
- void (*omp_deep_mapping) (const gimple *stmt, tree clause,
+ 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);
return expr;
tree iterator = OMP_CLAUSE_ITERATORS (c);
- tree index = OMP_ITERATORS_INDEX (iterator);
- tree elems = OMP_ITERATORS_ELEMS (iterator);
- gimple_seq *loop_body_p = enter_omp_iterator_loop_context (c, stmt);
-
- /* IN LOOP BODY: */
- /* elems[idx] = <expr>; */
- tree lhs;
- if (TREE_CODE (TREE_TYPE (elems)) == ARRAY_TYPE)
- lhs = build4 (ARRAY_REF, ptr_type_node, elems, index, NULL_TREE, NULL_TREE);
- else
- {
- tree tmp = size_binop (MULT_EXPR, index, TYPE_SIZE_UNIT (ptr_type_node));
- tmp = size_binop (POINTER_PLUS_EXPR, elems, tmp);
- lhs = build1 (INDIRECT_REF, ptr_type_node, tmp);
- }
- tree mod_expr = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
- void_type_node, lhs, expr);
- gimplify_and_add (mod_expr, loop_body_p);
- exit_omp_iterator_loop_context (c);
+ assign_to_iterator_elems_array (expr, iterator, stmt);
+ tree elems = OMP_ITERATORS_ELEMS (iterator);
if (TREE_CODE (TREE_TYPE (elems)) == ARRAY_TYPE)
return build_fold_addr_expr_with_type (elems, ptr_type_node);
else
return size;
tree iterator = OMP_CLAUSE_ITERATORS (c);
- tree index = OMP_ITERATORS_INDEX (iterator);
- tree elems = OMP_ITERATORS_ELEMS (iterator);
- gimple_seq *loop_body_p = enter_omp_iterator_loop_context (c, stmt);
-
- /* IN LOOP BODY: */
- /* elems[idx+1] = <size>; */
- tree lhs;
- if (TREE_CODE (TREE_TYPE (elems)) == ARRAY_TYPE)
- lhs = build4 (ARRAY_REF, ptr_type_node, elems,
- size_binop (PLUS_EXPR, index, size_int (1)),
- NULL_TREE, NULL_TREE);
- else
- {
- tree index_1 = size_binop (PLUS_EXPR, index, size_int (1));
- tree tmp = size_binop (MULT_EXPR, index_1,
- TYPE_SIZE_UNIT (ptr_type_node));
- tmp = size_binop (POINTER_PLUS_EXPR, elems, tmp);
- lhs = build1 (INDIRECT_REF, ptr_type_node, tmp);
- }
- tree mod_expr = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
- void_type_node, lhs, size);
- gimplify_and_add (mod_expr, loop_body_p);
- exit_omp_iterator_loop_context (c);
+ assign_to_iterator_elems_array (size, iterator, stmt, 1);
return size_int (SIZE_MAX);
}
deep_map_cnt = extra;
}
- if (deep_map_cnt
- && OMP_CLAUSE_HAS_ITERATORS (c))
- sorry ("iterators used together with deep mapping are not "
- "supported yet");
-
if (!DECL_P (var))
{
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
+2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
+
+ * testsuite/libgomp.fortran/allocatable-comp-iterators.f90: New.
+
2025-04-17 Kwok Cheung Yeung <kcyeung@baylibre.com>
* testsuite/libgomp.fortran/mapper-iterators-1.f90: New test.
--- /dev/null
+implicit none
+integer, parameter :: N = 16
+type t
+ integer, allocatable :: a, b(:)
+end type t
+type(t) :: x(N), y(N), z(N)
+integer :: i, j
+
+!$omp target map(iterator (it=1:N), to: x(it))
+ do i = 1, N
+ if (allocated(x(i)%a)) stop 1
+ if (allocated(x(i)%b)) stop 2
+ end do
+!$omp end target
+
+do i = 1, N
+ allocate(x(i)%a, x(i)%b(-4:6))
+ x(i)%b(:) = [(i, i=-4,6)]
+end do
+
+!$omp target map(iterator (it=2:N), to: x(it))
+ do i = 2, N
+ if (.not. allocated(x(i)%a)) stop 3
+ if (.not. allocated(x(i)%b)) stop 4
+ if (lbound(x(i)%b,1) /= -4) stop 5
+ if (ubound(x(i)%b,1) /= 6) stop 6
+ if (any (x(i)%b /= [(i, i=-4,6)])) stop 7
+ end do
+!$omp end target
+
+!$omp target enter data map(iterator (it=3:N), to: y(it), z(it))
+
+!$omp target map(iterator (it=3:N), to: y(it), z(it))
+ do i = 3, N
+ if (allocated(y(i)%b)) stop 8
+ if (allocated(z(i)%b)) stop 9
+ end do
+!$omp end target
+
+do i = 1, N
+ allocate(y(i)%b(5), z(i)%b(3))
+ y(i)%b = 42
+ z(i)%b = 99
+end do
+
+!$omp target map(iterator (it=3:N), to: y(it))
+ do i = 3, N
+ if (.not.allocated(y(i)%b)) stop 10
+ if (any (y(i)%b /= 42)) stop 11
+ end do
+!$omp end target
+
+!$omp target map(iterator (it=3:N), always, tofrom: z(it))
+ do i = 3, N
+ if (.not.allocated(z(i)%b)) stop 12
+ if (any (z(i)%b /= 99)) stop 13
+ end do
+!$omp end target
+
+end