https://gcc.gnu.org/g:76e5b71adb86c7861ae877c96546ba919c8c4e2a

commit 76e5b71adb86c7861ae877c96546ba919c8c4e2a
Author: Kwok Cheung Yeung <kcye...@baylibre.com>
Date:   Wed Nov 27 21:49:12 2024 +0000

    openmp: Refactor handling of iterators
    
    Move code to calculate the iteration size and to generate the iterator
    expansion loop into separate functions.
    
    Use OMP_ITERATOR_DECL_P to check for iterators in clause declarations.
    
    gcc/c-family/
    
            * c-omp.cc (c_finish_omp_depobj): Use OMP_ITERATOR_DECL_P.
    
    gcc/c/
    
            * c-typeck.cc (handle_omp_array_sections): Use OMP_ITERATOR_DECL_P.
            (c_finish_omp_clauses): Likewise.
    
    gcc/cp/
    
            * pt.cc (tsubst_omp_clause_decl): Use OMP_ITERATOR_DECL_P.
            * semantics.cc (handle_omp_array_sections): Likewise.
            (finish_omp_clauses): Likewise.
    
    gcc/
    
            * gimplify.cc (gimplify_omp_affinity): Use OMP_ITERATOR_DECL_P.
            (compute_omp_iterator_count): New.
            (build_omp_iterator_loop): New.
            (gimplify_omp_depend): Use OMP_ITERATOR_DECL_P,
            compute_omp_iterator_count and build_omp_iterator_loop.
            * tree-inline.cc (copy_tree_body_r): Use OMP_ITERATOR_DECL_P.
            * tree-pretty-print.cc (dump_omp_clause): Likewise.
            * tree.h (OMP_ITERATOR_DECL_P): New macro.

Diff:
---
 gcc/ChangeLog.omp          |  11 ++
 gcc/c-family/ChangeLog.omp |   4 +
 gcc/c-family/c-omp.cc      |   4 +-
 gcc/c/ChangeLog.omp        |   5 +
 gcc/c/c-typeck.cc          |  13 +-
 gcc/cp/ChangeLog.omp       |   6 +
 gcc/cp/pt.cc               |   4 +-
 gcc/cp/semantics.cc        |   8 +-
 gcc/gimplify.cc            | 321 ++++++++++++++++++++++-----------------------
 gcc/tree-inline.cc         |   5 +-
 gcc/tree-pretty-print.cc   |   8 +-
 gcc/tree.h                 |   6 +
 12 files changed, 199 insertions(+), 196 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 6988afbd2388..cfdaa58a05d8 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,14 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
+
+       * gimplify.cc (gimplify_omp_affinity): Use OMP_ITERATOR_DECL_P.
+       (compute_omp_iterator_count): New.
+       (build_omp_iterator_loop): New.
+       (gimplify_omp_depend): Use OMP_ITERATOR_DECL_P,
+       compute_omp_iterator_count and build_omp_iterator_loop.
+       * tree-inline.cc (copy_tree_body_r): Use OMP_ITERATOR_DECL_P.
+       * tree-pretty-print.cc (dump_omp_clause): Likewise.
+       * tree.h (OMP_ITERATOR_DECL_P): New macro.
+
 2025-04-17  Thomas Schwinge  <tschwi...@baylibre.com>
 
        Backported from trunk:
diff --git a/gcc/c-family/ChangeLog.omp b/gcc/c-family/ChangeLog.omp
index 8151f5a1f389..9fe71baa001c 100644
--- a/gcc/c-family/ChangeLog.omp
+++ b/gcc/c-family/ChangeLog.omp
@@ -1,3 +1,7 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
+
+       * c-omp.cc (c_finish_omp_depobj): Use OMP_ITERATOR_DECL_P.
+
 2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index fefb2b4facd2..ada8d8f03240 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -764,9 +764,7 @@ c_finish_omp_depobj (location_t loc, tree depobj,
          kind = OMP_CLAUSE_DEPEND_KIND (clause);
          t = OMP_CLAUSE_DECL (clause);
          gcc_assert (t);
-         if (TREE_CODE (t) == TREE_LIST
-             && TREE_PURPOSE (t)
-             && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+         if (OMP_ITERATOR_DECL_P (t))
            {
              error_at (OMP_CLAUSE_LOCATION (clause),
                        "%<iterator%> modifier may not be specified on "
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index 03a05cb7bbe2..41e3815e069d 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -1,3 +1,8 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
+
+       * c-typeck.cc (handle_omp_array_sections): Use OMP_ITERATOR_DECL_P.
+       (c_finish_omp_clauses): Likewise.
+
 2025-03-21  Paul-Antoine Arras  <par...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 70b15e20129c..4d4f73efa478 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -14607,9 +14607,7 @@ handle_omp_array_sections (tree *pc, tree **pnext, enum 
c_omp_region_type ort,
   tree *tp = &OMP_CLAUSE_DECL (c);
   if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
        || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
-      && TREE_CODE (*tp) == TREE_LIST
-      && TREE_PURPOSE (*tp)
-      && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC)
+      && OMP_ITERATOR_DECL_P (*tp))
     tp = &TREE_VALUE (*tp);
   tree first = handle_omp_array_sections_1 (c, *tp, types,
                                            maybe_zero_len, first_non_one,
@@ -16066,9 +16064,7 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
          /* FALLTHRU */
        case OMP_CLAUSE_AFFINITY:
          t = OMP_CLAUSE_DECL (c);
-         if (TREE_CODE (t) == TREE_LIST
-             && TREE_PURPOSE (t)
-             && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+         if (OMP_ITERATOR_DECL_P (t))
            {
              if (TREE_PURPOSE (t) != last_iterators)
                last_iterators_remove
@@ -16170,10 +16166,7 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
                      break;
                    }
                }
-             if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST
-                 && TREE_PURPOSE (OMP_CLAUSE_DECL (c))
-                 && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c)))
-                     == TREE_VEC))
+             if (OMP_ITERATOR_DECL_P (OMP_CLAUSE_DECL (c)))
                TREE_VALUE (OMP_CLAUSE_DECL (c)) = t;
              else
                OMP_CLAUSE_DECL (c) = t;
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index a19bcfa94fdd..09000189cc40 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,9 @@
+2025-04-17  Kwok Cheung Yeung  <kcye...@baylibre.com>
+
+       * pt.cc (tsubst_omp_clause_decl): Use OMP_ITERATOR_DECL_P.
+       * semantics.cc (handle_omp_array_sections): Likewise.
+       (finish_omp_clauses): Likewise.
+
 2025-03-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 91607d1d196a..996c005e42c3 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -17627,9 +17627,7 @@ tsubst_omp_clause_decl (tree decl, tree args, 
tsubst_flags_t complain,
     return decl;
 
   /* Handle OpenMP iterators.  */
-  if (TREE_CODE (decl) == TREE_LIST
-      && TREE_PURPOSE (decl)
-      && TREE_CODE (TREE_PURPOSE (decl)) == TREE_VEC)
+  if (OMP_ITERATOR_DECL_P (decl))
     {
       tree ret;
       if (iterator_cache[0] == TREE_PURPOSE (decl))
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index d24685c7224b..51cf8b960857 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -6003,9 +6003,7 @@ handle_omp_array_sections (tree *pc, tree **pnext, enum 
c_omp_region_type ort,
   tree *tp = &OMP_CLAUSE_DECL (c);
   if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
        || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
-      && TREE_CODE (*tp) == TREE_LIST
-      && TREE_PURPOSE (*tp)
-      && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC)
+      && OMP_ITERATOR_DECL_P (*tp))
     tp = &TREE_VALUE (*tp);
   tree first = handle_omp_array_sections_1 (c, *tp, types,
                                            maybe_zero_len, first_non_one,
@@ -8777,9 +8775,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
          /* FALLTHRU */
        case OMP_CLAUSE_AFFINITY:
          t = OMP_CLAUSE_DECL (c);
-         if (TREE_CODE (t) == TREE_LIST
-             && TREE_PURPOSE (t)
-             && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+         if (OMP_ITERATOR_DECL_P (t))
            {
              if (TREE_PURPOSE (t) != last_iterators)
                last_iterators_remove
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index fed72bd274ec..6e02490f43a6 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -9426,9 +9426,7 @@ gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
       {
        tree t = OMP_CLAUSE_DECL (c);
-       if (TREE_CODE (t) == TREE_LIST
-                   && TREE_PURPOSE (t)
-                   && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+       if (OMP_ITERATOR_DECL_P (t))
          {
            if (TREE_VALUE (t) == null_pointer_node)
              continue;
@@ -9533,6 +9531,155 @@ gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
   return;
 }
 
+/* Returns a tree expression containing the total iteration count of the
+   OpenMP iterator IT.  */
+
+static tree
+compute_omp_iterator_count (tree it, gimple_seq *pre_p)
+{
+  tree tcnt = size_one_node;
+  for (; it; it = TREE_CHAIN (it))
+    {
+      if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
+                        is_gimple_val, fb_rvalue) == GS_ERROR
+         || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
+                           is_gimple_val, fb_rvalue) == GS_ERROR
+         || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
+                           is_gimple_val, fb_rvalue) == GS_ERROR
+         || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
+                            is_gimple_val, fb_rvalue) == GS_ERROR))
+       return NULL_TREE;
+      tree var = TREE_VEC_ELT (it, 0);
+      tree begin = TREE_VEC_ELT (it, 1);
+      tree end = TREE_VEC_ELT (it, 2);
+      tree step = TREE_VEC_ELT (it, 3);
+      tree orig_step = TREE_VEC_ELT (it, 4);
+      tree type = TREE_TYPE (var);
+      tree stype = TREE_TYPE (step);
+      location_t loc = DECL_SOURCE_LOCATION (var);
+      tree endmbegin;
+      /* Compute count for this iterator as
+        orig_step > 0
+        ? (begin < end ? (end - begin + (step - 1)) / step : 0)
+        : (begin > end ? (end - begin + (step + 1)) / step : 0)
+        and compute product of those for the entire clause.  */
+      if (POINTER_TYPE_P (type))
+       endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR, stype, end, begin);
+      else
+       endmbegin = fold_build2_loc (loc, MINUS_EXPR, type, end, begin);
+      tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype, step,
+                                    build_int_cst (stype, 1));
+      tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
+                                    build_int_cst (stype, 1));
+      tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
+                                 unshare_expr (endmbegin), stepm1);
+      pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, pos, step);
+      tree neg = fold_build2_loc (loc, PLUS_EXPR, stype, endmbegin, stepp1);
+      if (TYPE_UNSIGNED (stype))
+       {
+         neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
+         step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
+       }
+      neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, neg, step);
+      step = NULL_TREE;
+      tree cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, begin, 
end);
+      pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
+                            build_int_cst (stype, 0));
+      cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, end, begin);
+      neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
+                            build_int_cst (stype, 0));
+      tree osteptype = TREE_TYPE (orig_step);
+      cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, orig_step,
+                             build_int_cst (osteptype, 0));
+      tree cnt = fold_build3_loc (loc, COND_EXPR, stype, cond, pos, neg);
+      cnt = fold_convert_loc (loc, sizetype, cnt);
+      if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
+                        fb_rvalue) == GS_ERROR)
+       return NULL_TREE;
+      tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
+    }
+  if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
+    return NULL_TREE;
+
+  return tcnt;
+}
+
+/* Build loops iterating over the space defined by the OpenMP iterator IT.
+   Returns a pointer to the BIND_EXPR_BODY in the innermost loop body.
+   LAST_BIND is set to point to the BIND_EXPR containing the whole loop.  */
+
+static tree *
+build_omp_iterator_loop (tree it, gimple_seq *pre_p, tree *last_bind)
+{
+  if (*last_bind)
+    gimplify_and_add (*last_bind, pre_p);
+  tree block = TREE_VEC_ELT (it, 5);
+  *last_bind = build3 (BIND_EXPR, void_type_node,
+                      BLOCK_VARS (block), NULL, block);
+  TREE_SIDE_EFFECTS (*last_bind) = 1;
+  tree *p = &BIND_EXPR_BODY (*last_bind);
+  for (; it; it = TREE_CHAIN (it))
+    {
+      tree var = TREE_VEC_ELT (it, 0);
+      tree begin = TREE_VEC_ELT (it, 1);
+      tree end = TREE_VEC_ELT (it, 2);
+      tree step = TREE_VEC_ELT (it, 3);
+      tree orig_step = TREE_VEC_ELT (it, 4);
+      tree type = TREE_TYPE (var);
+      location_t loc = DECL_SOURCE_LOCATION (var);
+      /* Emit:
+        var = begin;
+        goto cond_label;
+        beg_label:
+        ...
+        var = var + step;
+        cond_label:
+        if (orig_step > 0) {
+          if (var < end) goto beg_label;
+        } else {
+          if (var > end) goto beg_label;
+        }
+        for each iterator, with inner iterators added to
+        the ... above.  */
+      tree beg_label = create_artificial_label (loc);
+      tree cond_label = NULL_TREE;
+      tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node, var, begin);
+      append_to_statement_list_force (tem, p);
+      tem = build_and_jump (&cond_label);
+      append_to_statement_list_force (tem, p);
+      tem = build1 (LABEL_EXPR, void_type_node, beg_label);
+      append_to_statement_list (tem, p);
+      tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
+                         NULL_TREE, NULL_TREE);
+      TREE_SIDE_EFFECTS (bind) = 1;
+      SET_EXPR_LOCATION (bind, loc);
+      append_to_statement_list_force (bind, p);
+      if (POINTER_TYPE_P (type))
+       tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
+                         var, fold_convert_loc (loc, sizetype, step));
+      else
+       tem = build2_loc (loc, PLUS_EXPR, type, var, step);
+      tem = build2_loc (loc, MODIFY_EXPR, void_type_node, var, tem);
+      append_to_statement_list_force (tem, p);
+      tem = build1 (LABEL_EXPR, void_type_node, cond_label);
+      append_to_statement_list (tem, p);
+      tree cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, var, end);
+      tree pos = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
+                                 build_and_jump (&beg_label), void_node);
+      cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, var, end);
+      tree neg = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
+                                 build_and_jump (&beg_label), void_node);
+      tree osteptype = TREE_TYPE (orig_step);
+      cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, orig_step,
+                             build_int_cst (osteptype, 0));
+      tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, pos, neg);
+      append_to_statement_list_force (tem, p);
+      p = &BIND_EXPR_BODY (bind);
+    }
+
+  return p;
+}
+
 /* If *LIST_P contains any OpenMP depend clauses with iterators,
    lower all the depend clauses by populating corresponding depend
    array.  Returns 0 if there are no such depend clauses, or
@@ -9577,89 +9724,13 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
        tree t = OMP_CLAUSE_DECL (c);
        if (first_loc == UNKNOWN_LOCATION)
          first_loc = OMP_CLAUSE_LOCATION (c);
-       if (TREE_CODE (t) == TREE_LIST
-           && TREE_PURPOSE (t)
-           && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+       if (OMP_ITERATOR_DECL_P (t))
          {
            if (TREE_PURPOSE (t) != last_iter)
              {
-               tree tcnt = size_one_node;
-               for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
-                 {
-                   if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
-                                      is_gimple_val, fb_rvalue) == GS_ERROR
-                       || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
-                                         is_gimple_val, fb_rvalue) == GS_ERROR
-                       || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
-                                         is_gimple_val, fb_rvalue) == GS_ERROR
-                       || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
-                                          is_gimple_val, fb_rvalue)
-                           == GS_ERROR))
-                     return 2;
-                   tree var = TREE_VEC_ELT (it, 0);
-                   tree begin = TREE_VEC_ELT (it, 1);
-                   tree end = TREE_VEC_ELT (it, 2);
-                   tree step = TREE_VEC_ELT (it, 3);
-                   tree orig_step = TREE_VEC_ELT (it, 4);
-                   tree type = TREE_TYPE (var);
-                   tree stype = TREE_TYPE (step);
-                   location_t loc = DECL_SOURCE_LOCATION (var);
-                   tree endmbegin;
-                   /* Compute count for this iterator as
-                      orig_step > 0
-                      ? (begin < end ? (end - begin + (step - 1)) / step : 0)
-                      : (begin > end ? (end - begin + (step + 1)) / step : 0)
-                      and compute product of those for the entire depend
-                      clause.  */
-                   if (POINTER_TYPE_P (type))
-                     endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
-                                                  stype, end, begin);
-                   else
-                     endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
-                                                  end, begin);
-                   tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
-                                                  step,
-                                                  build_int_cst (stype, 1));
-                   tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
-                                                  build_int_cst (stype, 1));
-                   tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
-                                               unshare_expr (endmbegin),
-                                               stepm1);
-                   pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
-                                          pos, step);
-                   tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
-                                               endmbegin, stepp1);
-                   if (TYPE_UNSIGNED (stype))
-                     {
-                       neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
-                       step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
-                     }
-                   neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
-                                          neg, step);
-                   step = NULL_TREE;
-                   tree cond = fold_build2_loc (loc, LT_EXPR,
-                                                boolean_type_node,
-                                                begin, end);
-                   pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
-                                          build_int_cst (stype, 0));
-                   cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
-                                           end, begin);
-                   neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
-                                          build_int_cst (stype, 0));
-                   tree osteptype = TREE_TYPE (orig_step);
-                   cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
-                                           orig_step,
-                                           build_int_cst (osteptype, 0));
-                   tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
-                                               cond, pos, neg);
-                   cnt = fold_convert_loc (loc, sizetype, cnt);
-                   if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
-                                      fb_rvalue) == GS_ERROR)
-                     return 2;
-                   tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
-                 }
-               if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
-                                  fb_rvalue) == GS_ERROR)
+               tree tcnt = compute_omp_iterator_count (TREE_PURPOSE (t),
+                                                       pre_p);
+               if (!tcnt)
                  return 2;
                last_iter = TREE_PURPOSE (t);
                last_count = tcnt;
@@ -9813,91 +9884,13 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
            gcc_unreachable ();
          }
        tree t = OMP_CLAUSE_DECL (c);
-       if (TREE_CODE (t) == TREE_LIST
-           && TREE_PURPOSE (t)
-           && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+       if (OMP_ITERATOR_DECL_P (t))
          {
            if (TREE_PURPOSE (t) != last_iter)
              {
-               if (last_bind)
-                 gimplify_and_add (last_bind, pre_p);
-               tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
-               last_bind = build3 (BIND_EXPR, void_type_node,
-                                   BLOCK_VARS (block), NULL, block);
-               TREE_SIDE_EFFECTS (last_bind) = 1;
+               last_body = build_omp_iterator_loop (TREE_PURPOSE (t), pre_p,
+                                                    &last_bind);
                SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
-               tree *p = &BIND_EXPR_BODY (last_bind);
-               for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
-                 {
-                   tree var = TREE_VEC_ELT (it, 0);
-                   tree begin = TREE_VEC_ELT (it, 1);
-                   tree end = TREE_VEC_ELT (it, 2);
-                   tree step = TREE_VEC_ELT (it, 3);
-                   tree orig_step = TREE_VEC_ELT (it, 4);
-                   tree type = TREE_TYPE (var);
-                   location_t loc = DECL_SOURCE_LOCATION (var);
-                   /* Emit:
-                      var = begin;
-                      goto cond_label;
-                      beg_label:
-                      ...
-                      var = var + step;
-                      cond_label:
-                      if (orig_step > 0) {
-                        if (var < end) goto beg_label;
-                      } else {
-                        if (var > end) goto beg_label;
-                      }
-                      for each iterator, with inner iterators added to
-                      the ... above.  */
-                   tree beg_label = create_artificial_label (loc);
-                   tree cond_label = NULL_TREE;
-                   tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
-                                     var, begin);
-                   append_to_statement_list_force (tem, p);
-                   tem = build_and_jump (&cond_label);
-                   append_to_statement_list_force (tem, p);
-                   tem = build1 (LABEL_EXPR, void_type_node, beg_label);
-                   append_to_statement_list (tem, p);
-                   tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
-                                       NULL_TREE, NULL_TREE);
-                   TREE_SIDE_EFFECTS (bind) = 1;
-                   SET_EXPR_LOCATION (bind, loc);
-                   append_to_statement_list_force (bind, p);
-                   if (POINTER_TYPE_P (type))
-                     tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
-                                       var, fold_convert_loc (loc, sizetype,
-                                                              step));
-                   else
-                     tem = build2_loc (loc, PLUS_EXPR, type, var, step);
-                   tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
-                                     var, tem);
-                   append_to_statement_list_force (tem, p);
-                   tem = build1 (LABEL_EXPR, void_type_node, cond_label);
-                   append_to_statement_list (tem, p);
-                   tree cond = fold_build2_loc (loc, LT_EXPR,
-                                                boolean_type_node,
-                                                var, end);
-                   tree pos
-                     = fold_build3_loc (loc, COND_EXPR, void_type_node,
-                                        cond, build_and_jump (&beg_label),
-                                        void_node);
-                   cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
-                                           var, end);
-                   tree neg
-                     = fold_build3_loc (loc, COND_EXPR, void_type_node,
-                                        cond, build_and_jump (&beg_label),
-                                        void_node);
-                   tree osteptype = TREE_TYPE (orig_step);
-                   cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
-                                           orig_step,
-                                           build_int_cst (osteptype, 0));
-                   tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
-                                          cond, pos, neg);
-                   append_to_statement_list_force (tem, p);
-                   p = &BIND_EXPR_BODY (bind);
-                 }
-               last_body = p;
              }
            last_iter = TREE_PURPOSE (t);
            if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 535c74be7659..92cc734d9461 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -1453,10 +1453,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void 
*data)
                   || OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_DEPEND))
        {
          tree t = OMP_CLAUSE_DECL (*tp);
-         if (t
-             && TREE_CODE (t) == TREE_LIST
-             && TREE_PURPOSE (t)
-             && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+         if (t && OMP_ITERATOR_DECL_P (t))
            {
              *walk_subtrees = 0;
              OMP_CLAUSE_DECL (*tp) = copy_node (t);
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 068999769212..4371e9ac31f9 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -916,9 +916,7 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, 
dump_flags_t flags)
       pp_string (pp, "affinity(");
       {
        tree t = OMP_CLAUSE_DECL (clause);
-       if (TREE_CODE (t) == TREE_LIST
-           && TREE_PURPOSE (t)
-           && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+       if (OMP_ITERATOR_DECL_P (t))
          {
            dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags);
            pp_colon (pp);
@@ -958,9 +956,7 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, 
dump_flags_t flags)
        }
       {
        tree t = OMP_CLAUSE_DECL (clause);
-       if (TREE_CODE (t) == TREE_LIST
-           && TREE_PURPOSE (t)
-           && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
+       if (OMP_ITERATOR_DECL_P (t))
          {
            dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags);
            pp_colon (pp);
diff --git a/gcc/tree.h b/gcc/tree.h
index 0441ac635e0c..7d123fa32f87 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2214,6 +2214,12 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_OPERAND(NODE, I)                            \
        OMP_CLAUSE_ELT_CHECK (NODE, I)
 
+/* True if the clause decl NODE contains an OpenMP iterator.  */
+#define OMP_ITERATOR_DECL_P(NODE) \
+       (TREE_CODE (NODE) == TREE_LIST                          \
+        && TREE_PURPOSE (NODE)                                 \
+        && TREE_CODE (TREE_PURPOSE (NODE)) == TREE_VEC)
+
 /* In a BLOCK (scope) node:
    Variables declared in the scope NODE.  */
 #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)

Reply via email to