]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Partial OpenMP 5.2 doacross and omp_cur_iteration support
authorJakub Jelinek <jakub@redhat.com>
Mon, 5 Sep 2022 07:39:04 +0000 (09:39 +0200)
committerTobias Burnus <tobias@codesourcery.com>
Mon, 5 Sep 2022 07:39:04 +0000 (09:39 +0200)
The following patch implements part of the OpenMP 5.2 changes related
to ordered loops and with the assumed resolution of
https://github.com/OpenMP/spec/issues/3302 issues.

The changes are:
1) the depend clause on stand-alone ordered constructs has been renamed
   to doacross (because depend clause has different syntax on other
   constructs) with some syntax changes below, depend clause is deprecated
   (we'll deprecate stuff on the GCC side only when we have everything else
   from 5.2 implemented)
   depend(source) -> doacross(source:) or doacross(source:omp_cur_iteration)
   depend(sink:vec) -> doacross(sink:vec) (where vec has the same syntax
   as before)
2) in 5.1 and before it has been significant whether ordered clause has or
   doesn't have an argument, if it didn't, only block-associated ordered
   could appear in the body, if it did, only stand-alone ordered could appear
   in the body, all loops had to be perfectly nested, no associated
   range-based for loops, no linear clause on work-sharing loop and ordered
   clause with an argument wasn't allowed on composite for simd.
   In 5.2, whether ordered clause has or doesn't have an argument is
   insignificant (except for bugs in the standard, #3302 mentions those),
   if the argument is missing, it is simply treated as equal to collapse
   argument (if any, otherwise 1).  The implementation better should be able
   to differentiate between ordered and doacross loops at compile time
   which previously was through the absence or presence of the argument,
   now it is done through looking at the body of the construct lexically
   and looking for stand-alone ordered constructs.  If there are any,
   it is to be handled as doacross loop, otherwise it is ordered loop
   (but in that case ordered argument if present must be equal to collapse
   argument - 5.2 says instead it must be one, but that is clearly wrong
   and mentioned in #3302) - stand-alone ordered constructs must appear
   lexically in the body (and had to before as well).  For the restrictions
   mentioned above, the for simd restriction is gone (stand-alone ordered
   can't appear in simd construct, so that is enough), and the other rules
   are expected to be changed into something related to presence of
   stand-alone ordered constructs in the body
3) 5.2 allows a new syntax, doacross(sink:omp_cur_iteration-1), which
   means wait for previous iteration in the iteration space of all the
   associated loops

The following patch implements that, except that we sorry for now
on the doacross(sink:omp_cur_iteration-1) syntax during omp expansion
because library side isn't done yet for it.  It doesn't implement it for
the Fortran FE either.
Incrementally, I'd like to change the way we differentiate between
stand-alone and block-associated ordered constructs, because the current
way of looking for presence of doacross clause doesn't work well if those
clauses are removed because they had been invalid (wrong syntax or
unknown variables in it etc.) and of course implement
doacross(sink:omp_cur_iteration-1).

2022-09-03  Jakub Jelinek  <jakub@redhat.com>

gcc/
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DOACROSS.
(enum omp_clause_depend_kind): Remove OMP_CLAUSE_DEPEND_SOURCE
and OMP_CLAUSE_DEPEND_SINK, add OMP_CLAUSE_DEPEND_INVALID.
(enum omp_clause_doacross_kind): New type.
(struct tree_omp_clause): Add subcode.doacross_kind member.
* tree.h (OMP_CLAUSE_DEPEND_SINK_NEGATIVE): Remove.
(OMP_CLAUSE_DOACROSS_KIND): Define.
(OMP_CLAUSE_DOACROSS_SINK_NEGATIVE): Define.
(OMP_CLAUSE_DOACROSS_DEPEND): Define.
(OMP_CLAUSE_ORDERED_DOACROSS): Define.
* tree.cc (omp_clause_num_ops, omp_clause_code_name): Add
OMP_CLAUSE_DOACROSS entries.
* tree-nested.cc (convert_nonlocal_omp_clauses,
convert_local_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
* tree-pretty-print.cc (dump_omp_clause): Don't handle
OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.  Handle
OMP_CLAUSE_DOACROSS.
* gimplify.cc (gimplify_omp_depend): Don't handle
OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
(gimplify_scan_omp_clauses): Likewise.  Handle OMP_CLAUSE_DOACROSS.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
(find_standalone_omp_ordered): New function.
(gimplify_omp_for): When OMP_CLAUSE_ORDERED is present, search
body for OMP_ORDERED with OMP_CLAUSE_DOACROSS and if found,
set OMP_CLAUSE_ORDERED_DOACROSS.
(gimplify_omp_ordered): Don't handle OMP_CLAUSE_DEPEND_SINK or
OMP_CLAUSE_DEPEND_SOURCE, instead check OMP_CLAUSE_DOACROSS, adjust
diagnostics that presence or absence of ordered clause parameter
is irrelevant.  Handle doacross(sink:omp_cur_iteration-1).  Use
actual user name of the clause - doacross or depend - in diagnostics.
* omp-general.cc (omp_extract_for_data): Don't set fd->ordered
if !OMP_CLAUSE_ORDERED_DOACROSS (t).  If
OMP_CLAUSE_ORDERED_DOACROSS (t) but !OMP_CLAUSE_ORDERED_EXPR (t),
set fd->ordered to -1 and set it after the loop in that case to
fd->collapse.
* omp-low.cc (check_omp_nesting_restrictions): Don't handle
OMP_CLAUSE_DEPEND_SOURCE nor OMP_CLAUSE_DEPEND_SINK, instead check
OMP_CLAUSE_DOACROSS.  Use actual user name of the clause - doacross
or depend - in diagnostics.  Diagnose mixing of stand-alone and
block associated ordered constructs binding to the same loop.
(lower_omp_ordered_clauses): Don't handle OMP_CLAUSE_DEPEND_SINK,
instead handle OMP_CLAUSE_DOACROSS.
(lower_omp_ordered): Look for OMP_CLAUSE_DOACROSS instead of
OMP_CLAUSE_DEPEND.
(lower_depend_clauses): Don't handle OMP_CLAUSE_DEPEND_SOURCE and
OMP_CLAUSE_DEPEND_SINK.
* omp-expand.cc (expand_omp_ordered_sink): Emit a sorry for
doacross(sink:omp_cur_iteration-1).
(expand_omp_ordered_source_sink): Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE.  Use actual user name of the clause
- doacross or depend - in diagnostics.
(expand_omp): Look for OMP_CLAUSE_DOACROSS clause instead of
OMP_CLAUSE_DEPEND.
(build_omp_regions_1): Likewise.
(omp_make_gimple_edges): Likewise.
* lto-streamer-out.cc (hash_tree): Handle OMP_CLAUSE_DOACROSS.
* tree-streamer-in.cc (unpack_ts_omp_clause_value_fields): Likewise.
* tree-streamer-out.cc (pack_ts_omp_clause_value_fields): Likewise.
gcc/c-family/
* c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DOACROSS.
* c-omp.cc (c_finish_omp_depobj): Check also for OMP_CLAUSE_DOACROSS
clause and diagnose it.  Don't handle OMP_CLAUSE_DEPEND_SOURCE and
OMP_CLAUSE_DEPEND_SINK.  Assert kind is not OMP_CLAUSE_DEPEND_INVALID.
gcc/c/
* c-parser.cc (c_parser_omp_clause_name): Handle doacross.
(c_parser_omp_clause_depend_sink): Renamed to ...
(c_parser_omp_clause_doacross_sink): ... this.  Add depend_p argument.
Handle parsing of doacross(sink:omp_cur_iteration-1).  Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead
of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it.
(c_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and
OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and
OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source)
and set OMP_CLAUSE_DOACROSS_DEPEND on it.
(c_parser_omp_clause_doacross): New function.
(c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS.
(c_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of
OMP_CLAUSE_DEPEND_SOURCE.
(c_parser_omp_for_loop): Don't diagnose here linear clause together
with ordered with argument.
(c_parser_omp_simd): Don't diagnose ordered clause with argument on
for simd.
(OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS.
(c_parser_omp_ordered): Handle also doacross and adjust for it
diagnostic wording.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
gcc/cp/
* parser.cc (cp_parser_omp_clause_name): Handle doacross.
(cp_parser_omp_clause_depend_sink): Renamed to ...
(cp_parser_omp_clause_doacross_sink): ... this.  Add depend_p
argument.  Handle parsing of doacross(sink:omp_cur_iteration-1).  Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead
of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it.
(cp_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and
OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and
OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source)
and set OMP_CLAUSE_DOACROSS_DEPEND on it.
(cp_parser_omp_clause_doacross): New function.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS.
(cp_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of
OMP_CLAUSE_DEPEND_SOURCE.
(cp_parser_omp_for_loop): Don't diagnose here linear clause together
with ordered with argument.
(cp_parser_omp_simd): Don't diagnose ordered clause with argument on
for simd.
(OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS.
(cp_parser_omp_ordered): Handle also doacross and adjust for it
diagnostic wording.
* pt.cc (tsubst_omp_clause_decl): Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE.
(tsubst_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
(tsubst_expr): Use OMP_CLAUSE_DEPEND_INVALID instead of
OMP_CLAUSE_DEPEND_SOURCE.
* semantics.cc (cp_finish_omp_clause_depend_sink): Rename to ...
(cp_finish_omp_clause_doacross_sink): ... this.
(finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS.  Don't handle
OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
gcc/fortran/
* trans-openmp.cc (gfc_trans_omp_clauses): Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS
clause instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND
on it.
gcc/testsuite/
* c-c++-common/gomp/doacross-2.c: Adjust expected diagnostics.
* c-c++-common/gomp/doacross-5.c: New test.
* c-c++-common/gomp/doacross-6.c: New test.
* c-c++-common/gomp/nesting-2.c: Adjust expected diagnostics.
* c-c++-common/gomp/ordered-3.c: Likewise.
* c-c++-common/gomp/sink-3.c: Likewise.
* gfortran.dg/gomp/nesting-2.f90: Likewise.

(cherry picked from commit a651e6d59188da8992f8bfae2df1cb4e6316f9e6)

32 files changed:
gcc/ChangeLog.omp
gcc/c-family/c-omp.cc
gcc/c-family/c-pragma.h
gcc/c/ChangeLog.omp
gcc/c/c-parser.cc
gcc/c/c-typeck.cc
gcc/cp/ChangeLog.omp
gcc/cp/parser.cc
gcc/cp/pt.cc
gcc/cp/semantics.cc
gcc/fortran/ChangeLog.omp
gcc/fortran/trans-openmp.cc
gcc/gimplify.cc
gcc/lto-streamer-out.cc
gcc/omp-expand.cc
gcc/omp-general.cc
gcc/omp-low.cc
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/gomp/doacross-2.c
gcc/testsuite/c-c++-common/gomp/doacross-5.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/doacross-6.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/nesting-2.c
gcc/testsuite/c-c++-common/gomp/ordered-3.c
gcc/testsuite/c-c++-common/gomp/sink-3.c
gcc/testsuite/gfortran.dg/gomp/nesting-2.f90
gcc/tree-core.h
gcc/tree-nested.cc
gcc/tree-pretty-print.cc
gcc/tree-streamer-in.cc
gcc/tree-streamer-out.cc
gcc/tree.cc
gcc/tree.h

index 8229319f481fb75e3aeb60e30e6d8d50c2ae748d..08177cdd444420c5ae60f1b08eefd831c9eeae85 100644 (file)
@@ -1,3 +1,73 @@
+2022-09-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DOACROSS.
+       (enum omp_clause_depend_kind): Remove OMP_CLAUSE_DEPEND_SOURCE
+       and OMP_CLAUSE_DEPEND_SINK, add OMP_CLAUSE_DEPEND_INVALID.
+       (enum omp_clause_doacross_kind): New type.
+       (struct tree_omp_clause): Add subcode.doacross_kind member.
+       * tree.h (OMP_CLAUSE_DEPEND_SINK_NEGATIVE): Remove.
+       (OMP_CLAUSE_DOACROSS_KIND): Define.
+       (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE): Define.
+       (OMP_CLAUSE_DOACROSS_DEPEND): Define.
+       (OMP_CLAUSE_ORDERED_DOACROSS): Define.
+       * tree.cc (omp_clause_num_ops, omp_clause_code_name): Add
+       OMP_CLAUSE_DOACROSS entries.
+       * tree-nested.cc (convert_nonlocal_omp_clauses,
+       convert_local_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
+       * tree-pretty-print.cc (dump_omp_clause): Don't handle
+       OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.  Handle
+       OMP_CLAUSE_DOACROSS.
+       * gimplify.cc (gimplify_omp_depend): Don't handle
+       OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
+       (gimplify_scan_omp_clauses): Likewise.  Handle OMP_CLAUSE_DOACROSS.
+       (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
+       (find_standalone_omp_ordered): New function.
+       (gimplify_omp_for): When OMP_CLAUSE_ORDERED is present, search
+       body for OMP_ORDERED with OMP_CLAUSE_DOACROSS and if found,
+       set OMP_CLAUSE_ORDERED_DOACROSS.
+       (gimplify_omp_ordered): Don't handle OMP_CLAUSE_DEPEND_SINK or
+       OMP_CLAUSE_DEPEND_SOURCE, instead check OMP_CLAUSE_DOACROSS, adjust
+       diagnostics that presence or absence of ordered clause parameter
+       is irrelevant.  Handle doacross(sink:omp_cur_iteration-1).  Use
+       actual user name of the clause - doacross or depend - in diagnostics.
+       * omp-general.cc (omp_extract_for_data): Don't set fd->ordered
+       if !OMP_CLAUSE_ORDERED_DOACROSS (t).  If
+       OMP_CLAUSE_ORDERED_DOACROSS (t) but !OMP_CLAUSE_ORDERED_EXPR (t),
+       set fd->ordered to -1 and set it after the loop in that case to
+       fd->collapse.
+       * omp-low.cc (check_omp_nesting_restrictions): Don't handle
+       OMP_CLAUSE_DEPEND_SOURCE nor OMP_CLAUSE_DEPEND_SINK, instead check
+       OMP_CLAUSE_DOACROSS.  Use actual user name of the clause - doacross
+       or depend - in diagnostics.  Diagnose mixing of stand-alone and
+       block associated ordered constructs binding to the same loop.
+       (lower_omp_ordered_clauses): Don't handle OMP_CLAUSE_DEPEND_SINK,
+       instead handle OMP_CLAUSE_DOACROSS.
+       (lower_omp_ordered): Look for OMP_CLAUSE_DOACROSS instead of
+       OMP_CLAUSE_DEPEND.
+       (lower_depend_clauses): Don't handle OMP_CLAUSE_DEPEND_SOURCE and
+       OMP_CLAUSE_DEPEND_SINK.
+       * omp-expand.cc (expand_omp_ordered_sink): Emit a sorry for
+       doacross(sink:omp_cur_iteration-1).
+       (expand_omp_ordered_source_sink): Use
+       OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
+       OMP_CLAUSE_DEPEND_SINK_NEGATIVE.  Use actual user name of the clause
+       - doacross or depend - in diagnostics.
+       (expand_omp): Look for OMP_CLAUSE_DOACROSS clause instead of
+       OMP_CLAUSE_DEPEND.
+       (build_omp_regions_1): Likewise.
+       (omp_make_gimple_edges): Likewise.
+       * lto-streamer-out.cc (hash_tree): Handle OMP_CLAUSE_DOACROSS.
+       * tree-streamer-in.cc (unpack_ts_omp_clause_value_fields): Likewise.
+       * tree-streamer-out.cc (pack_ts_omp_clause_value_fields): Likewise.
+       gcc/c-family/
+       * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DOACROSS.
+       * c-omp.cc (c_finish_omp_depobj): Check also for OMP_CLAUSE_DOACROSS
+       clause and diagnose it.  Don't handle OMP_CLAUSE_DEPEND_SOURCE and
+       OMP_CLAUSE_DEPEND_SINK.  Assert kind is not OMP_CLAUSE_DEPEND_INVALID.
+
 2022-09-01  Andrew Stubbs  <ams@codesourcery.com>
 
        Backport from mainline:
index d71d5e446be65b70e1ec2606eef2365d2234f806..5c45935daca083992876c2862669287b96ae20b0 100644 (file)
@@ -715,8 +715,17 @@ c_finish_omp_depobj (location_t loc, tree depobj,
 
   if (clause)
     {
-      gcc_assert (TREE_CODE (clause) == OMP_CLAUSE
-                 && OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DEPEND);
+      gcc_assert (TREE_CODE (clause) == OMP_CLAUSE);
+      if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DOACROSS)
+       {
+         error_at (OMP_CLAUSE_LOCATION (clause),
+                   "%<depend(%s)%> is only allowed in %<omp ordered%>",
+                   OMP_CLAUSE_DOACROSS_KIND (clause)
+                   == OMP_CLAUSE_DOACROSS_SOURCE
+                   ? "source" : "sink");
+         return;
+       }
+      gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_DEPEND);
       if (OMP_CLAUSE_CHAIN (clause))
        error_at (OMP_CLAUSE_LOCATION (clause),
                  "more than one locator in %<depend%> clause on %<depobj%> "
@@ -728,13 +737,6 @@ c_finish_omp_depobj (location_t loc, tree depobj,
                    "%<depobj%> dependence type specified in %<depend%> "
                    "clause on %<depobj%> construct");
          return;
-       case OMP_CLAUSE_DEPEND_SOURCE:
-       case OMP_CLAUSE_DEPEND_SINK:
-         error_at (OMP_CLAUSE_LOCATION (clause),
-                   "%<depend(%s)%> is only allowed in %<omp ordered%>",
-                   OMP_CLAUSE_DEPEND_KIND (clause) == OMP_CLAUSE_DEPEND_SOURCE
-                   ? "source" : "sink");
-         return;
        case OMP_CLAUSE_DEPEND_IN:
        case OMP_CLAUSE_DEPEND_OUT:
        case OMP_CLAUSE_DEPEND_INOUT:
@@ -766,7 +768,7 @@ c_finish_omp_depobj (location_t loc, tree depobj,
        }
     }
   else
-    gcc_assert (kind != OMP_CLAUSE_DEPEND_SOURCE);
+    gcc_assert (kind != OMP_CLAUSE_DEPEND_INVALID);
 
   if (depobj == error_mark_node)
     return;
index f929e6a5258fcef64eadc5c278fd1ea5996e07d0..2fb459a98724e6d3ac2704e9d9e9771d9d13017b 100644 (file)
@@ -109,6 +109,7 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_DEVICE,
   PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
   PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
+  PRAGMA_OMP_CLAUSE_DOACROSS,
   PRAGMA_OMP_CLAUSE_ENTER,
   PRAGMA_OMP_CLAUSE_FILTER,
   PRAGMA_OMP_CLAUSE_FINAL,
index 6f8dae98e0c24bed7ea46da896e853806c7ec12b..32940146b60991d1fe75413f863bfb8058e3a056 100644 (file)
@@ -1,3 +1,33 @@
+2022-09-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-parser.cc (c_parser_omp_clause_name): Handle doacross.
+       (c_parser_omp_clause_depend_sink): Renamed to ...
+       (c_parser_omp_clause_doacross_sink): ... this.  Add depend_p argument.
+       Handle parsing of doacross(sink:omp_cur_iteration-1).  Use
+       OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
+       OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead
+       of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it.
+       (c_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and
+       OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and
+       OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source)
+       and set OMP_CLAUSE_DOACROSS_DEPEND on it.
+       (c_parser_omp_clause_doacross): New function.
+       (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS.
+       (c_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of
+       OMP_CLAUSE_DEPEND_SOURCE.
+       (c_parser_omp_for_loop): Don't diagnose here linear clause together
+       with ordered with argument.
+       (c_parser_omp_simd): Don't diagnose ordered clause with argument on
+       for simd.
+       (OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS.
+       (c_parser_omp_ordered): Handle also doacross and adjust for it
+       diagnostic wording.
+       * c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
+       Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
+
 2022-08-17  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index ce53667468ca5f09082d2e3974862bc65dd51701..70b72ad6fd72f72d1397fa107f9cb809a7e3174d 100644 (file)
@@ -12786,6 +12786,8 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
+         else if (!strcmp ("doacross", p))
+           result = PRAGMA_OMP_CLAUSE_DOACROSS;
          break;
        case 'e':
          if (!strcmp ("enter", p))
@@ -16148,8 +16150,8 @@ c_parser_omp_clause_simdlen (c_parser *parser, tree list)
 */
 
 static tree
-c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
-                                tree list)
+c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
+                                  tree list, bool depend_p)
 {
   tree vec = NULL;
   if (c_parser_next_token_is_not (parser, CPP_NAME)
@@ -16159,6 +16161,31 @@ c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
       return list;
     }
 
+  if (!depend_p)
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (strcmp (p, "omp_cur_iteration") == 0
+         && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
+         && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
+         && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
+       {
+         tree val = c_parser_peek_nth_token (parser, 3)->value;
+         if (integer_onep (val)
+             && comptypes (TREE_TYPE (val), integer_type_node))
+           {
+             c_parser_consume_token (parser);
+             c_parser_consume_token (parser);
+             c_parser_consume_token (parser);
+             tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
+             OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
+             OMP_CLAUSE_CHAIN (u) = list;
+             return u;
+           }
+       }
+    }
+
+
+
   while (c_parser_next_token_is (parser, CPP_NAME)
         && c_parser_peek_token (parser)->id_kind == C_ID_ID)
     {
@@ -16204,7 +16231,7 @@ c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
        {
          vec = tree_cons (addend, t, vec);
          if (neg)
-           OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
+           OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
        }
 
       if (c_parser_next_token_is_not (parser, CPP_COMMA)
@@ -16218,8 +16245,9 @@ c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
   if (vec == NULL_TREE)
     return list;
 
-  tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
-  OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
+  tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
+  OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
+  OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
   OMP_CLAUSE_DECL (u) = nreverse (vec);
   OMP_CLAUSE_CHAIN (u) = list;
   return u;
@@ -16411,6 +16439,7 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
+  enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
   tree nl, c, iterators = NULL_TREE;
 
   matching_parens parens;
@@ -16442,9 +16471,9 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
       else if (strcmp ("depobj", p) == 0)
        kind = OMP_CLAUSE_DEPEND_DEPOBJ;
       else if (strcmp ("sink", p) == 0)
-       kind = OMP_CLAUSE_DEPEND_SINK;
+       dkind = OMP_CLAUSE_DOACROSS_SINK;
       else if (strcmp ("source", p) == 0)
-       kind = OMP_CLAUSE_DEPEND_SOURCE;
+       dkind = OMP_CLAUSE_DOACROSS_SOURCE;
       else
        goto invalid_kind;
       break;
@@ -16454,18 +16483,20 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
   c_parser_consume_token (parser);
 
   if (iterators
-      && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
+      && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
+         || dkind == OMP_CLAUSE_DOACROSS_SINK))
     {
       pop_scope ();
       error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
-               kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
+               dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
       iterators = NULL_TREE;
     }
 
-  if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+  if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
     {
-      c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
-      OMP_CLAUSE_DEPEND_KIND (c) = kind;
+      c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
+      OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
+      OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
       OMP_CLAUSE_DECL (c) = NULL_TREE;
       OMP_CLAUSE_CHAIN (c) = list;
       parens.skip_until_found_close (parser);
@@ -16475,8 +16506,8 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
     goto resync_fail;
 
-  if (kind == OMP_CLAUSE_DEPEND_SINK)
-    nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
+  if (dkind == OMP_CLAUSE_DOACROSS_SINK)
+    nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
   else
     {
       nl = c_parser_omp_variable_list (parser, clause_loc,
@@ -16512,6 +16543,65 @@ c_parser_omp_clause_depend (c_parser *parser, tree list)
   return list;
 }
 
+/* OpenMP 5.2:
+   doacross ( source : )
+   doacross ( source : omp_cur_iteration )
+
+   doacross ( sink : vec )
+   doacross ( sink : omp_cur_iteration - logical_iteration )  */
+
+static tree
+c_parser_omp_clause_doacross (c_parser *parser, tree list)
+{
+  location_t clause_loc = c_parser_peek_token (parser)->location;
+  enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
+  tree nl;
+  const char *p;
+
+  matching_parens parens;
+  if (!parens.require_open (parser))
+    return list;
+
+  if (c_parser_next_token_is_not (parser, CPP_NAME))
+    goto invalid_kind;
+
+  p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+  if (strcmp ("sink", p) == 0)
+    kind = OMP_CLAUSE_DOACROSS_SINK;
+  else if (strcmp ("source", p) == 0)
+    kind = OMP_CLAUSE_DOACROSS_SOURCE;
+  else
+    goto invalid_kind;
+
+  c_parser_consume_token (parser);
+
+  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+    goto resync_fail;
+
+  if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
+    {
+      if (c_parser_next_token_is (parser, CPP_NAME)
+         && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
+                    "omp_cur_iteration") == 0)
+       c_parser_consume_token (parser);
+      nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
+      OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
+      OMP_CLAUSE_DECL (nl) = NULL_TREE;
+      OMP_CLAUSE_CHAIN (nl) = list;
+    }
+  else
+    nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
+
+  parens.skip_until_found_close (parser);
+  return nl;
+
+ invalid_kind:
+  c_parser_error (parser, "invalid doacross kind");
+ resync_fail:
+  parens.skip_until_found_close (parser);
+  return list;
+}
+
 /* OpenMP 4.0:
    map ( map-kind: variable-list )
    map ( variable-list )
@@ -17435,6 +17525,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
          clauses = c_parser_omp_clause_depend (parser, clauses);
          c_name = "depend";
          break;
+       case PRAGMA_OMP_CLAUSE_DOACROSS:
+         clauses = c_parser_omp_clause_doacross (parser, clauses);
+         c_name = "doacross";
+         break;
        case PRAGMA_OMP_CLAUSE_MAP:
          clauses = c_parser_omp_clause_map (parser, clauses);
          c_name = "map";
@@ -19383,7 +19477,7 @@ c_parser_omp_depobj (c_parser *parser)
 
   parens.skip_until_found_close (parser);
   tree clause = NULL_TREE;
-  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
+  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
   location_t c_loc = c_parser_peek_token (parser)->location;
   if (c_parser_next_token_is (parser, CPP_NAME))
     {
@@ -19422,7 +19516,7 @@ c_parser_omp_depobj (c_parser *parser)
                  else if (!strcmp ("inoutset", p2))
                    kind = OMP_CLAUSE_DEPEND_INOUTSET;
                }
-             if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+             if (kind == OMP_CLAUSE_DEPEND_INVALID)
                {
                  clause = error_mark_node;
                  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
@@ -19434,7 +19528,7 @@ c_parser_omp_depobj (c_parser *parser)
            clause = error_mark_node;
        }
     }
-  if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
+  if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
     {
       clause = error_mark_node;
       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
@@ -19634,19 +19728,6 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
        = build_int_cst (NULL_TREE, collapse);
       ordered = collapse;
     }
-  if (ordered)
-    {
-      for (tree *pc = &clauses; *pc; )
-       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
-         {
-           error_at (OMP_CLAUSE_LOCATION (*pc),
-                     "%<linear%> clause may not be specified together "
-                     "with %<ordered%> clause with a parameter");
-           *pc = OMP_CLAUSE_CHAIN (*pc);
-         }
-       else
-         pc = &OMP_CLAUSE_CHAIN (*pc);
-    }
 
   gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
   count = ordered ? ordered : collapse;
@@ -20084,15 +20165,6 @@ c_parser_omp_simd (location_t loc, c_parser *parser,
     {
       omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
-      tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
-                               OMP_CLAUSE_ORDERED);
-      if (c && OMP_CLAUSE_ORDERED_EXPR (c))
-       {
-         error_at (OMP_CLAUSE_LOCATION (c),
-                   "%<ordered%> clause with parameter may not be specified "
-                   "on %qs construct", p_name);
-         OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
-       }
     }
 
   block = c_begin_compound_stmt (true);
@@ -20331,14 +20403,18 @@ c_parser_omp_masked (location_t loc, c_parser *parser,
    # pragma omp ordered ordered-clauses new-line
      structured-block
 
-   # pragma omp ordered depend-clauses new-line  */
+   # pragma omp ordered depend-clauses new-line
+
+   OpenMP 5.2
+   # pragma omp ordered doacross-clauses new-line  */
 
 #define OMP_ORDERED_CLAUSE_MASK                                        \
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)      \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
 
 #define OMP_ORDERED_DEPEND_CLAUSE_MASK                         \
-       (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+       ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)       \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
 
 static bool
 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
@@ -20358,7 +20434,7 @@ c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
 
-      if (!strcmp ("depend", p))
+      if (!strcmp ("depend", p) || !strcmp ("doacross", p))
        {
          if (!flag_openmp)     /* flag_openmp_simd  */
            {
@@ -20368,8 +20444,8 @@ c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
          if (context == pragma_stmt)
            {
              error_at (loc,
-                       "%<#pragma omp ordered%> with %<depend%> clause may "
-                       "only be used in compound statements");
+                       "%<#pragma omp ordered%> with %qs clause may "
+                       "only be used in compound statements", p);
              c_parser_skip_to_pragma_eol (parser, false);
              return true;
            }
index c1852586cd84f43d4c4e0c7ec5f07360c2f0f7ff..7d855e7363072f92aaad1a34952ab9e9a7830997 100644 (file)
@@ -14960,15 +14960,11 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
              continue;
            }
 
-       case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_DOACROSS:
          t = OMP_CLAUSE_DECL (c);
          if (t == NULL_TREE)
-           {
-             gcc_assert (OMP_CLAUSE_DEPEND_KIND (c)
-                         == OMP_CLAUSE_DEPEND_SOURCE);
-             break;
-           }
-         if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+           break;
+         if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
            {
              gcc_assert (TREE_CODE (t) == TREE_LIST);
              for (; t; t = TREE_CHAIN (t))
@@ -14996,7 +14992,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
                }
              break;
            }
-         /* FALLTHRU */
+         gcc_unreachable ();
+       case OMP_CLAUSE_DEPEND:
        case OMP_CLAUSE_AFFINITY:
          t = OMP_CLAUSE_DECL (c);
          if (TREE_CODE (t) == TREE_LIST
index b122ac07ef98e3c9d20865b6574f3fdba9c73f18..07e7be2f819a40a1e8eae1eb0464a6f80ec2a894 100644 (file)
@@ -1,3 +1,41 @@
+2022-09-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.cc (cp_parser_omp_clause_name): Handle doacross.
+       (cp_parser_omp_clause_depend_sink): Renamed to ...
+       (cp_parser_omp_clause_doacross_sink): ... this.  Add depend_p
+       argument.  Handle parsing of doacross(sink:omp_cur_iteration-1).  Use
+       OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
+       OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead
+       of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it.
+       (cp_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and
+       OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and
+       OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source)
+       and set OMP_CLAUSE_DOACROSS_DEPEND on it.
+       (cp_parser_omp_clause_doacross): New function.
+       (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS.
+       (cp_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of
+       OMP_CLAUSE_DEPEND_SOURCE.
+       (cp_parser_omp_for_loop): Don't diagnose here linear clause together
+       with ordered with argument.
+       (cp_parser_omp_simd): Don't diagnose ordered clause with argument on
+       for simd.
+       (OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS.
+       (cp_parser_omp_ordered): Handle also doacross and adjust for it
+       diagnostic wording.
+       * pt.cc (tsubst_omp_clause_decl): Use
+       OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
+       OMP_CLAUSE_DEPEND_SINK_NEGATIVE.
+       (tsubst_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
+       (tsubst_expr): Use OMP_CLAUSE_DEPEND_INVALID instead of
+       OMP_CLAUSE_DEPEND_SOURCE.
+       * semantics.cc (cp_finish_omp_clause_depend_sink): Rename to ...
+       (cp_finish_omp_clause_doacross_sink): ... this.
+       (finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS.  Don't handle
+       OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
+
 2022-08-17  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 618dfdb8f9b0d22f796e14c5898c2d1b62765cb7..4c82ad150a2317a41f5b72a14bd136903bb6bee9 100644 (file)
@@ -11912,14 +11912,18 @@ cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs)
            if (dir->id == PRAGMA_OMP_ORDERED)
              {
                /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
-                  depend clause.  */
-               if (directive[1] && strcmp (directive[1], "depend") == 0)
+                  depend/doacross clause.  */
+               if (directive[1]
+                   && (strcmp (directive[1], "depend") == 0
+                       || strcmp (directive[1], "doacross") == 0))
                  kind = C_OMP_DIR_STANDALONE;
                else if (first + 2 < last
                         && first[1].type == CPP_COMMA
                         && first[2].type == CPP_NAME
-                        && strcmp (IDENTIFIER_POINTER (first[2].u.value),
-                                   "depend") == 0)
+                        && (strcmp (IDENTIFIER_POINTER (first[2].u.value),
+                                    "depend") == 0
+                            || strcmp (IDENTIFIER_POINTER (first[2].u.value),
+                                       "doacross") == 0))
                  kind = C_OMP_DIR_STANDALONE;
              }
            else if (dir->id == PRAGMA_OMP_ERROR)
@@ -36369,6 +36373,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
            result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
+         else if (!strcmp ("doacross", p))
+           result = PRAGMA_OMP_CLAUSE_DOACROSS;
          break;
        case 'e':
          if (!strcmp ("enter", p))
@@ -39328,8 +39334,8 @@ cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
 */
 
 static tree
-cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc,
-                                 tree list)
+cp_parser_omp_clause_doacross_sink (cp_parser *parser, location_t clause_loc,
+                                   tree list, bool depend_p)
 {
   tree vec = NULL;
 
@@ -39339,6 +39345,29 @@ cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc,
       return list;
     }
 
+  if (!depend_p)
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      if (strcmp (IDENTIFIER_POINTER (id), "omp_cur_iteration") == 0
+         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_MINUS)
+         && cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
+         && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN))
+       {
+         tree val = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value;
+         if (integer_onep (val)
+             && same_type_p (TREE_TYPE (val), integer_type_node))
+           {
+             cp_lexer_consume_token (parser->lexer);
+             cp_lexer_consume_token (parser->lexer);
+             cp_lexer_consume_token (parser->lexer);
+             tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
+             OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
+             OMP_CLAUSE_CHAIN (u) = list;
+             return u;
+           }
+       }
+    }
+
   while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
       location_t id_loc = cp_lexer_peek_token (parser->lexer)->location;
@@ -39386,7 +39415,7 @@ cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc,
        {
          vec = tree_cons (addend, t, vec);
          if (neg)
-           OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
+           OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
        }
 
       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
@@ -39398,8 +39427,9 @@ cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc,
 
   if (vec)
     {
-      tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
-      OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
+      tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
+      OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
+      OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
       OMP_CLAUSE_DECL (u) = nreverse (vec);
       OMP_CLAUSE_CHAIN (u) = list;
       return u;
@@ -39648,6 +39678,7 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
 {
   tree nlist, c, iterators = NULL_TREE;
   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
+  enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
 
   matching_parens parens;
   if (!parens.require_open (parser))
@@ -39681,9 +39712,9 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
       else if (strcmp ("depobj", p) == 0)
        kind = OMP_CLAUSE_DEPEND_DEPOBJ;
       else if (strcmp ("sink", p) == 0)
-       kind = OMP_CLAUSE_DEPEND_SINK;
+       dkind = OMP_CLAUSE_DOACROSS_SINK;
       else if (strcmp ("source", p) == 0)
-       kind = OMP_CLAUSE_DEPEND_SOURCE;
+       dkind = OMP_CLAUSE_DOACROSS_SOURCE;
       else
        goto invalid_kind;
       break;
@@ -39693,18 +39724,20 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
   cp_lexer_consume_token (parser->lexer);
 
   if (iterators
-      && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
+      && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
+         || dkind == OMP_CLAUSE_DOACROSS_SINK))
     {
       poplevel (0, 1, 0);
       error_at (loc, "%<iterator%> modifier incompatible with %qs",
-               kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
+               dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
       iterators = NULL_TREE;
     }
 
-  if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+  if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
     {
-      c = build_omp_clause (loc, OMP_CLAUSE_DEPEND);
-      OMP_CLAUSE_DEPEND_KIND (c) = kind;
+      c = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
+      OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
+      OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
       OMP_CLAUSE_DECL (c) = NULL_TREE;
       OMP_CLAUSE_CHAIN (c) = list;
       if (!parens.require_close (parser))
@@ -39717,9 +39750,9 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
     goto resync_fail;
 
-  if (kind == OMP_CLAUSE_DEPEND_SINK)
+  if (dkind == OMP_CLAUSE_DOACROSS_SINK)
     {
-      nlist = cp_parser_omp_clause_depend_sink (parser, loc, list);
+      nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, true);
       if (!parens.require_close (parser))
        cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                               /*or_comma=*/false,
@@ -39760,6 +39793,73 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
   return list;
 }
 
+/* OpenMP 5.2:
+   doacross ( source : )
+   doacross ( source : omp_cur_iteration )
+
+   doacross ( sink : vec )
+   doacross ( sink : omp_cur_iteration - logical_iteration )  */
+
+static tree
+cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc)
+{
+  tree nlist;
+  enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
+
+  matching_parens parens;
+  if (!parens.require_open (parser))
+    return list;
+
+  if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+    {
+    invalid_kind:
+      cp_parser_error (parser, "invalid doacross kind");
+    resync_fail:
+      cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                            /*or_comma=*/false,
+                                            /*consume_paren=*/true);
+      return list;
+    }
+
+  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+  const char *p = IDENTIFIER_POINTER (id);
+
+  if (strcmp ("sink", p) == 0)
+    kind = OMP_CLAUSE_DOACROSS_SINK;
+  else if (strcmp ("source", p) == 0)
+    kind = OMP_CLAUSE_DOACROSS_SOURCE;
+  else
+    goto invalid_kind;
+
+  cp_lexer_consume_token (parser->lexer);
+
+  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+    goto resync_fail;
+
+  if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
+    {
+      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+       {
+         id = cp_lexer_peek_token (parser->lexer)->u.value;
+         p = IDENTIFIER_POINTER (id);
+         if (strcmp (p, "omp_cur_iteration") == 0)
+           cp_lexer_consume_token (parser->lexer);
+       }
+      nlist = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
+      OMP_CLAUSE_DOACROSS_KIND (nlist) = OMP_CLAUSE_DOACROSS_SOURCE;
+      OMP_CLAUSE_DECL (nlist) = NULL_TREE;
+      OMP_CLAUSE_CHAIN (nlist) = list;
+    }
+  else
+    nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, false);
+
+  if (!parens.require_close (parser))
+    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                          /*or_comma=*/false,
+                                          /*consume_paren=*/true);
+  return nlist;
+}
+
 /* OpenMP 4.0:
    map ( map-kind : variable-list )
    map ( variable-list )
@@ -40706,6 +40806,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
                                                 token->location);
          c_name = "depend";
          break;
+       case PRAGMA_OMP_CLAUSE_DOACROSS:
+         clauses = cp_parser_omp_clause_doacross (parser, clauses,
+                                                  token->location);
+         c_name = "doacross";
+         break;
        case PRAGMA_OMP_CLAUSE_DETACH:
          clauses = cp_parser_omp_clause_detach (parser, clauses);
          c_name = "detach";
@@ -41944,7 +42049,7 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
                                           /*consume_paren=*/true);
 
   tree clause = NULL_TREE;
-  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
+  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
   location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
   /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
   if (parser->lexer->in_omp_attribute_pragma
@@ -41992,7 +42097,7 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
                  else if (!strcmp ("inoutset", p2))
                    kind = OMP_CLAUSE_DEPEND_INOUTSET;
                }
-             if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+             if (kind == OMP_CLAUSE_DEPEND_INVALID)
                {
                  clause = error_mark_node;
                  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
@@ -42008,7 +42113,7 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
            clause = error_mark_node;
        }
     }
-  if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
+  if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
     {
       clause = error_mark_node;
       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
@@ -42840,19 +42945,6 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
        = build_int_cst (NULL_TREE, collapse);
       ordered = collapse;
     }
-  if (ordered)
-    {
-      for (tree *pc = &clauses; *pc; )
-       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
-         {
-           error_at (OMP_CLAUSE_LOCATION (*pc),
-                     "%<linear%> clause may not be specified together "
-                     "with %<ordered%> clause with a parameter");
-           *pc = OMP_CLAUSE_CHAIN (*pc);
-         }
-       else
-         pc = &OMP_CLAUSE_CHAIN (*pc);
-    }
 
   gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
   count = ordered ? ordered : collapse;
@@ -43304,15 +43396,6 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
     {
       cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
-      tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
-                               OMP_CLAUSE_ORDERED);
-      if (c && OMP_CLAUSE_ORDERED_EXPR (c))
-       {
-         error_at (OMP_CLAUSE_LOCATION (c),
-                   "%<ordered%> clause with parameter may not be specified "
-                   "on %qs construct", p_name);
-         OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
-       }
     }
 
   keep_next_level (true);
@@ -43574,7 +43657,8 @@ cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
 
 #define OMP_ORDERED_DEPEND_CLAUSE_MASK                         \
-       (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+       ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)       \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
 
 static bool
 cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
@@ -43593,7 +43677,7 @@ cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
       tree id = cp_lexer_peek_nth_token (parser->lexer, n)->u.value;
       const char *p = IDENTIFIER_POINTER (id);
 
-      if (strcmp (p, "depend") == 0)
+      if (strcmp (p, "depend") == 0 || strcmp (p, "doacross") == 0)
        {
          if (!flag_openmp)     /* flag_openmp_simd */
            {
@@ -43603,8 +43687,8 @@ cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
          if (context == pragma_stmt)
            {
              error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
-                       "%<depend%> clause may only be used in compound "
-                       "statements");
+                       "%qs clause may only be used in compound "
+                       "statements", p);
              cp_parser_skip_to_pragma_eol (parser, pragma_tok);
              return true;
            }
index 7b4ce3fae02f45d75dc0f138f12ad5a601850738..42fc7e9746130354fa72d04a14435849da36c5d2 100644 (file)
@@ -17717,8 +17717,8 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
     }
 
   /* Handle an OpenMP array section represented as a TREE_LIST (or
-     OMP_CLAUSE_DEPEND_KIND).  An OMP_CLAUSE_DEPEND (with a depend
-     kind of OMP_CLAUSE_DEPEND_SINK) can also be represented as a
+     OMP_CLAUSE_DOACROSS_KIND).  An OMP_CLAUSE_DOACROSS (with a depend
+     kind of OMP_CLAUSE_DOACROSS_SINK) can also be represented as a
      TREE_LIST.  We can handle it exactly the same as an array section
      (purpose, value, and a chain), even though the nomenclature
      (low_bound, length, etc) is different.  */
@@ -17736,8 +17736,8 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
          && TREE_CHAIN (decl) == chain)
        return decl;
       tree ret = tree_cons (low_bound, length, chain);
-      OMP_CLAUSE_DEPEND_SINK_NEGATIVE (ret)
-       = OMP_CLAUSE_DEPEND_SINK_NEGATIVE (decl);
+      OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (ret)
+       = OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (decl);
       return ret;
     }
   tree ret = tsubst_expr (decl, args, complain, in_decl,
@@ -17785,6 +17785,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
        case OMP_CLAUSE_COPYPRIVATE:
        case OMP_CLAUSE_UNIFORM:
        case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_DOACROSS:
        case OMP_CLAUSE_AFFINITY:
        case OMP_CLAUSE_FROM:
        case OMP_CLAUSE_TO:
@@ -19273,7 +19274,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       r = RECUR (OMP_DEPOBJ_DEPOBJ (t));
       if (OMP_DEPOBJ_CLAUSES (t) && OMP_DEPOBJ_CLAUSES (t) != error_mark_node)
        {
-         enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
+         enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
          if (TREE_CODE (OMP_DEPOBJ_CLAUSES (t)) == OMP_CLAUSE)
            {
              tmp = tsubst_omp_clauses (OMP_DEPOBJ_CLAUSES (t), C_ORT_OMP,
@@ -19291,7 +19292,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
        }
       else
        finish_omp_depobj (EXPR_LOCATION (t), r,
-                          OMP_CLAUSE_DEPEND_SOURCE,
+                          OMP_CLAUSE_DEPEND_INVALID,
                           OMP_DEPOBJ_CLAUSES (t));
       break;
 
index 85ec4807dc8cf71253f62b4a0d9fbce2b41df6e8..7717a820f0dbcfdf1de0a9fc31ff1ebb0518b25b 100644 (file)
@@ -6528,13 +6528,13 @@ finish_omp_declare_simd_methods (tree t)
     }
 }
 
-/* Adjust sink depend clause to take into account pointer offsets.
+/* Adjust sink depend/doacross clause to take into account pointer offsets.
 
    Return TRUE if there was a problem processing the offset, and the
    whole clause should be removed.  */
 
 static bool
-cp_finish_omp_clause_depend_sink (tree sink_clause)
+cp_finish_omp_clause_doacross_sink (tree sink_clause)
 {
   tree t = OMP_CLAUSE_DECL (sink_clause);
   gcc_assert (TREE_CODE (t) == TREE_LIST);
@@ -7966,21 +7966,18 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
              continue;
            }
 
-       case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_DOACROSS:
          t = OMP_CLAUSE_DECL (c);
          if (t == NULL_TREE)
+           break;
+         if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
            {
-             gcc_assert (OMP_CLAUSE_DEPEND_KIND (c)
-                         == OMP_CLAUSE_DEPEND_SOURCE);
-             break;
-           }
-         if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
-           {
-             if (cp_finish_omp_clause_depend_sink (c))
+             if (cp_finish_omp_clause_doacross_sink (c))
                remove = true;
              break;
            }
-         /* FALLTHRU */
+         gcc_unreachable ();
+       case OMP_CLAUSE_DEPEND:
        case OMP_CLAUSE_AFFINITY:
          t = OMP_CLAUSE_DECL (c);
          if (TREE_CODE (t) == TREE_LIST
index f623b7201bbe320f67f32925f04af9a17d459693..84aefdad57322acc2b197dea1e278d23fa28c44b 100644 (file)
@@ -1,3 +1,14 @@
+2022-09-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * trans-openmp.cc (gfc_trans_omp_clauses): Use
+       OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
+       OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS
+       clause instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND
+       on it.
+
 2022-08-30  Tobias Burnus  <tobias@codesourcery.com>
 
        Backport from mainline:
index 31ad6255f247ee41621ccf5d5712b792b0e8f7a7..a4d75b19921d10628f16332c35693564a6624334 100644 (file)
@@ -4292,7 +4292,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
                            }
                          vec = tree_cons (addend, t, vec);
                          if (neg)
-                           OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
+                           OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
                        }
                      if (n->next == NULL
                          || n->next->u.depend_op != OMP_DEPEND_SINK)
@@ -4303,8 +4303,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
                    continue;
 
                  tree node = build_omp_clause (input_location,
-                                               OMP_CLAUSE_DEPEND);
-                 OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_SINK;
+                                               OMP_CLAUSE_DOACROSS);
+                 OMP_CLAUSE_DOACROSS_KIND (node) = OMP_CLAUSE_DOACROSS_SINK;
+                 OMP_CLAUSE_DOACROSS_DEPEND (node) = 1;
                  OMP_CLAUSE_DECL (node) = nreverse (vec);
                  omp_clauses = gfc_trans_add_clause (node, omp_clauses);
                  continue;
@@ -5763,8 +5764,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
 
   if (clauses->depend_source)
     {
-      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DEPEND);
-      OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_SOURCE;
+      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DOACROSS);
+      OMP_CLAUSE_DOACROSS_KIND (c) = OMP_CLAUSE_DOACROSS_SOURCE;
+      OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
 
index 6b0ec75f01ae74518f7df4c942ccbf4626b8a3cc..493a42eff4f8aa03bab5177eb75ccac281e6fa7f 100644 (file)
@@ -8330,9 +8330,6 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
          case OMP_CLAUSE_DEPEND_INOUTSET:
            i = 4;
            break;
-         case OMP_CLAUSE_DEPEND_SOURCE:
-         case OMP_CLAUSE_DEPEND_SINK:
-           continue;
          default:
            gcc_unreachable ();
          }
@@ -8571,9 +8568,6 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
          case OMP_CLAUSE_DEPEND_INOUTSET:
            i = 4;
            break;
-         case OMP_CLAUSE_DEPEND_SOURCE:
-         case OMP_CLAUSE_DEPEND_SINK:
-           continue;
          default:
            gcc_unreachable ();
          }
@@ -10860,8 +10854,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
          gimplify_omp_affinity (list_p, pre_p);
          remove = true;
          break;
-       case OMP_CLAUSE_DEPEND:
-         if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+       case OMP_CLAUSE_DOACROSS:
+         if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
            {
              tree deps = OMP_CLAUSE_DECL (c);
              while (deps && TREE_CODE (deps) == TREE_LIST)
@@ -10872,10 +10866,12 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                                   pre_p, NULL, is_gimple_val, fb_rvalue);
                  deps = TREE_CHAIN (deps);
                }
-             break;
            }
-         else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
-           break;
+         else
+           gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
+                       == OMP_CLAUSE_DOACROSS_SOURCE);
+         break;
+       case OMP_CLAUSE_DEPEND:
          if (handled_depend_iterators == -1)
            handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
          if (handled_depend_iterators)
@@ -12579,6 +12575,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
        case OMP_CLAUSE_SAFELEN:
        case OMP_CLAUSE_SIMDLEN:
        case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_DOACROSS:
        case OMP_CLAUSE_PRIORITY:
        case OMP_CLAUSE_GRAINSIZE:
        case OMP_CLAUSE_NUM_TASKS:
@@ -13152,6 +13149,30 @@ localize_reductions (tree clauses, tree body)
 }
 
 
+/* Helper function of gimplify_omp_for, find OMP_ORDERED with
+   OMP_CLAUSE_DOACROSS clause inside of OMP_FOR's body.  */
+
+static tree
+find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
+{
+  switch (TREE_CODE (*tp))
+    {
+    case OMP_ORDERED:
+      if (omp_find_clause (OMP_ORDERED_CLAUSES (*tp), OMP_CLAUSE_DOACROSS))
+       return *tp;
+      break;
+    case OMP_SIMD:
+    case OMP_PARALLEL:
+    case OMP_TARGET:
+      *walk_subtrees = 0;
+      break;
+    default:
+      break;
+    }
+  return NULL_TREE;
+}
+
+
 /* Gimplify the gross structure of an OMP_FOR statement.  */
 
 static enum gimplify_status
@@ -13543,12 +13564,24 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
 
   tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
   bool is_doacross = false;
-  if (c && OMP_CLAUSE_ORDERED_EXPR (c))
+  if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
+                                        find_standalone_omp_ordered, NULL))
     {
+      OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
       is_doacross = true;
-      gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
-                                                (OMP_FOR_INIT (for_stmt))
-                                              * 2);
+      int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
+      gimplify_omp_ctxp->loop_iter_var.create (len * 2);
+      for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
+       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
+         {
+           error_at (OMP_CLAUSE_LOCATION (*pc),
+                     "%<linear%> clause may not be specified together "
+                     "with %<ordered%> clause if stand-alone %<ordered%> "
+                     "construct is nested in it");
+           *pc = OMP_CLAUSE_CHAIN (*pc);
+         }
+       else
+         pc = &OMP_CLAUSE_CHAIN (*pc);
     }
   int collapse = 1, tile = 0;
   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
@@ -15709,21 +15742,22 @@ gimplify_omp_ordered (tree expr, gimple_seq body)
   if (gimplify_omp_ctxp)
     {
       for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
-       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-           && gimplify_omp_ctxp->loop_iter_var.is_empty ()
-           && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
-               || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
+       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
+           && gimplify_omp_ctxp->loop_iter_var.is_empty ())
          {
            error_at (OMP_CLAUSE_LOCATION (c),
-                     "%<ordered%> construct with %<depend%> clause must be "
-                     "closely nested inside a loop with %<ordered%> clause "
-                     "with a parameter");
+                     "%<ordered%> construct with %qs clause must be "
+                     "closely nested inside a loop with %<ordered%> clause",
+                     OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
            failures++;
          }
-       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-                && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
+                && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
          {
            bool fail = false;
+           sink_c = c;
+           if (OMP_CLAUSE_DECL (c) == NULL_TREE)
+             continue;  /* omp_cur_iteration - 1 */
            for (decls = OMP_CLAUSE_DECL (c), i = 0;
                 decls && TREE_CODE (decls) == TREE_LIST;
                 decls = TREE_CHAIN (decls), ++i)
@@ -15746,21 +15780,24 @@ gimplify_omp_ordered (tree expr, gimple_seq body)
            if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
              {
                error_at (OMP_CLAUSE_LOCATION (c),
-                         "number of variables in %<depend%> clause with "
+                         "number of variables in %qs clause with "
                          "%<sink%> modifier does not match number of "
-                         "iteration variables");
+                         "iteration variables",
+                         OMP_CLAUSE_DOACROSS_DEPEND (c)
+                         ? "depend" : "doacross");
                failures++;
              }
-           sink_c = c;
          }
-       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-                && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
+       else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
+                && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
          {
            if (source_c)
              {
                error_at (OMP_CLAUSE_LOCATION (c),
-                         "more than one %<depend%> clause with %<source%> "
-                         "modifier on an %<ordered%> construct");
+                         "more than one %qs clause with %<source%> "
+                         "modifier on an %<ordered%> construct",
+                         OMP_CLAUSE_DOACROSS_DEPEND (source_c)
+                         ? "depend" : "doacross");
                failures++;
              }
            else
@@ -15770,9 +15807,11 @@ gimplify_omp_ordered (tree expr, gimple_seq body)
   if (source_c && sink_c)
     {
       error_at (OMP_CLAUSE_LOCATION (source_c),
-               "%<depend%> clause with %<source%> modifier specified "
-               "together with %<depend%> clauses with %<sink%> modifier "
-               "on the same construct");
+               "%qs clause with %<source%> modifier specified "
+               "together with %qs clauses with %<sink%> modifier "
+               "on the same construct",
+               OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
+               OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
       failures++;
     }
 
index 471f35c315fcc31aaf4b816ac70dcfa0b6707eb3..1bc3f5515994eadf3dfe4b4fc80c13af978277d5 100644 (file)
@@ -1553,6 +1553,9 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map,
        case OMP_CLAUSE_DEPEND:
          val = OMP_CLAUSE_DEPEND_KIND (t);
          break;
+       case OMP_CLAUSE_DOACROSS:
+         val = OMP_CLAUSE_DOACROSS_KIND (t);
+         break;
        case OMP_CLAUSE_MAP:
          val = OMP_CLAUSE_MAP_KIND (t);
          break;
index 9f887c2d0e162ef74c3831fb726a1503c97e4b14..48a0c8b634f7949d0393fd5bc58f283f1b424b63 100644 (file)
@@ -3306,6 +3306,11 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
   gimple_stmt_iterator gsi2 = *gsi;
   bool warned_step = false;
 
+  if (deps == NULL)
+    {
+      sorry_at (loc, "%<doacross(sink:omp_cur_iteration-1)%> not supported yet");
+      return;
+    }
   for (i = 0; i < fd->ordered; i++)
     {
       tree step = NULL_TREE;
@@ -3329,9 +3334,11 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
                break;
              forward = tree_int_cst_sgn (step) != -1;
            }
-         if (forward ^ OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
-           warning_at (loc, 0, "%<depend%> clause with %<sink%> modifier "
-                               "waiting for lexically later iteration");
+         if (forward ^ OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
+           warning_at (loc, 0, "%qs clause with %<sink%> modifier "
+                               "waiting for lexically later iteration",
+                       OMP_CLAUSE_DOACROSS_DEPEND (c)
+                       ? "depend" : "doacross");
          break;
        }
       deps = TREE_CHAIN (deps);
@@ -3385,13 +3392,13 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
          tree co = fold_convert_loc (loc, itype, off);
          if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
            {
-             if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+             if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
                co = fold_build1_loc (loc, NEGATE_EXPR, itype, co);
              a = fold_build2_loc (loc, POINTER_PLUS_EXPR,
                                   TREE_TYPE (fd->loops[i].v), fd->loops[i].v,
                                   co);
            }
-         else if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+         else if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
            a = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (fd->loops[i].v),
                                 fd->loops[i].v, co);
          else
@@ -3400,13 +3407,13 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
          if (step)
            {
              tree t1, t2;
-             if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+             if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
                t1 = fold_build2_loc (loc, GE_EXPR, boolean_type_node, a,
                                      fd->loops[i].n1);
              else
                t1 = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a,
                                      fd->loops[i].n2);
-             if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+             if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
                t2 = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a,
                                      fd->loops[i].n2);
              else
@@ -3428,14 +3435,14 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
            }
          else if (fd->loops[i].cond_code == LT_EXPR)
            {
-             if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+             if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
                t = fold_build2_loc (loc, GE_EXPR, boolean_type_node, a,
                                     fd->loops[i].n1);
              else
                t = fold_build2_loc (loc, LT_EXPR, boolean_type_node, a,
                                     fd->loops[i].n2);
            }
-         else if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+         else if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
            t = fold_build2_loc (loc, GT_EXPR, boolean_type_node, a,
                                 fd->loops[i].n2);
          else
@@ -3467,9 +3474,11 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
                               build_int_cst (itype, 0));
          if (integer_zerop (t) && !warned_step)
            {
-             warning_at (loc, 0, "%<depend%> clause with %<sink%> modifier "
+             warning_at (loc, 0, "%qs clause with %<sink%> modifier "
                                  "refers to iteration never in the iteration "
-                                 "space");
+                                 "space",
+                         OMP_CLAUSE_DOACROSS_DEPEND (c)
+                         ? "depend" : "doacross");
              warned_step = true;
            }
          cond = fold_build2_loc (loc, BIT_AND_EXPR, boolean_type_node,
@@ -3494,7 +3503,7 @@ expand_omp_ordered_sink (gimple_stmt_iterator *gsi, struct omp_for_data *fd,
                                                s));
       else
        off = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, off, s);
-      if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (deps))
+      if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps))
        off = fold_build1_loc (loc, NEGATE_EXPR, itype, off);
       off = fold_convert_loc (loc, fd->iter_type, off);
       if (i <= fd->collapse - 1 && fd->collapse > 1)
@@ -3567,13 +3576,13 @@ expand_omp_ordered_source_sink (struct omp_region *region,
        tree c;
        for (c = gimple_omp_ordered_clauses (ord_stmt);
             c; c = OMP_CLAUSE_CHAIN (c))
-         if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
+         if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
            break;
        if (c)
          expand_omp_ordered_source (&gsi, fd, counts, loc);
        for (c = gimple_omp_ordered_clauses (ord_stmt);
             c; c = OMP_CLAUSE_CHAIN (c))
-         if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+         if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
            expand_omp_ordered_sink (&gsi, fd, counts, c, loc);
        gsi_remove (&gsi, true);
       }
@@ -10611,7 +10620,7 @@ expand_omp (struct omp_region *region)
            gomp_ordered *ord_stmt
              = as_a <gomp_ordered *> (last_stmt (region->entry));
            if (omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
-                                OMP_CLAUSE_DEPEND))
+                                OMP_CLAUSE_DOACROSS))
              {
                /* We'll expand these when expanding corresponding
                   worksharing region with ordered(n) clause.  */
@@ -10746,7 +10755,7 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
          else if (code == GIMPLE_OMP_ORDERED
                   && omp_find_clause (gimple_omp_ordered_clauses
                                         (as_a <gomp_ordered *> (stmt)),
-                                      OMP_CLAUSE_DEPEND))
+                                      OMP_CLAUSE_DOACROSS))
            /* #pragma omp ordered depend is also just a stand-alone
               directive.  */
            region = NULL;
@@ -10972,7 +10981,7 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region,
       fallthru = true;
       if (omp_find_clause (gimple_omp_ordered_clauses
                             (as_a <gomp_ordered *> (last)),
-                          OMP_CLAUSE_DEPEND))
+                          OMP_CLAUSE_DOACROSS))
        cur_region = cur_region->outer;
       break;
 
index 13d9a5e4492a096cfba6fede189171f818d1e1b8..aae5d105bdba227e170935ee200037646151fdbc 100644 (file)
@@ -242,8 +242,13 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
        break;
       case OMP_CLAUSE_ORDERED:
        fd->have_ordered = true;
-       if (OMP_CLAUSE_ORDERED_EXPR (t))
-         fd->ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (t));
+       if (OMP_CLAUSE_ORDERED_DOACROSS (t))
+         {
+           if (OMP_CLAUSE_ORDERED_EXPR (t))
+             fd->ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (t));
+           else
+             fd->ordered = -1;
+         }
        break;
       case OMP_CLAUSE_SCHEDULE:
        gcc_assert (!distribute && !taskloop);
@@ -302,6 +307,9 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
        break;
       }
 
+  if (fd->ordered == -1)
+    fd->ordered = fd->collapse;
+
   /* For order(reproducible:concurrent) schedule ({dynamic,guided,runtime})
      we have either the option to expensively remember at runtime how we've
      distributed work from first loop and reuse that in following loops with
index ea51ff9e6973632099c5ddd9e120d6a54df35481..ce114af7518c0cd046cf79076eb8b0499f03761f 100644 (file)
@@ -4115,14 +4115,13 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
       break;
     case GIMPLE_OMP_TASK:
       for (c = gimple_omp_task_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
-       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-           && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
-               || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
+       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS)
          {
-           enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
+           enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_KIND (c);
            error_at (OMP_CLAUSE_LOCATION (c),
-                     "%<depend(%s)%> is only allowed in %<omp ordered%>",
-                     kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
+                     "%<%s(%s)%> is only allowed in %<omp ordered%>",
+                     OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross",
+                     kind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
            return false;
          }
       break;
@@ -4130,43 +4129,30 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
       for (c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
           c; c = OMP_CLAUSE_CHAIN (c))
        {
-         if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
+         if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DOACROSS)
            {
-             gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
-                         || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
-             continue;
-           }
-         enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
-         if (kind == OMP_CLAUSE_DEPEND_SOURCE
-             || kind == OMP_CLAUSE_DEPEND_SINK)
-           {
-             tree oclause;
-             /* Look for containing ordered(N) loop.  */
-             if (ctx == NULL
-                 || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
-                 || (oclause
-                       = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
-                                          OMP_CLAUSE_ORDERED)) == NULL_TREE)
+             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
                {
                  error_at (OMP_CLAUSE_LOCATION (c),
-                           "%<ordered%> construct with %<depend%> clause "
-                           "must be closely nested inside an %<ordered%> "
-                           "loop");
-                 return false;
-               }
-             else if (OMP_CLAUSE_ORDERED_EXPR (oclause) == NULL_TREE)
-               {
-                 error_at (OMP_CLAUSE_LOCATION (c),
-                           "%<ordered%> construct with %<depend%> clause "
-                           "must be closely nested inside a loop with "
-                           "%<ordered%> clause with a parameter");
+                           "invalid depend kind in omp %<ordered%> %<depend%>");
                  return false;
                }
+             gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREADS
+                         || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMD);
+             continue;
            }
-         else
+
+         tree oclause;
+         /* Look for containing ordered(N) loop.  */
+         if (ctx == NULL
+             || gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
+             || (oclause
+                 = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
+                                    OMP_CLAUSE_ORDERED)) == NULL_TREE)
            {
              error_at (OMP_CLAUSE_LOCATION (c),
-                       "invalid depend kind in omp %<ordered%> %<depend%>");
+                       "%<ordered%> construct with %<depend%> clause "
+                       "must be closely nested inside an %<ordered%> loop");
              return false;
            }
        }
@@ -4211,14 +4197,37 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
                          "a loop region with an %<ordered%> clause");
                return false;
              }
-           if (OMP_CLAUSE_ORDERED_EXPR (o) != NULL_TREE
-               && omp_find_clause (c, OMP_CLAUSE_DEPEND) == NULL_TREE)
+           if (omp_find_clause (c, OMP_CLAUSE_DOACROSS) == NULL_TREE)
              {
-               error_at (gimple_location (stmt),
-                         "%<ordered%> region without %<depend%> clause may "
-                         "not be closely nested inside a loop region with "
-                         "an %<ordered%> clause with a parameter");
-               return false;
+               if (OMP_CLAUSE_ORDERED_DOACROSS (o))
+                 {
+                   error_at (gimple_location (stmt),
+                             "%<ordered%> construct without %<doacross%> or "
+                             "%<depend%> clauses must not have the same "
+                             "binding region as %<ordered%> construct with "
+                             "those clauses");
+                   return false;
+                 }
+               else if (OMP_CLAUSE_ORDERED_EXPR (o))
+                 {
+                   tree co
+                     = omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
+                                        OMP_CLAUSE_COLLAPSE);
+                   HOST_WIDE_INT
+                     o_n = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (o));
+                   HOST_WIDE_INT c_n = 1;
+                   if (co)
+                     c_n = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
+                   if (o_n != c_n)
+                     {
+                       error_at (gimple_location (stmt),
+                                 "%<ordered%> construct without %<doacross%> "
+                                 "or %<depend%> clauses binds to loop where "
+                                 "%<collapse%> argument %wd is different from "
+                                 "%<ordered%> argument %wd", c_n, o_n);
+                       return false;
+                     }
+                 }
              }
            return true;
          case GIMPLE_OMP_TARGET:
@@ -4272,14 +4281,12 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
       break;
     case GIMPLE_OMP_TARGET:
       for (c = gimple_omp_target_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
-       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-           && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE
-               || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK))
+       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS)
          {
-           enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_KIND (c);
+           enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_KIND (c);
            error_at (OMP_CLAUSE_LOCATION (c),
                      "%<depend(%s)%> is only allowed in %<omp ordered%>",
-                     kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
+                     kind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
            return false;
          }
       if (is_gimple_omp_offloaded (stmt)
@@ -10438,8 +10445,8 @@ lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
 
   tree *list_p = gimple_omp_ordered_clauses_ptr (ord_stmt);
   tree c = gimple_omp_ordered_clauses (ord_stmt);
-  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
-      && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
+  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
+      && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
     {
       /* Merge depend clauses from multiple adjacent
         #pragma omp ordered depend(sink:...) constructs
@@ -10461,8 +10468,8 @@ lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
          gomp_ordered *ord_stmt2 = as_a <gomp_ordered *> (stmt);
          c = gimple_omp_ordered_clauses (ord_stmt2);
          if (c == NULL_TREE
-             || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
-             || OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
+             || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DOACROSS
+             || OMP_CLAUSE_DOACROSS_KIND (c) != OMP_CLAUSE_DOACROSS_SINK)
            break;
          while (*list_p)
            list_p = &OMP_CLAUSE_CHAIN (*list_p);
@@ -10529,8 +10536,8 @@ lower_omp_ordered_clauses (gimple_stmt_iterator *gsi_p, gomp_ordered *ord_stmt,
     {
       bool remove = false;
 
-      gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND);
-      if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_SINK)
+      gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS);
+      if (OMP_CLAUSE_DOACROSS_KIND (c) != OMP_CLAUSE_DOACROSS_SINK)
        goto next_ordered_clause;
 
       tree vec;
@@ -10681,7 +10688,7 @@ lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
                                  OMP_CLAUSE_THREADS);
 
   if (omp_find_clause (gimple_omp_ordered_clauses (ord_stmt),
-                      OMP_CLAUSE_DEPEND))
+                      OMP_CLAUSE_DOACROSS))
     {
       /* FIXME: This is needs to be moved to the expansion to verify various
         conditions only testable on cfg with dominators computed, and also
@@ -13149,9 +13156,6 @@ lower_depend_clauses (tree *pclauses, gimple_seq *iseq, gimple_seq *oseq)
        case OMP_CLAUSE_DEPEND_INOUTSET:
          cnt[4]++;
          break;
-       case OMP_CLAUSE_DEPEND_SOURCE:
-       case OMP_CLAUSE_DEPEND_SINK:
-         /* FALLTHRU */
        default:
          gcc_unreachable ();
        }
index ab273766e31eecfb94aed899af368e6365a0af8a..9daad25790ff6ee330ca3a1669db2d085a951d0f 100644 (file)
@@ -1,3 +1,16 @@
+2022-09-05  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backport from mainline:
+       2022-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/doacross-2.c: Adjust expected diagnostics.
+       * c-c++-common/gomp/doacross-5.c: New test.
+       * c-c++-common/gomp/doacross-6.c: New test.
+       * c-c++-common/gomp/nesting-2.c: Adjust expected diagnostics.
+       * c-c++-common/gomp/ordered-3.c: Likewise.
+       * c-c++-common/gomp/sink-3.c: Likewise.
+       * gfortran.dg/gomp/nesting-2.f90: Likewise.
+
 2022-09-01  Andrew Stubbs  <ams@codesourcery.com>
 
        * gcc.dg/vect/vect-simd-clone-1.c: Add dg-warning.
index cc454879553fa5d4bfc0e596b3f07162e5a58def..44c5c212c89762893ae717aae54620295111cc75 100644 (file)
@@ -7,13 +7,13 @@ foo (void)
   #pragma omp for ordered(1)
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered                      /* { dg-error "'ordered' region without 'depend' clause may not be closely nested inside a loop region with an 'ordered' clause with a parameter" } */
+      #pragma omp ordered
       ;
     }
   #pragma omp for ordered(1)
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered threads              /* { dg-error "'ordered' region without 'depend' clause may not be closely nested inside a loop region with an 'ordered' clause with a parameter" } */
+      #pragma omp ordered threads
       ;
     }
 }
@@ -25,14 +25,20 @@ bar (void)
   #pragma omp for ordered
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered depend(source)       /* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
+      #pragma omp ordered depend(source)
+      #pragma omp ordered depend(sink: i - 1)
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered doacross(source:)
+      #pragma omp ordered doacross(sink: i - 1)
     }
   #pragma omp for
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered depend(source)       /* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause with a parameter" } */
+      #pragma omp ordered depend(source)       /* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause" } */
+      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "'ordered' construct with 'depend' clause must be closely nested inside a loop with 'ordered' clause" } */
     }
   #pragma omp for
   for (i = 0; i < 64; i++)
diff --git a/gcc/testsuite/c-c++-common/gomp/doacross-5.c b/gcc/testsuite/c-c++-common/gomp/doacross-5.c
new file mode 100644 (file)
index 0000000..9dd6dbf
--- /dev/null
@@ -0,0 +1,94 @@
+void
+foo (int n)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(source:)
+      #pragma omp ordered doacross(sink: i - 2)
+    }
+}
+
+void
+bar (int n)
+{
+  int i, j;
+  #pragma omp for collapse(2) ordered(2)
+  for (i = 0; i < 8; i += n)
+    for (j = 0; j < 8; j += n)
+      {
+       #pragma omp ordered doacross(source:omp_cur_iteration)
+       #pragma omp ordered doacross(sink: i - 2, j + 2)
+      }
+}
+
+void
+baz (void)
+{
+  int i, j;
+  #pragma omp for ordered(1)
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered                      /* { dg-error "'ordered' construct without 'doacross' or 'depend' clauses must not have the same binding region as 'ordered' construct with those clauses" } */
+      ;
+      #pragma omp ordered doacross(source:)
+      #pragma omp ordered doacross(sink: i - 1)
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered doacross(source: omp_cur_iteration )
+      #pragma omp ordered doacross(sink: i - 1)
+      #pragma omp ordered threads              /* { dg-error "'ordered' construct without 'doacross' or 'depend' clauses must not have the same binding region as 'ordered' construct with those clauses" } */
+      ;
+    }
+  #pragma omp for ordered(2)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       #pragma omp ordered                     /* { dg-error "'ordered' construct without 'doacross' or 'depend' clauses binds to loop where 'collapse' argument 1 is different from 'ordered' argument 2" } */
+       ;
+      }
+  #pragma omp for ordered(2) collapse(1)
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      {
+       #pragma omp ordered threads             /* { dg-error "'ordered' construct without 'doacross' or 'depend' clauses binds to loop where 'collapse' argument 1 is different from 'ordered' argument 2" } */
+       ;
+      }
+}
+
+void
+qux (void)
+{
+  int i, j = 0;
+  #pragma omp for ordered linear(j)
+  for (i = 0; i < 64; i++)
+    {
+      ++j;
+      #pragma omp ordered
+      ;
+    }
+  #pragma omp for ordered linear(j)            /* { dg-error "'linear' clause may not be specified together with 'ordered' clause if stand-alone 'ordered' construct is nested in it" } */
+  for (i = 0; i < 64; i++)
+    {
+      ++j;
+      #pragma omp ordered doacross(source:)
+      #pragma omp ordered doacross(sink:i-1)
+    }
+  #pragma omp for ordered(1) linear(j)
+  for (i = 0; i < 64; i++)
+    {
+      ++j;
+      #pragma omp ordered
+      ;
+    }
+  #pragma omp for ordered(1) linear(j)         /* { dg-error "'linear' clause may not be specified together with 'ordered' clause if stand-alone 'ordered' construct is nested in it" } */
+  for (i = 0; i < 64; i++)
+    {
+      ++j;
+      #pragma omp ordered doacross(source:)
+      #pragma omp ordered doacross(sink:i-1)
+    }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/doacross-6.c b/gcc/testsuite/c-c++-common/gomp/doacross-6.c
new file mode 100644 (file)
index 0000000..d126ad1
--- /dev/null
@@ -0,0 +1,74 @@
+void
+foo (int n)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(source)             /* { dg-error "expected ':' before '\\\)' token" } */
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(source:omp_current_iteration)       /* { dg-error "expected '\\\)' before 'omp_current_iteration'" } */
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(source:i - 2)       /* { dg-error "expected '\\\)' before 'i'" } */
+    }
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(sink)               /* { dg-error "expected ':' before '\\\)' token" } */
+    }
+}
+
+void
+bar (int n)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(sink:omp_current_iteration - 1)     /* { dg-error "'omp_current_iteration' undeclared \\\(first use in this function\\\)" "" { target c } } */
+    }                                                                  /* { dg-error "'omp_current_iteration' has not been declared" "" { target c++ } .-1 } */
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(sink:omp_cur_iteration)     /* { dg-error "'omp_cur_iteration' undeclared \\\(first use in this function\\\)" "" { target c } } */
+    }                                                          /* { dg-error "'omp_cur_iteration' has not been declared" "" { target c++ } .-1 } */
+}
+
+void
+baz (int n)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(sink:omp_cur_iteration + 1) /* { dg-error "'omp_cur_iteration' undeclared \\\(first use in this function\\\)" "" { target c } } */
+    }                                                          /* { dg-error "'omp_cur_iteration' has not been declared" "" { target c++ } .-1 } */
+}
+
+void
+qux (int n)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(sink:omp_cur_iteration - (2 - 1))   /* { dg-error "'omp_cur_iteration' undeclared \\\(first use in this function\\\)" "" { target c } } */
+    }                                                          /* { dg-error "expected integer before '\\\(' token" "" { target *-*-* } .-1 } */
+}                                                              /* { dg-error "'omp_cur_iteration' has not been declared" "" { target c++ } .-2 } */
+                                                               /* { dg-error "expected '\\\)' before '\\\(' token" "" { target c++ } .-3 } */
+void
+corge (int n)
+{
+  int i;
+  #pragma omp for ordered
+  for (i = 0; i < 8; i += n)
+    {
+      #pragma omp ordered doacross(sink:omp_cur_iteration - 1LL)       /* { dg-error "'omp_cur_iteration' undeclared \\\(first use in this function\\\)" "" { target c } } */
+    }                                                                  /* { dg-error "'omp_cur_iteration' has not been declared" "" { target c++ } .-1 } */
+}
index 420cfd3cfa6add8acf9f229ffc343fce67aaea7e..6ce560de7f5e07c81390e34ca68be7f916c2d497 100644 (file)
@@ -160,7 +160,14 @@ foo (void)
   for (i = 0; i < 64; i++)
     #pragma omp parallel
     {
-      #pragma omp ordered depend(source)       /* { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered depend(source)       /* { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered depend(sink: i - 1)  /* { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause" } */
+    }
+  #pragma omp for ordered(1)
+  for (i = 0; i < 64; i++)
+    #pragma omp parallel
+    {
+      #pragma omp ordered doacross(source:)    /* { dg-error ".ordered. construct with .doacross. clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered doacross(sink: i - 1)        /* { dg-error ".ordered. construct with .doacross. clause must be closely nested inside a loop with .ordered. clause" } */
     }
 }
index e7fd738f6697c013be584548508abada9ad7731f..b007ca7982a367dd275656e11539dba29158f28c 100644 (file)
@@ -47,29 +47,53 @@ foo (void)
       #pragma omp ordered threads, simd, threads, simd /* { dg-error "too many .threads. clauses" } */
       ;        /* { dg-error "too many .simd. clauses" "" { target *-*-* } .-1 } */
     }
-  #pragma omp for simd ordered(1)      /* { dg-error ".ordered. clause with parameter may not be specified on .#pragma omp for simd. construct" } */
+  #pragma omp for simd ordered(1)
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
-      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
     }
-  #pragma omp parallel for simd ordered(1)     /* { dg-error ".ordered. clause with parameter may not be specified on .#pragma omp parallel for simd. construct" } */
+  #pragma omp for simd ordered(1)
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
-      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered doacross(sink: i - 1)        /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered doacross(source:omp_cur_iteration)   /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+    }
+  #pragma omp parallel for simd ordered(1)
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+    }
+  #pragma omp parallel for simd ordered(1)
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered doacross(sink: i - 1)        /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered doacross(source:)    /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+    }
+  #pragma omp parallel for ordered
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(sink: i - 1)
+      #pragma omp ordered depend(source)
     }
   #pragma omp parallel for ordered
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
-      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered doacross(sink: i - 1)
+      #pragma omp ordered doacross(source:)
+    }
+  #pragma omp parallel for
+  for (i = 0; i < 64; i++)
+    {
+      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
     }
   #pragma omp parallel for
   for (i = 0; i < 64; i++)
     {
-      #pragma omp ordered depend(sink: i - 1)  /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
-      #pragma omp ordered depend(source)       /* { dg-error "clause must be closely nested inside a loop with .ordered. clause with a parameter" } */
+      #pragma omp ordered doacross(sink: i - 1)        /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
+      #pragma omp ordered doacross(source:)    /* { dg-error "clause must be closely nested inside a loop with .ordered. clause" } */
     }
 }
 
index 588aea215c947cdde03c6786ba3b36b44d7842da..3f7ba5e307db3731b44cf5e7ecc19ef4d37bb359 100644 (file)
@@ -14,7 +14,7 @@ foo ()
   for (i=0; i < 100; ++i)
     {
 #pragma omp ordered depend(sink:poo-1,paa+1) /* { dg-error "poo.*declared.*paa.*declared" } */
-    bar(&i);                                /* { dg-error "may not be closely nested" "" { target *-*-* } .-1 } */
+    bar(&i);                                /* { dg-error "must not have the same binding region" "" { target *-*-* } .-1 } */
 #pragma omp ordered depend(source)
     }
 }
index 2eccdf9b03474a7e6f1f2b3ef8e282c0ff89fa1b..d8014d6f151a85a9a9995cc4d5b5249c8e301516 100644 (file)
@@ -158,8 +158,8 @@ subroutine foo
   !$omp do ordered(1)
   do i = 0, 63
     !$omp parallel
-      !$omp ordered depend(source)     ! { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause with a parameter" }
-      !$omp ordered depend(sink: i - 1)        ! { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause with a parameter" }
+      !$omp ordered depend(source)     ! { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause" }
+      !$omp ordered depend(sink: i - 1)        ! { dg-error ".ordered. construct with .depend. clause must be closely nested inside a loop with .ordered. clause" }
     !$omp end parallel
   end do
 end
index d65e474f1b3f21590bd5733bd24581ec74383bd7..030007ba77b49961e15ca81ad83e2bbfe03072c5 100644 (file)
@@ -347,6 +347,9 @@ enum omp_clause_code {
   /* OpenMP clause: has_device_addr (variable-list).  */
   OMP_CLAUSE_HAS_DEVICE_ADDR,
 
+  /* OpenMP clause: doacross ({source,sink}:vec).  */
+  OMP_CLAUSE_DOACROSS,
+
   /* Internal structure to hold OpenACC cache directive's variable-list.
      #pragma acc cache (variable-list).  */
   OMP_CLAUSE__CACHE_,
@@ -1542,12 +1545,18 @@ enum omp_clause_depend_kind
   OMP_CLAUSE_DEPEND_INOUT,
   OMP_CLAUSE_DEPEND_MUTEXINOUTSET,
   OMP_CLAUSE_DEPEND_INOUTSET,
-  OMP_CLAUSE_DEPEND_SOURCE,
-  OMP_CLAUSE_DEPEND_SINK,
   OMP_CLAUSE_DEPEND_DEPOBJ,
+  OMP_CLAUSE_DEPEND_INVALID,
   OMP_CLAUSE_DEPEND_LAST
 };
 
+enum omp_clause_doacross_kind
+{
+  OMP_CLAUSE_DOACROSS_SOURCE,
+  OMP_CLAUSE_DOACROSS_SINK,
+  OMP_CLAUSE_DOACROSS_LAST
+};
+
 enum omp_clause_proc_bind_kind
 {
   /* Numbers should match omp_proc_bind_t enum in omp.h.  */
@@ -1635,6 +1644,7 @@ struct GTY(()) tree_omp_clause {
     enum omp_clause_default_kind   default_kind;
     enum omp_clause_schedule_kind  schedule_kind;
     enum omp_clause_depend_kind    depend_kind;
+    enum omp_clause_doacross_kind  doacross_kind;
     /* See include/gomp-constants.h for enum gomp_map_kind's values.  */
     unsigned int                  map_kind;
     enum omp_clause_proc_bind_kind proc_bind_kind;
index 995280904b068a501dc3222f3707fd1b893edf48..ea7d57a0591c6fbe08862814b02833f5bf2eb50c 100644 (file)
@@ -1368,6 +1368,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_DOACROSS:
        case OMP_CLAUSE_DEVICE:
        case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_THREAD_LIMIT:
@@ -2157,6 +2158,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_DEPEND:
+       case OMP_CLAUSE_DOACROSS:
        case OMP_CLAUSE_DEVICE:
        case OMP_CLAUSE_NUM_TEAMS:
        case OMP_CLAUSE_THREAD_LIMIT:
index 8950ea884926bd49c737dfdc328cff899402f6a4..3ef98f050989a2aaa1b048405f20cc0b9f807a3d 100644 (file)
@@ -859,34 +859,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
        case OMP_CLAUSE_DEPEND_INOUTSET:
          name = "inoutset";
          break;
-       case OMP_CLAUSE_DEPEND_SOURCE:
-         pp_string (pp, "source)");
-         return;
        case OMP_CLAUSE_DEPEND_LAST:
          name = "__internal__";
          break;
-       case OMP_CLAUSE_DEPEND_SINK:
-         pp_string (pp, "sink:");
-         for (tree t = OMP_CLAUSE_DECL (clause); t; t = TREE_CHAIN (t))
-           if (TREE_CODE (t) == TREE_LIST)
-             {
-               dump_generic_node (pp, TREE_VALUE (t), spc, flags, false);
-               if (TREE_PURPOSE (t) != integer_zero_node)
-                 {
-                   if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (t))
-                     pp_minus (pp);
-                   else
-                     pp_plus (pp);
-                   dump_generic_node (pp, TREE_PURPOSE (t), spc, flags,
-                                      false);
-                 }
-               if (TREE_CHAIN (t))
-                 pp_comma (pp);
-             }
-           else
-             gcc_unreachable ();
-         pp_right_paren (pp);
-         return;
        default:
          gcc_unreachable ();
        }
@@ -913,6 +888,49 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
       }
       break;
 
+    case OMP_CLAUSE_DOACROSS:
+      pp_string (pp, OMP_CLAUSE_DOACROSS_DEPEND (clause)
+                    ? "depend(" : "doacross(");
+      switch (OMP_CLAUSE_DOACROSS_KIND (clause))
+       {
+       case OMP_CLAUSE_DOACROSS_SOURCE:
+         if (OMP_CLAUSE_DOACROSS_DEPEND (clause))
+           pp_string (pp, "source)");
+         else
+           pp_string (pp, "source:)");
+         break;
+       case OMP_CLAUSE_DOACROSS_SINK:
+         pp_string (pp, "sink:");
+         if (OMP_CLAUSE_DECL (clause) == NULL_TREE)
+           {
+             pp_string (pp, "omp_cur_iteration-1)");
+             break;
+           }
+         for (tree t = OMP_CLAUSE_DECL (clause); t; t = TREE_CHAIN (t))
+           if (TREE_CODE (t) == TREE_LIST)
+             {
+               dump_generic_node (pp, TREE_VALUE (t), spc, flags, false);
+               if (TREE_PURPOSE (t) != integer_zero_node)
+                 {
+                   if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (t))
+                     pp_minus (pp);
+                   else
+                     pp_plus (pp);
+                   dump_generic_node (pp, TREE_PURPOSE (t), spc, flags,
+                                      false);
+                 }
+               if (TREE_CHAIN (t))
+                 pp_comma (pp);
+             }
+           else
+             gcc_unreachable ();
+         pp_right_paren (pp);
+         break;
+       default:
+         gcc_unreachable ();
+       }
+      break;
+
     case OMP_CLAUSE_MAP:
       pp_string (pp, "map(");
       switch (OMP_CLAUSE_MAP_KIND (clause))
index a35a810f4d100240341bb3d3421a77505d82c403..0c55dea9b91723f7f36d8167c0425b6f05293fcb 100644 (file)
@@ -456,6 +456,11 @@ unpack_ts_omp_clause_value_fields (class data_in *data_in,
       OMP_CLAUSE_DEPEND_KIND (expr)
        = bp_unpack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST);
       break;
+    case OMP_CLAUSE_DOACROSS:
+      OMP_CLAUSE_DOACROSS_KIND (expr)
+       = bp_unpack_enum (bp, omp_clause_doacross_kind,
+                         OMP_CLAUSE_DOACROSS_LAST);
+      break;
     case OMP_CLAUSE_MAP:
       OMP_CLAUSE_SET_MAP_KIND (expr, bp_unpack_enum (bp, gomp_map_kind,
                                                     GOMP_MAP_LAST));
index d39dc158a4650d802d9f3dc6feed99e4749aab37..9b114dc05bb1c08f0ea57869a1a90817c4d52a06 100644 (file)
@@ -419,6 +419,10 @@ pack_ts_omp_clause_value_fields (struct output_block *ob,
       bp_pack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST,
                    OMP_CLAUSE_DEPEND_KIND (expr));
       break;
+    case OMP_CLAUSE_DOACROSS:
+      bp_pack_enum (bp, omp_clause_doacross_kind, OMP_CLAUSE_DOACROSS_LAST,
+                   OMP_CLAUSE_DOACROSS_KIND (expr));
+      break;
     case OMP_CLAUSE_MAP:
       bp_pack_enum (bp, gomp_map_kind, GOMP_MAP_LAST,
                    OMP_CLAUSE_MAP_KIND (expr));
index b28b86ba225ec7a7bf6751226697de15b3058339..46517ee8913fec17ed645433988a9cbbd4f33321 100644 (file)
@@ -292,6 +292,7 @@ unsigned const char omp_clause_num_ops[] =
   2, /* OMP_CLAUSE_TO  */
   2, /* OMP_CLAUSE_MAP  */
   1, /* OMP_CLAUSE_HAS_DEVICE_ADDR  */
+  1, /* OMP_CLAUSE_DOACROSS  */
   2, /* OMP_CLAUSE__CACHE_  */
   2, /* OMP_CLAUSE_GANG  */
   1, /* OMP_CLAUSE_ASYNC  */
@@ -384,6 +385,7 @@ const char * const omp_clause_code_name[] =
   "to",
   "map",
   "has_device_addr",
+  "doacross",
   "_cache_",
   "gang",
   "async",
index 8d855b3b4745ebadb190b861698917a7302d4714..4b1df4665d7060e5abdddeeafc7b0446cec01f3b 100644 (file)
@@ -1686,9 +1686,16 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_DEPEND_KIND(NODE) \
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEPEND)->omp_clause.subcode.depend_kind)
 
-#define OMP_CLAUSE_DEPEND_SINK_NEGATIVE(NODE) \
+#define OMP_CLAUSE_DOACROSS_KIND(NODE) \
+  (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DOACROSS)->omp_clause.subcode.doacross_kind)
+
+#define OMP_CLAUSE_DOACROSS_SINK_NEGATIVE(NODE) \
   TREE_PUBLIC (TREE_LIST_CHECK (NODE))
 
+/* True if DOACROSS clause is spelled as DEPEND.  */
+#define OMP_CLAUSE_DOACROSS_DEPEND(NODE) \
+  TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DOACROSS))
+
 #define OMP_CLAUSE_MAP_KIND(NODE) \
   ((enum gomp_map_kind) OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->omp_clause.subcode.map_kind)
 #define OMP_CLAUSE_SET_MAP_KIND(NODE, MAP_KIND) \
@@ -1750,6 +1757,11 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_ORDERED_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDERED), 0)
 
+/* True on an OMP_CLAUSE_ORDERED if stand-alone ordered construct is nested
+   inside of work-sharing loop the clause is on.  */
+#define OMP_CLAUSE_ORDERED_DOACROSS(NODE) \
+  (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDERED)->base.public_flag)
+
 /* True for unconstrained modifier on order(concurrent) clause.  */
 #define OMP_CLAUSE_ORDER_UNCONSTRAINED(NODE) \
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDER)->base.public_flag)