https://gcc.gnu.org/g:ae60c1e09fe11c7b9e33478d016ca5c6251884d2

commit ae60c1e09fe11c7b9e33478d016ca5c6251884d2
Author: Kwok Cheung Yeung <kcye...@baylibre.com>
Date:   Fri Feb 14 15:26:00 2025 +0000

    openmp, fortran: Add iterator support for Fortran deep-mapping of 
allocatables
    
    gcc/fortran/
    
            * 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.
    
    gcc/
    
            * 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.
    
    libgomp/
    
            * testsuite/libgomp.fortran/allocatable-comp-iterators.f90: New.

Diff:
---
 gcc/ChangeLog.omp                                  | 26 ++++++
 gcc/fortran/ChangeLog.omp                          | 23 +++++
 gcc/fortran/trans-openmp.cc                        | 98 +++++++++++++++++-----
 gcc/fortran/trans.h                                |  4 +-
 gcc/gimplify.cc                                    | 87 ++++++++++++++-----
 gcc/gimplify.h                                     |  8 +-
 gcc/langhooks-def.h                                |  4 +-
 gcc/langhooks.cc                                   |  4 +-
 gcc/langhooks.h                                    |  4 +-
 gcc/omp-low.cc                                     | 50 +----------
 libgomp/ChangeLog.omp                              |  4 +
 .../libgomp.fortran/allocatable-comp-iterators.f90 | 60 +++++++++++++
 12 files changed, 272 insertions(+), 100 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 035396457fa1..5a102279c1e3 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,29 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@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  <kcye...@baylibre.com>
 
        * gimplify.cc (add_new_omp_iterators_clause): New.
diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index 1d05abede709..f9412db0a49e 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,26 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@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  <kcye...@baylibre.com>
 
        * openmp.cc (gfc_omp_instantiate_mapper): Add argument for namespace.
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index f94de6a425cb..c428831157b5 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -2375,7 +2375,8 @@ static void
 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);
 
@@ -2386,26 +2387,65 @@ gfc_omp_deep_mapping_map (tree data, tree size, 
unsigned HOST_WIDE_INT tkind,
       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);
@@ -2415,7 +2455,7 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned 
HOST_WIDE_INT tkind,
   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. */
@@ -2433,6 +2473,12 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned 
HOST_WIDE_INT 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);
@@ -2442,7 +2488,7 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned 
HOST_WIDE_INT tkind,
   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
@@ -2467,7 +2513,7 @@ gfc_omp_deep_mapping_map (tree data, tree size, unsigned 
HOST_WIDE_INT tkind,
 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
@@ -2475,7 +2521,7 @@ gfc_omp_deep_mapping_comps (bool is_cnt, location_t loc, 
tree decl,
                            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)
@@ -2493,7 +2539,7 @@ 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);
+                                    seq, ctx, iterators);
        }
       else if (GFC_DECL_GET_SCALAR_POINTER (field)
               || GFC_DESCRIPTOR_TYPE_P (type))
@@ -2506,11 +2552,12 @@ 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);
+                                      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);
        }
     }
 }
@@ -2652,7 +2699,7 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
                           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;
@@ -2721,7 +2768,8 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
       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),
@@ -2738,6 +2786,9 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
       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,
@@ -2786,7 +2837,7 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
       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);
@@ -2802,7 +2853,7 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
        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)
     {
@@ -2815,7 +2866,7 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
          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);
@@ -2836,7 +2887,7 @@ 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);
+                               offset, seq, ctx, iterators, loops_pre_seq);
     }
 
   /* Handle allocatable components. */
@@ -2929,7 +2980,8 @@ gfc_omp_deep_mapping_item (bool is_cnt, bool do_copy, 
bool do_alloc_check,
        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)
@@ -3079,7 +3131,7 @@ gfc_omp_deep_mapping_p (const gimple *ctx, tree clause)
 
 /* 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)
@@ -3173,13 +3225,15 @@ gfc_omp_deep_mapping_do (bool is_cnt, const gimple 
*ctx, tree clause,
       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,
@@ -3192,7 +3246,7 @@ gfc_omp_deep_mapping_do (bool is_cnt, const gimple *ctx, 
tree clause,
 /* 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);
@@ -3200,7 +3254,7 @@ gfc_omp_deep_mapping_cnt (const gimple *ctx, tree clause, 
gimple_seq *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)
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 6c6c5029ff93..972b7c41f832 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -835,8 +835,8 @@ tree gfc_omp_clause_linear_ctor (tree, tree, tree, tree);
 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);
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 19640113ab53..9c9a0717f6b4 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -10024,6 +10024,16 @@ enter_omp_iterator_loop_context_1 (tree iterator, 
gimple_seq *loops_seq_p)
   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.  */
@@ -10035,12 +10045,8 @@ enter_omp_iterator_loop_context (tree c, gimple_seq 
*loops_seq_p,
   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
@@ -10055,6 +10061,14 @@ enter_omp_iterator_loop_context (tree c, gomp_target 
*stmt,
   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
@@ -10062,23 +10076,39 @@ exit_omp_iterator_loop_context (tree c)
 {
   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.  */
@@ -10115,10 +10145,25 @@ add_new_omp_iterators_clause (tree c, gimple_seq 
*loops_seq_p)
   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,
diff --git a/gcc/gimplify.h b/gcc/gimplify.h
index 644b390d46c4..aba11e02d43a 100644
--- a/gcc/gimplify.h
+++ b/gcc/gimplify.h
@@ -80,9 +80,13 @@ extern tree omp_get_construct_context (void);
 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 *);
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 36d03e6088ff..3836629bb148 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -87,8 +87,8 @@ extern tree lhd_omp_assignment (tree, tree, tree);
 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);
diff --git a/gcc/langhooks.cc b/gcc/langhooks.cc
index ead29aa58ba7..3f81c6639cb5 100644
--- a/gcc/langhooks.cc
+++ b/gcc/langhooks.cc
@@ -653,7 +653,7 @@ lhd_omp_deep_mapping_p (const gimple *, 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;
 }
@@ -661,7 +661,7 @@ lhd_omp_deep_mapping_cnt (const gimple *, tree, gimple_seq 
*)
 /* 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 *)
 {
 }
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 05d2d140c3c8..1d2a3a7a2365 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -319,11 +319,11 @@ struct lang_hooks_for_decls
 
   /* 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);
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index f05015f62288..0a9c131aafff 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -13669,26 +13669,9 @@ lower_omp_map_iterator_expr (tree expr, tree c, 
gomp_target *stmt)
     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
@@ -13706,29 +13689,7 @@ lower_omp_map_iterator_size (tree size, tree c, 
gomp_target *stmt)
     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);
 }
@@ -13989,11 +13950,6 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
omp_context *ctx)
            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
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index e441b06073db..6c7d6531e8a2 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,7 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
+
+       * testsuite/libgomp.fortran/allocatable-comp-iterators.f90: New.
+
 2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
 
        * testsuite/libgomp.fortran/mapper-iterators-1.f90: New test.
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90 
b/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90
new file mode 100644
index 000000000000..483ab0c335b8
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable-comp-iterators.f90
@@ -0,0 +1,60 @@
+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

Reply via email to