]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add OpenACC 2.6 `serial' construct support
authorMaciej W. Rozycki <macro@codesourcery.com>
Thu, 20 Dec 2018 14:10:18 +0000 (14:10 +0000)
committerThomas Schwinge <thomas@codesourcery.com>
Tue, 3 Mar 2020 11:16:05 +0000 (12:16 +0100)
The `serial' construct is equivalent to a `parallel' construct with
clauses `num_gangs(1) num_workers(1) vector_length(1)' implied.
Naturally these clauses are therefore not supported with the `serial'
construct.  All the remaining clauses accepted with `parallel' are also
accepted with `serial'.

Consequently implementation is straightforward, by handling `serial'
exactly like `parallel', except for hardcoding dimensions rather than
taking them from the relevant clauses, in `expand_omp_target'.

Separate codes are used to denote the `serial' construct throughout the
middle end, even though the mapping of `serial' to an equivalent
`parallel' construct could have been done in the individual language
frontends, saving a lot of mechanical changes and avoiding middle-end
code expansion.  This is so that any reporting such as with warning or
error messages and in diagnostic dumps use `serial' rather than
`parallel', therefore avoiding user confusion.

gcc/
* gimple.h (gf_mask): Add GF_OMP_TARGET_KIND_OACC_SERIAL
enumeration constant.
(is_gimple_omp_oacc): Handle GF_OMP_TARGET_KIND_OACC_SERIAL.
(is_gimple_omp_offloaded): Likewise.
* gimplify.c (omp_region_type): Add ORT_ACC_SERIAL enumeration
constant.  Adjust the value of ORT_NONE accordingly.
(is_gimple_stmt): Handle OACC_SERIAL.
(oacc_default_clause): Handle ORT_ACC_SERIAL.
(gomp_needs_data_present): Likewise.
(gimplify_adjust_omp_clauses): Likewise.
(gimplify_omp_workshare): Handle OACC_SERIAL.
(gimplify_expr): Likewise.
* omp-expand.c (expand_omp_target): Handle
GF_OMP_TARGET_KIND_OACC_SERIAL.
(build_omp_regions_1, omp_make_gimple_edges): Likewise.
* omp-low.c (is_oacc_parallel): Rename function to...
(is_oacc_parallel_or_serial): ... this.  Handle
GF_OMP_TARGET_KIND_OACC_SERIAL.
(build_receiver_ref): Adjust accordingly.
(build_sender_ref): Likewise.
(scan_sharing_clauses): Likewise.
(create_omp_child_function): Likewise.
(scan_omp_for): Likewise.
(scan_omp_target): Likewise.
(lower_oacc_head_mark): Likewise.
(convert_from_firstprivate_int): Likewise.
(lower_omp_target): Likewise.
(check_omp_nesting_restrictions): Handle
GF_OMP_TARGET_KIND_OACC_SERIAL.
(lower_oacc_reductions): Likewise.
(lower_omp_target): Likewise.
* tree-pretty-print.c (dump_generic_node): Handle OACC_SERIAL.
* tree.def (OACC_SERIAL): New tree code.

* doc/generic.texi (OpenACC): Document OACC_SERIAL.

gcc/c-family/
* c-pragma.h (pragma_kind): Add PRAGMA_OACC_SERIAL enumeration
constant.
* c-pragma.c (oacc_pragmas): Add "serial" entry.

gcc/c/
* c-parser.c (OACC_SERIAL_CLAUSE_MASK): New macro.
(OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK): Likewise.
(c_parser_oacc_kernels_parallel): Rename function to...
(c_parser_oacc_compute): ... this.  Handle PRAGMA_OACC_SERIAL.
(c_parser_omp_construct): Update accordingly.

gcc/cp/
* constexpr.c (potential_constant_expression_1): Handle
OACC_SERIAL.
* parser.c (OACC_SERIAL_CLAUSE_MASK): New macro.
(OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK): Likewise.
(cp_parser_oacc_kernels_parallel): Rename function to...
(cp_parser_oacc_compute): ... this.  Handle PRAGMA_OACC_SERIAL.
(cp_parser_omp_construct): Update accordingly.
(cp_parser_pragma): Handle PRAGMA_OACC_SERIAL.  Fix alphabetic
order.
* pt.c (tsubst_expr): Handle OACC_SERIAL.

gcc/fortran/
* gfortran.h (gfc_statement): Add ST_OACC_SERIAL_LOOP,
ST_OACC_END_SERIAL_LOOP, ST_OACC_SERIAL and ST_OACC_END_SERIAL
enumeration constants.
(gfc_exec_op): Add EXEC_OACC_SERIAL_LOOP and EXEC_OACC_SERIAL
enumeration constants.
* match.h (gfc_match_oacc_serial): New prototype.
(gfc_match_oacc_serial_loop): Likewise.
* dump-parse-tree.c (show_omp_node, show_code_node): Handle
EXEC_OACC_SERIAL_LOOP and EXEC_OACC_SERIAL.
* match.c (match_exit_cycle): Handle EXEC_OACC_SERIAL_LOOP.
* openmp.c (OACC_SERIAL_CLAUSES): New macro.
(OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK): Likewise.
(gfc_match_oacc_serial_loop): New function.
(gfc_match_oacc_serial): Likewise.
(oacc_is_loop): Handle EXEC_OACC_SERIAL_LOOP.
(resolve_omp_clauses): Handle EXEC_OACC_SERIAL.
(oacc_is_serial): New function.
(oacc_code_to_statement): Handle EXEC_OACC_SERIAL and
EXEC_OACC_SERIAL_LOOP.
(gfc_resolve_oacc_directive): Likewise.
* parse.c (decode_oacc_directive) <'s'>: Add case for "serial"
and "serial loop".
(next_statement): Handle ST_OACC_SERIAL_LOOP and ST_OACC_SERIAL.
(gfc_ascii_statement): Likewise.  Handle ST_OACC_END_SERIAL_LOOP
and ST_OACC_END_SERIAL.
(parse_oacc_structured_block): Handle ST_OACC_SERIAL.
(parse_oacc_loop): Handle ST_OACC_SERIAL_LOOP and
ST_OACC_END_SERIAL_LOOP.
(parse_executable): Handle ST_OACC_SERIAL_LOOP and
ST_OACC_SERIAL.
(is_oacc): Handle EXEC_OACC_SERIAL_LOOP and EXEC_OACC_SERIAL.
* resolve.c (gfc_resolve_blocks, gfc_resolve_code): Likewise.
* st.c (gfc_free_statement): Likewise.
* trans-openmp.c (gfc_trans_oacc_construct): Handle
EXEC_OACC_SERIAL.
(gfc_trans_oacc_combined_directive): Handle
EXEC_OACC_SERIAL_LOOP.
(gfc_trans_oacc_directive): Handle EXEC_OACC_SERIAL_LOOP and
EXEC_OACC_SERIAL.
* trans.c (trans_code): Likewise.

gcc/testsuite/
* c-c++-common/goacc/serial-dims.c: New test.

libgomp/
* testsuite/libgomp.oacc-c-c++-common/serial-dims.c: New test.

(cherry picked from openacc-gcc-9-branch commit
46e6f6b64f5e9e9996e7a66e3885747d85dab8b2)

33 files changed:
gcc/ChangeLog.omp
gcc/c-family/ChangeLog.omp
gcc/c-family/c-pragma.c
gcc/c-family/c-pragma.h
gcc/c/ChangeLog.omp
gcc/c/c-parser.c
gcc/cp/ChangeLog.omp
gcc/cp/constexpr.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/doc/generic.texi
gcc/fortran/ChangeLog.omp
gcc/fortran/dump-parse-tree.c
gcc/fortran/gfortran.h
gcc/fortran/match.c
gcc/fortran/match.h
gcc/fortran/openmp.c
gcc/fortran/parse.c
gcc/fortran/resolve.c
gcc/fortran/st.c
gcc/fortran/trans-openmp.c
gcc/fortran/trans.c
gcc/gimple-pretty-print.c
gcc/gimple.h
gcc/gimplify.c
gcc/omp-expand.c
gcc/omp-low.c
gcc/testsuite/ChangeLog.omp
gcc/testsuite/c-c++-common/goacc/serial-dims.c [new file with mode: 0644]
gcc/tree-pretty-print.c
gcc/tree.def
libgomp/ChangeLog.omp
libgomp/testsuite/libgomp.oacc-c-c++-common/serial-dims.c [new file with mode: 0644]

index e68675163ea90c6d0e80ff8385f6ebd541897928..43370cf90f6259ccd88054574419d0e3739f512b 100644 (file)
@@ -1,3 +1,41 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * gimple.h (gf_mask): Add GF_OMP_TARGET_KIND_OACC_SERIAL
+       enumeration constant.
+       (is_gimple_omp_oacc): Handle GF_OMP_TARGET_KIND_OACC_SERIAL.
+       (is_gimple_omp_offloaded): Likewise.
+       * gimplify.c (omp_region_type): Add ORT_ACC_SERIAL enumeration
+       constant.  Adjust the value of ORT_NONE accordingly.
+       (is_gimple_stmt): Handle OACC_SERIAL.
+       (oacc_default_clause): Handle ORT_ACC_SERIAL.
+       (gomp_needs_data_present): Likewise.
+       (gimplify_adjust_omp_clauses): Likewise.
+       (gimplify_omp_workshare): Handle OACC_SERIAL.
+       (gimplify_expr): Likewise.
+       * omp-expand.c (expand_omp_target): Handle
+       GF_OMP_TARGET_KIND_OACC_SERIAL.
+       (build_omp_regions_1, omp_make_gimple_edges): Likewise.
+       * omp-low.c (is_oacc_parallel): Rename function to...
+       (is_oacc_parallel_or_serial): ... this.  Handle
+       GF_OMP_TARGET_KIND_OACC_SERIAL.
+       (build_receiver_ref): Adjust accordingly.
+       (build_sender_ref): Likewise.
+       (scan_sharing_clauses): Likewise.
+       (create_omp_child_function): Likewise.
+       (scan_omp_for): Likewise.
+       (scan_omp_target): Likewise.
+       (lower_oacc_head_mark): Likewise.
+       (convert_from_firstprivate_int): Likewise.
+       (lower_omp_target): Likewise.
+       (check_omp_nesting_restrictions): Handle
+       GF_OMP_TARGET_KIND_OACC_SERIAL.
+       (lower_oacc_reductions): Likewise.
+       (lower_omp_target): Likewise.
+       * tree-pretty-print.c (dump_generic_node): Handle OACC_SERIAL.
+       * tree.def (OACC_SERIAL): New tree code.
+
+       * doc/generic.texi (OpenACC): Document OACC_SERIAL.
+
 2017-12-21  Cesar Philippidis  <cesar@codesourcery.com>
 
        * omp-low.c (install_parm_decl): Don't extract identifiers from
index 0f348b2219a8cd2cd71d2f4a62f5317e38db4573..f0ea8c5ce3f96376b24f01ede47c3cae13bf3fde 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * c-pragma.h (pragma_kind): Add PRAGMA_OACC_SERIAL enumeration
+       constant.
+       * c-pragma.c (oacc_pragmas): Add "serial" entry.
+
 2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
index fbc734a047bdc4216b6170e2394a65612b3c0077..c20a8aa9da185e88ac6b1893ce7627a28a5a006e 100644 (file)
@@ -1277,6 +1277,7 @@ static const struct omp_pragma_def oacc_pragmas[] = {
   { "loop", PRAGMA_OACC_LOOP },
   { "parallel", PRAGMA_OACC_PARALLEL },
   { "routine", PRAGMA_OACC_ROUTINE },
+  { "serial", PRAGMA_OACC_SERIAL },
   { "update", PRAGMA_OACC_UPDATE },
   { "wait", PRAGMA_OACC_WAIT }
 };
index 62bdaee80ebf7ce7b145ebf2ca4706eff3fd4432..d9a75fc80ca63dab10874005b573ca90fe954746 100644 (file)
@@ -38,6 +38,7 @@ enum pragma_kind {
   PRAGMA_OACC_LOOP,
   PRAGMA_OACC_PARALLEL,
   PRAGMA_OACC_ROUTINE,
+  PRAGMA_OACC_SERIAL,
   PRAGMA_OACC_UPDATE,
   PRAGMA_OACC_WAIT,
 
index e085e879f6731d069a9c3dec71291fcb599e4e7c..68a1d77c0105032313e51c9ea133862a0c848f02 100644 (file)
@@ -1,3 +1,11 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * c-parser.c (OACC_SERIAL_CLAUSE_MASK): New macro.
+       (OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK): Likewise.
+       (c_parser_oacc_kernels_parallel): Rename function to...
+       (c_parser_oacc_compute): ... this.  Handle PRAGMA_OACC_SERIAL.
+       (c_parser_omp_construct): Update accordingly.
+
 2018-12-21  Gergö Barany  <gergo@codesourcery.com>
 
        * c-parser.c (OACC_HOST_DATA_CLAUSE_MASK): Add PRAGMA_OACC_CLAUSE_IF
index d11216472d7bbc4bd72b37510427578f14574f13..2baddd0e4648b49550a717486c96fd0deea12778 100644 (file)
@@ -15692,6 +15692,11 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
    # pragma acc parallel oacc-parallel-clause[optseq] new-line
      structured-block
 
+   OpenACC 2.6:
+
+   # pragma acc serial oacc-serial-clause[optseq] new-line
+     structured-block
+
    LOC is the location of the #pragma token.
 */
 
@@ -15730,10 +15735,25 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)       \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
 
+#define OACC_SERIAL_CLAUSE_MASK                                        \
+       ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)               \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)              \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)                \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)              \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)              \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)        \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)           \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
+
 static tree
-c_parser_oacc_kernels_parallel (location_t loc, c_parser *parser,
-                               enum pragma_kind p_kind, char *p_name,
-                               bool *if_p)
+c_parser_oacc_compute (location_t loc, c_parser *parser,
+                      enum pragma_kind p_kind, char *p_name, bool *if_p)
 {
   omp_clause_mask mask;
   enum tree_code code;
@@ -15749,6 +15769,11 @@ c_parser_oacc_kernels_parallel (location_t loc, c_parser *parser,
       mask = OACC_PARALLEL_CLAUSE_MASK;
       code = OACC_PARALLEL;
       break;
+    case PRAGMA_OACC_SERIAL:
+      strcat (p_name, " serial");
+      mask = OACC_SERIAL_CLAUSE_MASK;
+      code = OACC_SERIAL;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -19549,9 +19574,9 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
       break;
     case PRAGMA_OACC_KERNELS:
     case PRAGMA_OACC_PARALLEL:
+    case PRAGMA_OACC_SERIAL:
       strcpy (p_name, "#pragma acc");
-      stmt = c_parser_oacc_kernels_parallel (loc, parser, p_kind, p_name,
-                                            if_p);
+      stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
       break;
     case PRAGMA_OACC_LOOP:
       strcpy (p_name, "#pragma acc");
index b2c7cfc20dbd2e9cddd5a7a19a6743455e4a6c18..10484632cca772b7f7a1821eb12769fafa1c279d 100644 (file)
@@ -1,3 +1,16 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * constexpr.c (potential_constant_expression_1): Handle
+       OACC_SERIAL.
+       * parser.c (OACC_SERIAL_CLAUSE_MASK): New macro.
+       (OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK): Likewise.
+       (cp_parser_oacc_kernels_parallel): Rename function to...
+       (cp_parser_oacc_compute): ... this.  Handle PRAGMA_OACC_SERIAL.
+       (cp_parser_omp_construct): Update accordingly.
+       (cp_parser_pragma): Handle PRAGMA_OACC_SERIAL.  Fix alphabetic
+       order.
+       * pt.c (tsubst_expr): Handle OACC_SERIAL.
+
 2018-12-21  Gergö Barany  <gergo@codesourcery.com>
 
        * parser.c (OACC_HOST_DATA_CLAUSE_MASK): Likewise.
index 9c13f0d5f320b7d8acca2a9199c3afa3c45efe4f..962936b957c933b49f00b4fb2f232f9bf54e0285 100644 (file)
@@ -6369,6 +6369,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
     case OMP_DEPOBJ:
     case OACC_PARALLEL:
     case OACC_KERNELS:
+    case OACC_SERIAL:
     case OACC_DATA:
     case OACC_HOST_DATA:
     case OACC_LOOP:
index 3c42f43742ed1d9c456e0f7acacc0eea8c5381d9..bd278ee0cbd9460faf772567341d4699d153c7cf 100644 (file)
@@ -39053,6 +39053,10 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
 
    # pragma acc parallel oacc-parallel-clause[optseq] new-line
      structured-block
+
+   OpenACC 2.6:
+
+   # pragma acc serial oacc-serial-clause[optseq] new-line
 */
 
 #define OACC_KERNELS_CLAUSE_MASK                                       \
@@ -39090,9 +39094,29 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)       \
        | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
 
+#define OACC_SERIAL_CLAUSE_MASK                                                \
+       ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)               \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)              \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)                \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)              \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)              \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)           \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)        \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)             \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)           \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
+
+#define OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK                            \
+       ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)               \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
+
 static tree
-cp_parser_oacc_kernels_parallel (cp_parser *parser, cp_token *pragma_tok,
-                                char *p_name, bool *if_p)
+cp_parser_oacc_compute (cp_parser *parser, cp_token *pragma_tok,
+                       char *p_name, bool *if_p)
 {
   omp_clause_mask mask;
   enum tree_code code;
@@ -39108,6 +39132,11 @@ cp_parser_oacc_kernels_parallel (cp_parser *parser, cp_token *pragma_tok,
       mask = OACC_PARALLEL_CLAUSE_MASK;
       code = OACC_PARALLEL;
       break;
+    case PRAGMA_OACC_SERIAL:
+      strcat (p_name, " serial");
+      mask = OACC_SERIAL_CLAUSE_MASK;
+      code = OACC_SERIAL;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -40407,9 +40436,9 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
       break;
     case PRAGMA_OACC_KERNELS:
     case PRAGMA_OACC_PARALLEL:
+    case PRAGMA_OACC_SERIAL:
       strcpy (p_name, "#pragma acc");
-      stmt = cp_parser_oacc_kernels_parallel (parser, pragma_tok, p_name,
-                                             if_p);
+      stmt = cp_parser_oacc_compute (parser, pragma_tok, p_name, if_p);
       break;
     case PRAGMA_OACC_LOOP:
       strcpy (p_name, "#pragma acc");
@@ -41061,8 +41090,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
     case PRAGMA_OACC_DATA:
     case PRAGMA_OACC_HOST_DATA:
     case PRAGMA_OACC_KERNELS:
-    case PRAGMA_OACC_PARALLEL:
     case PRAGMA_OACC_LOOP:
+    case PRAGMA_OACC_PARALLEL:
+    case PRAGMA_OACC_SERIAL:
     case PRAGMA_OMP_ATOMIC:
     case PRAGMA_OMP_CRITICAL:
     case PRAGMA_OMP_DISTRIBUTE:
index 85f54ee15d96fae8f6b514e6011fd32ba183293d..052e5233f54e364cb50d8bee689d970e0108e891 100644 (file)
@@ -17501,6 +17501,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 
     case OACC_KERNELS:
     case OACC_PARALLEL:
+    case OACC_SERIAL:
       tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_ACC, args, complain,
                                in_decl);
       stmt = begin_omp_parallel ();
index 15f6cfec21bbe9438f735dbddb902bc28a3ac41d..e9804d8829facbb9275955df576d691d54cd23cc 100644 (file)
@@ -2384,6 +2384,7 @@ compilation.
 @tindex OACC_KERNELS
 @tindex OACC_LOOP
 @tindex OACC_PARALLEL
+@tindex OACC_SERIAL
 @tindex OACC_UPDATE
 
 All the statements starting with @code{OACC_} represent directives and
@@ -2428,6 +2429,10 @@ See the description of the @code{OMP_FOR} code.
 
 Represents @code{#pragma acc parallel [clause1 @dots{} clauseN]}.
 
+@item OACC_SERIAL
+
+Represents @code{#pragma acc serial [clause1 @dots{} clauseN]}.
+
 @item OACC_UPDATE
 
 Represents @code{#pragma acc update [clause1 @dots{} clauseN]}.
index 3bf4f43730d4117e144beb05e844389cff89f8e4..9e83b6228792f9b646be15eeeb9d11abcb20cf90 100644 (file)
@@ -1,3 +1,46 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * gfortran.h (gfc_statement): Add ST_OACC_SERIAL_LOOP,
+       ST_OACC_END_SERIAL_LOOP, ST_OACC_SERIAL and ST_OACC_END_SERIAL
+       enumeration constants.
+       (gfc_exec_op): Add EXEC_OACC_SERIAL_LOOP and EXEC_OACC_SERIAL
+       enumeration constants.
+       * match.h (gfc_match_oacc_serial): New prototype.
+       (gfc_match_oacc_serial_loop): Likewise.
+       * dump-parse-tree.c (show_omp_node, show_code_node): Handle
+       EXEC_OACC_SERIAL_LOOP and EXEC_OACC_SERIAL.
+       * match.c (match_exit_cycle): Handle EXEC_OACC_SERIAL_LOOP.
+       * openmp.c (OACC_SERIAL_CLAUSES): New macro.
+       (OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK): Likewise.
+       (gfc_match_oacc_serial_loop): New function.
+       (gfc_match_oacc_serial): Likewise.
+       (oacc_is_loop): Handle EXEC_OACC_SERIAL_LOOP.
+       (resolve_omp_clauses): Handle EXEC_OACC_SERIAL.
+       (oacc_is_serial): New function.
+       (oacc_code_to_statement): Handle EXEC_OACC_SERIAL and
+       EXEC_OACC_SERIAL_LOOP.
+       (gfc_resolve_oacc_directive): Likewise.
+       * parse.c (decode_oacc_directive) <'s'>: Add case for "serial"
+       and "serial loop".
+       (next_statement): Handle ST_OACC_SERIAL_LOOP and ST_OACC_SERIAL.
+       (gfc_ascii_statement): Likewise.  Handle ST_OACC_END_SERIAL_LOOP
+       and ST_OACC_END_SERIAL.
+       (parse_oacc_structured_block): Handle ST_OACC_SERIAL.
+       (parse_oacc_loop): Handle ST_OACC_SERIAL_LOOP and
+       ST_OACC_END_SERIAL_LOOP.
+       (parse_executable): Handle ST_OACC_SERIAL_LOOP and
+       ST_OACC_SERIAL.
+       (is_oacc): Handle EXEC_OACC_SERIAL_LOOP and EXEC_OACC_SERIAL.
+       * resolve.c (gfc_resolve_blocks, gfc_resolve_code): Likewise.
+       * st.c (gfc_free_statement): Likewise.
+       * trans-openmp.c (gfc_trans_oacc_construct): Handle
+       EXEC_OACC_SERIAL.
+       (gfc_trans_oacc_combined_directive): Handle
+       EXEC_OACC_SERIAL_LOOP.
+       (gfc_trans_oacc_directive): Handle EXEC_OACC_SERIAL_LOOP and
+       EXEC_OACC_SERIAL.
+       * trans.c (trans_code): Likewise.
+
 2017-12-21  Cesar Philippidis  <cesar@codesourcery.com>
 
        * types.def: (BF_FN_VOID_INT_INT_OMPFN_SIZE_PTR_PTR_PTR_VAR):
index 7a74c317fd580ff576cca91d5cb967e0307b308d..afa7c36b89e2925dcd33f5c9276f38daa0aa7dbd 100644 (file)
@@ -1617,6 +1617,8 @@ show_omp_node (int level, gfc_code *c)
     case EXEC_OACC_PARALLEL: name = "PARALLEL"; is_oacc = true; break;
     case EXEC_OACC_KERNELS_LOOP: name = "KERNELS LOOP"; is_oacc = true; break;
     case EXEC_OACC_KERNELS: name = "KERNELS"; is_oacc = true; break;
+    case EXEC_OACC_SERIAL_LOOP: name = "SERIAL LOOP"; is_oacc = true; break;
+    case EXEC_OACC_SERIAL: name = "SERIAL"; is_oacc = true; break;
     case EXEC_OACC_DATA: name = "DATA"; is_oacc = true; break;
     case EXEC_OACC_HOST_DATA: name = "HOST_DATA"; is_oacc = true; break;
     case EXEC_OACC_LOOP: name = "LOOP"; is_oacc = true; break;
@@ -1692,6 +1694,8 @@ show_omp_node (int level, gfc_code *c)
     case EXEC_OACC_PARALLEL:
     case EXEC_OACC_KERNELS_LOOP:
     case EXEC_OACC_KERNELS:
+    case EXEC_OACC_SERIAL_LOOP:
+    case EXEC_OACC_SERIAL:
     case EXEC_OACC_DATA:
     case EXEC_OACC_HOST_DATA:
     case EXEC_OACC_LOOP:
@@ -2877,6 +2881,8 @@ show_code_node (int level, gfc_code *c)
     case EXEC_OACC_PARALLEL:
     case EXEC_OACC_KERNELS_LOOP:
     case EXEC_OACC_KERNELS:
+    case EXEC_OACC_SERIAL_LOOP:
+    case EXEC_OACC_SERIAL:
     case EXEC_OACC_DATA:
     case EXEC_OACC_HOST_DATA:
     case EXEC_OACC_LOOP:
index 8bf221b69829434c9c64b0ac36c1c926be7c12b4..b47b98133d5a7295c9841bf1dcbb89d636b4ef68 100644 (file)
@@ -223,7 +223,8 @@ enum gfc_statement
   ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP,
   ST_OACC_END_LOOP, ST_OACC_DECLARE, ST_OACC_UPDATE, ST_OACC_WAIT,
   ST_OACC_CACHE, ST_OACC_KERNELS_LOOP, ST_OACC_END_KERNELS_LOOP,
-  ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA, ST_OACC_ROUTINE,
+  ST_OACC_SERIAL_LOOP, ST_OACC_END_SERIAL_LOOP, ST_OACC_SERIAL,
+  ST_OACC_END_SERIAL, ST_OACC_ENTER_DATA, ST_OACC_EXIT_DATA, ST_OACC_ROUTINE,
   ST_OACC_ATOMIC, ST_OACC_END_ATOMIC,
   ST_OMP_ATOMIC, ST_OMP_BARRIER, ST_OMP_CRITICAL, ST_OMP_END_ATOMIC,
   ST_OMP_END_CRITICAL, ST_OMP_END_DO, ST_OMP_END_MASTER, ST_OMP_END_ORDERED,
@@ -2549,11 +2550,11 @@ enum gfc_exec_op
   EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH,
   EXEC_FORM_TEAM, EXEC_CHANGE_TEAM, EXEC_END_TEAM, EXEC_SYNC_TEAM,
   EXEC_LOCK, EXEC_UNLOCK, EXEC_EVENT_POST, EXEC_EVENT_WAIT, EXEC_FAIL_IMAGE,
-  EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_ROUTINE,
-  EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA,
-  EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE,
-  EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA, EXEC_OACC_ATOMIC,
-  EXEC_OACC_DECLARE,
+  EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_SERIAL_LOOP,
+  EXEC_OACC_ROUTINE, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_SERIAL,
+  EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE,
+  EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA,
+  EXEC_OACC_ATOMIC, EXEC_OACC_DECLARE,
   EXEC_OMP_CRITICAL, EXEC_OMP_DO, EXEC_OMP_FLUSH, EXEC_OMP_MASTER,
   EXEC_OMP_ORDERED, EXEC_OMP_PARALLEL, EXEC_OMP_PARALLEL_DO,
   EXEC_OMP_PARALLEL_SECTIONS, EXEC_OMP_PARALLEL_WORKSHARE,
index eba428fd084171686cf2ab346a3dfdcf28f55aa1..7a497b878e9a3a4d41c9b70c8ccdf9e6496ab897 100644 (file)
@@ -2837,7 +2837,8 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op)
       && o != NULL
       && o->state == COMP_OMP_STRUCTURED_BLOCK
       && (o->head->op == EXEC_OACC_LOOP
-         || o->head->op == EXEC_OACC_PARALLEL_LOOP))
+         || o->head->op == EXEC_OACC_PARALLEL_LOOP
+         || o->head->op == EXEC_OACC_SERIAL_LOOP))
     {
       int collapse = 1;
       gcc_assert (o->head->next != NULL
index ac47d992f4a79ab2eebd4d1fa4f93d9cdefb0147..3a5b866f12028ca2678f05dae8433d0e80081bcb 100644 (file)
@@ -145,6 +145,8 @@ match gfc_match_oacc_kernels_loop (void);
 match gfc_match_oacc_parallel (void);
 match gfc_match_oacc_parallel_loop (void);
 match gfc_match_oacc_enter_data (void);
+match gfc_match_oacc_serial (void);
+match gfc_match_oacc_serial_loop (void);
 match gfc_match_oacc_exit_data (void);
 match gfc_match_oacc_routine (void);
 
index 2a6dce7d65f841844922be1317a997e3b6da3b5a..82ac0fa8523a89f1354c94e09d2d71af8f7a4f14 100644 (file)
@@ -1988,6 +1988,15 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
    | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT                \
    | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT | OMP_CLAUSE_DEFAULT             \
    | OMP_CLAUSE_WAIT | OMP_CLAUSE_ATTACH)
+#define OACC_SERIAL_CLAUSES \
+  (omp_mask (OMP_CLAUSE_ASYNC) | OMP_CLAUSE_WAIT                             \
+   | OMP_CLAUSE_IF                                                           \
+   | OMP_CLAUSE_REDUCTION                                                    \
+   | OMP_CLAUSE_COPY | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT                \
+   | OMP_CLAUSE_CREATE | OMP_CLAUSE_PRESENT                                  \
+   | OMP_CLAUSE_DEVICEPTR                                                    \
+   | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_FIRSTPRIVATE                            \
+   | OMP_CLAUSE_DEFAULT | OMP_CLAUSE_ATTACH)
 #define OACC_DATA_CLAUSES \
   (omp_mask (OMP_CLAUSE_IF) | OMP_CLAUSE_DEVICEPTR  | OMP_CLAUSE_COPY        \
    | OMP_CLAUSE_COPYIN | OMP_CLAUSE_COPYOUT | OMP_CLAUSE_CREATE                      \
@@ -2027,6 +2036,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
    | OMP_CLAUSE_SEQ                                                          \
    | OMP_CLAUSE_NOHOST)
 
+#define OACC_SERIAL_CLAUSE_DEVICE_TYPE_MASK \
+  (omp_mask (OMP_CLAUSE_ASYNC) | OMP_CLAUSE_WAIT                             \
+   | OMP_CLAUSE_DEVICE_TYPE)
+
 
 static match
 match_acc (gfc_exec_op op, const omp_mask mask)
@@ -2067,6 +2080,21 @@ gfc_match_oacc_kernels (void)
 }
 
 
+match
+gfc_match_oacc_serial_loop (void)
+{
+  return match_acc (EXEC_OACC_SERIAL_LOOP,
+                   OACC_SERIAL_CLAUSES | OACC_LOOP_CLAUSES);
+}
+
+
+match
+gfc_match_oacc_serial (void)
+{
+  return match_acc (EXEC_OACC_SERIAL, OACC_SERIAL_CLAUSES);
+}
+
+
 match
 gfc_match_oacc_data (void)
 {
@@ -3814,6 +3842,7 @@ oacc_is_loop (gfc_code *code)
 {
   return code->op == EXEC_OACC_PARALLEL_LOOP
         || code->op == EXEC_OACC_KERNELS_LOOP
+        || code->op == EXEC_OACC_SERIAL_LOOP
         || code->op == EXEC_OACC_LOOP;
 }
 
@@ -4655,7 +4684,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
                                 n->sym->name, name, &n->where);
                  }
                if (code
-                   && (oacc_is_loop (code) || code->op == EXEC_OACC_PARALLEL))
+                   && (oacc_is_loop (code)
+                       || code->op == EXEC_OACC_PARALLEL
+                       || code->op == EXEC_OACC_SERIAL))
                  check_array_not_assumed (n->sym, n->where, name);
                else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
                  gfc_error ("Assumed size array %qs in %s clause at %L",
@@ -5806,6 +5837,12 @@ oacc_is_parallel (gfc_code *code)
   return code->op == EXEC_OACC_PARALLEL || code->op == EXEC_OACC_PARALLEL_LOOP;
 }
 
+static bool
+oacc_is_serial (gfc_code *code)
+{
+  return code->op == EXEC_OACC_SERIAL || code->op == EXEC_OACC_SERIAL_LOOP;
+}
+
 static gfc_statement
 omp_code_to_statement (gfc_code *code)
 {
@@ -5847,6 +5884,8 @@ oacc_code_to_statement (gfc_code *code)
       return ST_OACC_PARALLEL;
     case EXEC_OACC_KERNELS:
       return ST_OACC_KERNELS;
+    case EXEC_OACC_SERIAL:
+      return ST_OACC_SERIAL;
     case EXEC_OACC_DATA:
       return ST_OACC_DATA;
     case EXEC_OACC_HOST_DATA:
@@ -5855,6 +5894,8 @@ oacc_code_to_statement (gfc_code *code)
       return ST_OACC_PARALLEL_LOOP;
     case EXEC_OACC_KERNELS_LOOP:
       return ST_OACC_KERNELS_LOOP;
+    case EXEC_OACC_SERIAL_LOOP:
+      return ST_OACC_SERIAL_LOOP;
     case EXEC_OACC_LOOP:
       return ST_OACC_LOOP;
     case EXEC_OACC_ATOMIC:
@@ -6208,6 +6249,7 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
     {
     case EXEC_OACC_PARALLEL:
     case EXEC_OACC_KERNELS:
+    case EXEC_OACC_SERIAL:
     case EXEC_OACC_DATA:
     case EXEC_OACC_HOST_DATA:
     case EXEC_OACC_UPDATE:
@@ -6219,6 +6261,7 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
       break;
     case EXEC_OACC_PARALLEL_LOOP:
     case EXEC_OACC_KERNELS_LOOP:
+    case EXEC_OACC_SERIAL_LOOP:
     case EXEC_OACC_LOOP:
       resolve_oacc_loop (code);
       break;
index 14cda5f9fba42e606eddf9654daf7daed682a272..2f1c2c8517bcff348501430e62991b1927d0a952 100644 (file)
@@ -698,6 +698,10 @@ decode_oacc_directive (void)
     case 'r':
       match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
       break;
+    case 's':
+      matcha ("serial loop", gfc_match_oacc_serial_loop, ST_OACC_SERIAL_LOOP);
+      matcha ("serial", gfc_match_oacc_serial, ST_OACC_SERIAL);
+      break;
     case 'u':
       matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
       break;
@@ -1552,7 +1556,8 @@ next_statement (void)
   case ST_CRITICAL: \
   case ST_OACC_PARALLEL_LOOP: case ST_OACC_PARALLEL: case ST_OACC_KERNELS: \
   case ST_OACC_DATA: case ST_OACC_HOST_DATA: case ST_OACC_LOOP: \
-  case ST_OACC_KERNELS_LOOP: case ST_OACC_ATOMIC
+  case ST_OACC_KERNELS_LOOP: case ST_OACC_SERIAL_LOOP: case ST_OACC_SERIAL: \
+  case ST_OACC_ATOMIC
 
 /* Declaration statements */
 
@@ -2120,6 +2125,18 @@ gfc_ascii_statement (gfc_statement st)
     case ST_OACC_END_KERNELS_LOOP:
       p = "!$ACC END KERNELS LOOP";
       break;
+    case ST_OACC_SERIAL_LOOP:
+      p = "!$ACC SERIAL LOOP";
+      break;
+    case ST_OACC_END_SERIAL_LOOP:
+      p = "!$ACC END SERIAL LOOP";
+      break;
+    case ST_OACC_SERIAL:
+      p = "!$ACC SERIAL";
+      break;
+    case ST_OACC_END_SERIAL:
+      p = "!$ACC END SERIAL";
+      break;
     case ST_OACC_DATA:
       p = "!$ACC DATA";
       break;
@@ -4938,6 +4955,9 @@ parse_oacc_structured_block (gfc_statement acc_st)
     case ST_OACC_KERNELS:
       acc_end_st = ST_OACC_END_KERNELS;
       break;
+    case ST_OACC_SERIAL:
+      acc_end_st = ST_OACC_END_SERIAL;
+      break;
     case ST_OACC_DATA:
       acc_end_st = ST_OACC_END_DATA;
       break;
@@ -5022,6 +5042,7 @@ parse_oacc_loop (gfc_statement acc_st)
     gfc_warning (0, "Redundant !$ACC END LOOP at %C");
   if ((acc_st == ST_OACC_PARALLEL_LOOP && st == ST_OACC_END_PARALLEL_LOOP) ||
       (acc_st == ST_OACC_KERNELS_LOOP && st == ST_OACC_END_KERNELS_LOOP) ||
+      (acc_st == ST_OACC_SERIAL_LOOP && st == ST_OACC_END_SERIAL_LOOP) ||
       (acc_st == ST_OACC_LOOP && st == ST_OACC_END_LOOP))
     {
       gcc_assert (new_st.op == EXEC_NOP);
@@ -5357,6 +5378,7 @@ parse_executable (gfc_statement st)
 
        case ST_OACC_PARALLEL_LOOP:
        case ST_OACC_KERNELS_LOOP:
+       case ST_OACC_SERIAL_LOOP:
        case ST_OACC_LOOP:
          st = parse_oacc_loop (st);
          if (st == ST_IMPLIED_ENDDO)
@@ -5365,6 +5387,7 @@ parse_executable (gfc_statement st)
 
        case ST_OACC_PARALLEL:
        case ST_OACC_KERNELS:
+       case ST_OACC_SERIAL:
        case ST_OACC_DATA:
        case ST_OACC_HOST_DATA:
          parse_oacc_structured_block (st);
@@ -6359,6 +6382,8 @@ is_oacc (gfc_state_data *sd)
     case EXEC_OACC_PARALLEL:
     case EXEC_OACC_KERNELS_LOOP:
     case EXEC_OACC_KERNELS:
+    case EXEC_OACC_SERIAL_LOOP:
+    case EXEC_OACC_SERIAL:
     case EXEC_OACC_DATA:
     case EXEC_OACC_HOST_DATA:
     case EXEC_OACC_LOOP:
index 8232deb81704b8cea92e1a6064870b7cbc801046..9b4b0bdd00635a8c39f9fe5375957ca326dece01 100644 (file)
@@ -10332,6 +10332,8 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
        case EXEC_OACC_PARALLEL:
        case EXEC_OACC_KERNELS_LOOP:
        case EXEC_OACC_KERNELS:
+       case EXEC_OACC_SERIAL_LOOP:
+       case EXEC_OACC_SERIAL:
        case EXEC_OACC_DATA:
        case EXEC_OACC_HOST_DATA:
        case EXEC_OACC_LOOP:
@@ -11292,6 +11294,8 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns)
            case EXEC_OACC_PARALLEL:
            case EXEC_OACC_KERNELS_LOOP:
            case EXEC_OACC_KERNELS:
+           case EXEC_OACC_SERIAL_LOOP:
+           case EXEC_OACC_SERIAL:
            case EXEC_OACC_DATA:
            case EXEC_OACC_HOST_DATA:
            case EXEC_OACC_LOOP:
@@ -11701,6 +11705,8 @@ start:
        case EXEC_OACC_PARALLEL:
        case EXEC_OACC_KERNELS_LOOP:
        case EXEC_OACC_KERNELS:
+       case EXEC_OACC_SERIAL_LOOP:
+       case EXEC_OACC_SERIAL:
        case EXEC_OACC_DATA:
        case EXEC_OACC_HOST_DATA:
        case EXEC_OACC_LOOP:
index ade2fce06a5696cd0f044592bd7bd7d486862add..69641e39e32e969badce55e6318bd359bb865461 100644 (file)
@@ -201,6 +201,8 @@ gfc_free_statement (gfc_code *p)
     case EXEC_OACC_PARALLEL:
     case EXEC_OACC_KERNELS_LOOP:
     case EXEC_OACC_KERNELS:
+    case EXEC_OACC_SERIAL_LOOP:
+    case EXEC_OACC_SERIAL:
     case EXEC_OACC_DATA:
     case EXEC_OACC_HOST_DATA:
     case EXEC_OACC_LOOP:
index 264d65f062e477b84cf0a36b1df1dc604c0cd6ab..ed132ac7fa6d8d43cbb825d9cd89720215f43050 100644 (file)
@@ -3264,7 +3264,7 @@ gfc_trans_omp_code (gfc_code *code, bool force_empty)
 }
 
 /* Trans OpenACC directives. */
-/* parallel, kernels, data and host_data. */
+/* parallel, serial, kernels, data and host_data. */
 static tree
 gfc_trans_oacc_construct (gfc_code *code)
 {
@@ -3280,6 +3280,9 @@ gfc_trans_oacc_construct (gfc_code *code)
       case EXEC_OACC_KERNELS:
        construct_code = OACC_KERNELS;
        break;
+      case EXEC_OACC_SERIAL:
+       construct_code = OACC_SERIAL;
+       break;
       case EXEC_OACC_DATA:
        construct_code = OACC_DATA;
        break;
@@ -4088,7 +4091,8 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
   return gfc_finish_block (&block);
 }
 
-/* parallel loop and kernels loop. */
+/* Combined OpenACC parallel loop, kernels loop and serial loop. */
+
 static tree
 gfc_trans_oacc_combined_directive (gfc_code *code)
 {
@@ -4106,6 +4110,9 @@ gfc_trans_oacc_combined_directive (gfc_code *code)
       case EXEC_OACC_KERNELS_LOOP:
        construct_code = OACC_KERNELS;
        break;
+      case EXEC_OACC_SERIAL_LOOP:
+       construct_code = OACC_SERIAL;
+       break;
       default:
        gcc_unreachable ();
     }
@@ -5373,9 +5380,11 @@ gfc_trans_oacc_directive (gfc_code *code)
     {
     case EXEC_OACC_PARALLEL_LOOP:
     case EXEC_OACC_KERNELS_LOOP:
+    case EXEC_OACC_SERIAL_LOOP:
       return gfc_trans_oacc_combined_directive (code);
     case EXEC_OACC_PARALLEL:
     case EXEC_OACC_KERNELS:
+    case EXEC_OACC_SERIAL:
     case EXEC_OACC_DATA:
     case EXEC_OACC_HOST_DATA:
       return gfc_trans_oacc_construct (code);
index 022ceb9e197a1250edb0d7f36a8196ba859fcdec..497290be241761680114ccc1ebeef02928f07c02 100644 (file)
@@ -2106,6 +2106,8 @@ trans_code (gfc_code * code, tree cond)
        case EXEC_OACC_KERNELS_LOOP:
        case EXEC_OACC_PARALLEL:
        case EXEC_OACC_PARALLEL_LOOP:
+       case EXEC_OACC_SERIAL:
+       case EXEC_OACC_SERIAL_LOOP:
        case EXEC_OACC_ENTER_DATA:
        case EXEC_OACC_EXIT_DATA:
        case EXEC_OACC_ATOMIC:
index 69bae0d10d02befb46a072824b7081fffd2751c2..bae6d25ebb5e9c0f4eeccdb5f10414b0f1983feb 100644 (file)
@@ -1614,6 +1614,9 @@ dump_gimple_omp_target (pretty_printer *buffer, gomp_target *gs,
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
       kind = " oacc_parallel";
       break;
+    case GF_OMP_TARGET_KIND_OACC_SERIAL:
+      kind = " oacc_serial";
+      break;
     case GF_OMP_TARGET_KIND_OACC_DATA:
       kind = " oacc_data";
       break;
index 8b5c9e2190a456278fd18245e4f0790f5cfe4c57..5c3defd96fedc7106163442c3bb6f46518fedcc1 100644 (file)
@@ -184,6 +184,7 @@ enum gf_mask {
     GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 9,
     GF_OMP_TARGET_KIND_OACC_DECLARE = 10,
     GF_OMP_TARGET_KIND_OACC_HOST_DATA = 11,
+    GF_OMP_TARGET_KIND_OACC_SERIAL = 12,
     GF_OMP_TEAMS_GRID_PHONY    = 1 << 0,
     GF_OMP_TEAMS_HOST          = 1 << 1,
 
@@ -6419,6 +6420,7 @@ is_gimple_omp_oacc (const gimple *stmt)
        {
        case GF_OMP_TARGET_KIND_OACC_PARALLEL:
        case GF_OMP_TARGET_KIND_OACC_KERNELS:
+       case GF_OMP_TARGET_KIND_OACC_SERIAL:
        case GF_OMP_TARGET_KIND_OACC_DATA:
        case GF_OMP_TARGET_KIND_OACC_UPDATE:
        case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
@@ -6448,6 +6450,7 @@ is_gimple_omp_offloaded (const gimple *stmt)
        case GF_OMP_TARGET_KIND_REGION:
        case GF_OMP_TARGET_KIND_OACC_PARALLEL:
        case GF_OMP_TARGET_KIND_OACC_KERNELS:
+       case GF_OMP_TARGET_KIND_OACC_SERIAL:
          return true;
        default:
          return false;
index e253c2b0c27010a945a049f288e88973bcaadf58..f7cfa0eb4e1e399e901d7f2951b988dff1656f84 100644 (file)
@@ -157,6 +157,7 @@ enum omp_region_type
   ORT_ACC_DATA = ORT_ACC | ORT_TARGET_DATA, /* Data construct.  */
   ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET,  /* Parallel construct */
   ORT_ACC_KERNELS  = ORT_ACC | ORT_TARGET | 2,  /* Kernels construct.  */
+  ORT_ACC_SERIAL = ORT_ACC | ORT_TARGET | 4,  /* Serial construct.  */
   ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2,  /* Host data.  */
 
   /* Dummy OpenMP region, used to disable expansion of
@@ -5492,6 +5493,7 @@ is_gimple_stmt (tree t)
     case STATEMENT_LIST:
     case OACC_PARALLEL:
     case OACC_KERNELS:
+    case OACC_SERIAL:
     case OACC_DATA:
     case OACC_HOST_DATA:
     case OACC_DECLARE:
@@ -7201,7 +7203,8 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
       break;
 
     case ORT_ACC_PARALLEL:
-      rkind = "parallel";
+    case ORT_ACC_SERIAL:
+      rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
 
       if (is_private)
        flags |= GOVD_FIRSTPRIVATE;
@@ -9693,7 +9696,8 @@ gomp_oacc_needs_data_present (tree decl)
   gimplify_omp_ctx *ctx = NULL;
 
   if (gimplify_omp_ctxp->region_type != ORT_ACC_PARALLEL
-      && gimplify_omp_ctxp->region_type != ORT_ACC_KERNELS)
+      && gimplify_omp_ctxp->region_type != ORT_ACC_KERNELS
+      && gimplify_omp_ctxp->region_type != ORT_ACC_SERIAL)
     return NULL;
 
   if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
@@ -10168,7 +10172,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
          /* Data clauses associated with acc parallel reductions must be
             compatible with present_or_copy.  Warn and adjust the clause
             if that is not the case.  */
-         if (ctx->region_type == ORT_ACC_PARALLEL)
+         if (ctx->region_type == ORT_ACC_PARALLEL
+             || ctx->region_type == ORT_ACC_SERIAL)
            {
              tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
              n = NULL;
@@ -10330,7 +10335,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
          /* OpenACC reductions need a present_or_copy data clause.
             Add one if necessary.  Emit error when the reduction is
             private.  */
-         if (DECL_P (decl) && ctx->region_type == ORT_ACC_PARALLEL)
+         if (DECL_P (decl) && ctx->region_type == ORT_ACC_PARALLEL
+             || ctx->region_type == ORT_ACC_SERIAL)
            {
              n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
              if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
@@ -12019,6 +12025,9 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
     case OACC_PARALLEL:
       ort = ORT_ACC_PARALLEL;
       break;
+    case OACC_SERIAL:
+      ort = ORT_ACC_SERIAL;
+      break;
     case OACC_DATA:
       ort = ORT_ACC_DATA;
       break;
@@ -12100,6 +12109,10 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
                                      OMP_CLAUSES (expr));
       break;
+    case OACC_SERIAL:
+      stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
+                                     OMP_CLAUSES (expr));
+      break;
     case OMP_SECTIONS:
       stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
       break;
@@ -13329,6 +13342,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        case OACC_DATA:
        case OACC_KERNELS:
        case OACC_PARALLEL:
+       case OACC_SERIAL:
        case OMP_SECTIONS:
        case OMP_SINGLE:
        case OMP_TARGET:
@@ -13728,6 +13742,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
                  && code != TRY_FINALLY_EXPR
                  && code != OACC_PARALLEL
                  && code != OACC_KERNELS
+                 && code != OACC_SERIAL
                  && code != OACC_DATA
                  && code != OACC_HOST_DATA
                  && code != OACC_DECLARE
index c16db789d9f6557229988cca92d75bc6ad0293db..e30d8e78aaee44d475be422a6fb83c22111de717 100644 (file)
@@ -7316,6 +7316,7 @@ expand_omp_target (struct omp_region *region)
   switch (gimple_omp_target_kind (entry_stmt))
     {
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
+    case GF_OMP_TARGET_KIND_OACC_SERIAL:
       oacc_parallel = true;
       gcc_fallthrough ();
     case GF_OMP_TARGET_KIND_REGION:
@@ -7353,16 +7354,28 @@ expand_omp_target (struct omp_region *region)
   entry_bb = region->entry;
   exit_bb = region->exit;
 
-  if (gimple_omp_target_kind (entry_stmt) == GF_OMP_TARGET_KIND_OACC_KERNELS)
+  switch (gimple_omp_target_kind (entry_stmt))
     {
+    case GF_OMP_TARGET_KIND_OACC_KERNELS:
       mark_loops_in_oacc_kernels_region (region->entry, region->exit);
 
-      /* Further down, both OpenACC kernels and OpenACC parallel constructs
-        will be mappted to BUILT_IN_GOACC_PARALLEL, and to distinguish the
-        two, there is an "oacc kernels" attribute set for OpenACC kernels.  */
+      /* Further down, all OpenACC compute constructs will be mapped to
+        BUILT_IN_GOACC_PARALLEL, and to distinguish between them, there
+        is an "oacc kernels" attribute set for OpenACC kernels.  */
       DECL_ATTRIBUTES (child_fn)
        = tree_cons (get_identifier ("oacc kernels"),
                     NULL_TREE, DECL_ATTRIBUTES (child_fn));
+      break;
+    case GF_OMP_TARGET_KIND_OACC_SERIAL:
+      /* Further down, all OpenACC compute constructs will be mapped to
+        BUILT_IN_GOACC_PARALLEL, and to distinguish between them, there
+        is an "oacc serial" attribute set for OpenACC serial.  */
+      DECL_ATTRIBUTES (child_fn)
+       = tree_cons (get_identifier ("oacc serial"),
+                    NULL_TREE, DECL_ATTRIBUTES (child_fn));
+      break;
+    default:
+      break;
     }
 
   if (offloaded)
@@ -7567,6 +7580,7 @@ expand_omp_target (struct omp_region *region)
       break;
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
+    case GF_OMP_TARGET_KIND_OACC_SERIAL:
       start_ix = BUILT_IN_GOACC_PARALLEL;
       break;
     case GF_OMP_TARGET_KIND_OACC_DATA:
@@ -7776,7 +7790,18 @@ expand_omp_target (struct omp_region *region)
        args.quick_push (get_target_arguments (&gsi, entry_stmt));
       break;
     case BUILT_IN_GOACC_PARALLEL:
-      oacc_set_fn_attrib (child_fn, clauses, &args);
+      if (lookup_attribute ("oacc serial", DECL_ATTRIBUTES (child_fn)) != NULL)
+       {
+         tree dims = NULL_TREE;
+         unsigned int ix;
+
+         /* For serial constructs we set all dimensions to 1.  */
+         for (ix = GOMP_DIM_MAX; ix--;)
+           dims = tree_cons (NULL_TREE, integer_one_node, dims);
+         oacc_replace_fn_attrib (child_fn, dims);
+       }
+      else
+       oacc_set_fn_attrib (child_fn, clauses, &args);
       tagging = true;
       /* FALLTHRU */
     case BUILT_IN_GOACC_ENTER_EXIT_DATA:
@@ -8349,6 +8374,7 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
                case GF_OMP_TARGET_KIND_DATA:
                case GF_OMP_TARGET_KIND_OACC_PARALLEL:
                case GF_OMP_TARGET_KIND_OACC_KERNELS:
+               case GF_OMP_TARGET_KIND_OACC_SERIAL:
                case GF_OMP_TARGET_KIND_OACC_DATA:
                case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
                  break;
@@ -8603,6 +8629,7 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region,
        case GF_OMP_TARGET_KIND_DATA:
        case GF_OMP_TARGET_KIND_OACC_PARALLEL:
        case GF_OMP_TARGET_KIND_OACC_KERNELS:
+       case GF_OMP_TARGET_KIND_OACC_SERIAL:
        case GF_OMP_TARGET_KIND_OACC_DATA:
        case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
          break;
index 0c8acb27614f5fdddf70f8c58adfc9e800f2c2da..92d118a3c512ece55cb54ac1181703b7ef0f9e0e 100644 (file)
@@ -171,15 +171,17 @@ static tree scan_omp_1_op (tree *, int *, void *);
       *handled_ops_p = false; \
       break;
 
-/* Return true if CTX corresponds to an oacc parallel region.  */
+/* Return true if CTX corresponds to an oacc parallel or serial region.  */
 
 static bool
-is_oacc_parallel (omp_context *ctx)
+is_oacc_parallel_or_serial (omp_context *ctx)
 {
   enum gimple_code outer_type = gimple_code (ctx->stmt);
   return ((outer_type == GIMPLE_OMP_TARGET)
-         && (gimple_omp_target_kind (ctx->stmt)
-             == GF_OMP_TARGET_KIND_OACC_PARALLEL));
+         && ((gimple_omp_target_kind (ctx->stmt)
+              == GF_OMP_TARGET_KIND_OACC_PARALLEL)
+             || (gimple_omp_target_kind (ctx->stmt)
+                 == GF_OMP_TARGET_KIND_OACC_SERIAL)));
 }
 
 /* Return true if CTX corresponds to an oacc kernels region.  */
@@ -540,7 +542,7 @@ build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
 {
   tree x, field = lookup_field (var, ctx);
 
-  if (is_oacc_parallel (ctx))
+  if (is_oacc_parallel_or_serial (ctx))
     x = lookup_parm (var, ctx);
   else
     {
@@ -694,7 +696,7 @@ build_sender_ref (tree var, omp_context *ctx)
 static void
 install_parm_decl (tree var, tree type, omp_context *ctx)
 {
-  if (!is_oacc_parallel (ctx))
+  if (!is_oacc_parallel_or_serial (ctx))
     return;
 
   splay_tree_key key = (splay_tree_key) var;
@@ -1292,7 +1294,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx,
 
        case OMP_CLAUSE_REDUCTION:
        case OMP_CLAUSE_IN_REDUCTION:
-          if (is_oacc_parallel (ctx) || is_oacc_kernels (ctx))
+          if (is_oacc_parallel_or_serial (ctx) || is_oacc_kernels (ctx))
             ctx->local_reduction_clauses
              = tree_cons (NULL, c, ctx->local_reduction_clauses);
          decl = OMP_CLAUSE_DECL (c);
@@ -1910,7 +1912,7 @@ create_omp_child_function (omp_context *ctx, bool task_copy,
   if (task_copy)
     type = build_function_type_list (void_type_node, ptr_type_node,
                                     ptr_type_node, NULL_TREE);
-  else if (is_oacc_parallel (ctx))
+  else if (is_oacc_parallel_or_serial (ctx))
     {
       tree *arg_types = (tree *) alloca (sizeof (tree) * map_cnt);
       for (unsigned int i = 0; i < map_cnt; i++)
@@ -1990,7 +1992,7 @@ create_omp_child_function (omp_context *ctx, bool task_copy,
   DECL_CONTEXT (t) = decl;
   DECL_RESULT (decl) = t;
 
-  if (!is_oacc_parallel (ctx))
+  if (!is_oacc_parallel_or_serial (ctx))
     {
       tree data_name = get_identifier (".omp_data_i");
       t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
@@ -2559,7 +2561,7 @@ scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
     {
       omp_context *tgt = enclosing_target_ctx (outer_ctx);
 
-      if (!tgt || is_oacc_parallel (tgt))
+      if (!tgt || is_oacc_parallel_or_serial (tgt))
        for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
          {
            char const *check = NULL;
@@ -2924,7 +2926,7 @@ scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
   bool base_pointers_restrict = false;
   if (offloaded)
     {
-      if (!is_oacc_parallel (ctx))
+      if (!is_oacc_parallel_or_serial (ctx))
        {
          create_omp_child_function (ctx, false);
          gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
@@ -3125,6 +3127,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
                  {
                  case GF_OMP_TARGET_KIND_OACC_PARALLEL:
                  case GF_OMP_TARGET_KIND_OACC_KERNELS:
+                 case GF_OMP_TARGET_KIND_OACC_SERIAL:
                    ok = true;
                    break;
 
@@ -3573,6 +3576,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
              stmt_name = "target exit data"; break;
            case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
            case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
+           case GF_OMP_TARGET_KIND_OACC_SERIAL: stmt_name = "serial"; break;
            case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
            case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
            case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
@@ -3589,6 +3593,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
              ctx_stmt_name = "parallel"; break;
            case GF_OMP_TARGET_KIND_OACC_KERNELS:
              ctx_stmt_name = "kernels"; break;
+           case GF_OMP_TARGET_KIND_OACC_SERIAL:
+             ctx_stmt_name = "serial"; break;
            case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
            case GF_OMP_TARGET_KIND_OACC_HOST_DATA:
              ctx_stmt_name = "host_data"; break;
@@ -6127,8 +6133,10 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
                    break;
 
                  case GIMPLE_OMP_TARGET:
-                   if (gimple_omp_target_kind (probe->stmt)
-                       != GF_OMP_TARGET_KIND_OACC_PARALLEL)
+                   if ((gimple_omp_target_kind (probe->stmt)
+                        != GF_OMP_TARGET_KIND_OACC_PARALLEL)
+                       && (gimple_omp_target_kind (probe->stmt)
+                           != GF_OMP_TARGET_KIND_OACC_SERIAL))
                      goto do_lookup;
 
                    cls = gimple_omp_target_clauses (probe->stmt);
@@ -6933,7 +6941,8 @@ lower_oacc_head_mark (location_t loc, tree ddvar, tree clauses,
   /* In a parallel region, loops without auto and seq clauses are
      implicitly INDEPENDENT.  */
   omp_context *tgt = enclosing_target_ctx (ctx);
-  if ((!tgt || is_oacc_parallel (tgt)) && !(tag & (OLF_SEQ | OLF_AUTO)))
+  if ((!tgt || is_oacc_parallel_or_serial (tgt))
+      && !(tag & (OLF_SEQ | OLF_AUTO)))
     tag |= OLF_INDEPENDENT;
 
   if (tag & OLF_TILE)
@@ -9759,7 +9768,7 @@ convert_from_firstprivate_int (tree var, tree orig_type, bool is_ref,
 static tree
 append_decl_arg (tree var, tree decl_args, omp_context *ctx)
 {
-  if (!is_oacc_parallel (ctx))
+  if (!is_oacc_parallel_or_serial (ctx))
     return NULL_TREE;
 
   tree temp = lookup_parm (var, ctx);
@@ -9792,6 +9801,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
     case GF_OMP_TARGET_KIND_EXIT_DATA:
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
+    case GF_OMP_TARGET_KIND_OACC_SERIAL:
     case GF_OMP_TARGET_KIND_OACC_UPDATE:
     case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
     case GF_OMP_TARGET_KIND_OACC_DECLARE:
@@ -9835,7 +9845,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   /* Determine init_cnt to finish initialize ctx.  */
 
-  if (is_oacc_parallel (ctx))
+  if (is_oacc_parallel_or_serial (ctx))
     {
       for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
        switch (OMP_CLAUSE_CODE (c))
@@ -9885,7 +9895,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
            break;
 
          case OMP_CLAUSE_FIRSTPRIVATE:
-           if (is_oacc_parallel (ctx))
+           if (is_oacc_parallel_or_serial (ctx))
              goto init_oacc_firstprivate;
            init_cnt++;
            break;
@@ -10082,7 +10092,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
        break;
 
       case OMP_CLAUSE_FIRSTPRIVATE:
-       if (is_oacc_parallel (ctx))
+       if (is_oacc_parallel_or_serial (ctx))
          goto oacc_firstprivate;
        map_cnt++;
        var = OMP_CLAUSE_DECL (c);
@@ -10166,7 +10176,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 
   if (offloaded)
     {
-      if (is_oacc_parallel (ctx))
+      if (is_oacc_parallel_or_serial (ctx))
        gcc_assert (init_cnt == map_cnt);
       target_nesting_level++;
       lower_omp (&tgt_body, ctx);
@@ -10494,7 +10504,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
            break;
 
          case OMP_CLAUSE_FIRSTPRIVATE:
-           if (is_oacc_parallel (ctx))
+           if (is_oacc_parallel_or_serial (ctx))
              goto oacc_firstprivate_map;
            ovar = OMP_CLAUSE_DECL (c);
            if (omp_is_reference (ovar))
@@ -10632,7 +10642,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
          }
 
       gcc_assert (map_idx == map_cnt);
-      if (is_oacc_parallel (ctx))
+      if (is_oacc_parallel_or_serial (ctx))
        DECL_ARGUMENTS (child_fn) = nreverse (decl_args);
 
       DECL_INITIAL (TREE_VEC_ELT (t, 1))
@@ -10672,7 +10682,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
     {
       t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
       /* fixup_child_record_type might have changed receiver_decl's type.  */
-      if (!is_oacc_parallel (ctx))
+      if (!is_oacc_parallel_or_serial (ctx))
        {
          t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
          gimple_seq_add_stmt (&new_body,
@@ -11043,7 +11053,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
       gimple_seq fork_seq = NULL;
       gimple_seq join_seq = NULL;
 
-      if (is_oacc_parallel (ctx))
+      if (is_oacc_parallel_or_serial (ctx))
        {
          /* If there are reductions on the offloaded region itself, treat
             them as a dummy GANG loop.  */
index 9bc3aac58f6de605ac8ed5277f0bcbd2757ac7d4..d4ac568f43378a4ef6f94639626180e8b3968ec7 100644 (file)
@@ -1,3 +1,7 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * c-c++-common/goacc/serial-dims.c: New test.
+
 2017-12-21  Cesar Philippidis  <cesar@codesourcery.com>
 
        * c-c++-common/goacc/large_array.c: New test.
diff --git a/gcc/testsuite/c-c++-common/goacc/serial-dims.c b/gcc/testsuite/c-c++-common/goacc/serial-dims.c
new file mode 100644 (file)
index 0000000..41698d2
--- /dev/null
@@ -0,0 +1,12 @@
+/* Invalid use of OpenACC parallelism dimensions clauses: num_gangs,
+   num_workers, vector_length with the serial construct.  */
+
+void f(void)
+{
+#pragma acc serial num_gangs (1) /* { dg-error "'num_gangs' is not valid for '#pragma acc serial'" } */
+  ;
+#pragma acc serial num_workers (1) /* { dg-error "'num_workers' is not valid for '#pragma acc serial'" } */
+  ;
+#pragma acc serial vector_length (1) /* { dg-error "'vector_length' is not valid for '#pragma acc serial'" } */
+  ;
+}
index f74a927bbd6f0aafaee0ebfae692e59d8240026a..5e1483f77cbee64d1f599f2393509c81112c3af8 100644 (file)
@@ -3126,6 +3126,10 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
       pp_string (pp, "#pragma acc kernels");
       goto dump_omp_clauses_body;
 
+    case OACC_SERIAL:
+      pp_string (pp, "#pragma acc serial");
+      goto dump_omp_clauses_body;
+
     case OACC_DATA:
       pp_string (pp, "#pragma acc data");
       dump_omp_clauses (pp, OACC_DATA_CLAUSES (node), spc, flags);
index 1d6ddedd9657191e67917dcff8b7f3d681cd8e1c..56cec43c3c8876b98e362c18bc78d5c345341dc0 100644 (file)
@@ -1084,6 +1084,12 @@ DEFTREECODE (OACC_PARALLEL, "oacc_parallel", tcc_statement, 2)
 
 DEFTREECODE (OACC_KERNELS, "oacc_kernels", tcc_statement, 2)
 
+/* OpenACC - #pragma acc serial [clause1 ... clauseN]
+   Operand 0: OMP_BODY: Code to be executed sequentially.
+   Operand 1: OMP_CLAUSES: List of clauses.  */
+
+DEFTREECODE (OACC_SERIAL, "oacc_serial", tcc_statement, 2)
+
 /* OpenACC - #pragma acc data [clause1 ... clauseN]
    Operand 0: OACC_DATA_BODY: Data construct body.
    Operand 1: OACC_DATA_CLAUSES: List of clauses.  */
index 05cfabc72af6c144b63d231ca53c9e35c3b81ebf..c063ddab27eae05dd1063b62a0637d586710e028 100644 (file)
@@ -1,3 +1,7 @@
+2018-12-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * testsuite/libgomp.oacc-c-c++-common/serial-dims.c: New test.
+
 2017-12-21  Cesar Philippidis  <cesar@codesourcery.com>
 
        * Makefile.am: Add libffi build dependency.
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/serial-dims.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/serial-dims.c
new file mode 100644 (file)
index 0000000..7a8a85c
--- /dev/null
@@ -0,0 +1,98 @@
+/* OpenACC dimensions with the serial construct.  */
+
+/* { dg-additional-options "-foffload-force" } */
+
+#include <limits.h>
+#include <openacc.h>
+#include <gomp-constants.h>
+
+/* TODO: "(int) acc_device_*" casts because of the C++ acc_on_device wrapper
+   not behaving as expected for -O0.  */
+#pragma acc routine seq
+static unsigned int __attribute__ ((optimize ("O2"))) acc_gang ()
+{
+  if (acc_on_device ((int) acc_device_host))
+    return 0;
+  else if (acc_on_device ((int) acc_device_nvidia))
+    return __builtin_goacc_parlevel_id (GOMP_DIM_GANG);
+  else
+    __builtin_abort ();
+}
+
+#pragma acc routine seq
+static unsigned int __attribute__ ((optimize ("O2"))) acc_worker ()
+{
+  if (acc_on_device ((int) acc_device_host))
+    return 0;
+  else if (acc_on_device ((int) acc_device_nvidia))
+    return __builtin_goacc_parlevel_id (GOMP_DIM_WORKER);
+  else
+    __builtin_abort ();
+}
+
+#pragma acc routine seq
+static unsigned int __attribute__ ((optimize ("O2"))) acc_vector ()
+{
+  if (acc_on_device ((int) acc_device_host))
+    return 0;
+  else if (acc_on_device ((int) acc_device_nvidia))
+    return __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR);
+  else
+    __builtin_abort ();
+}
+
+
+int main ()
+{
+  acc_init (acc_device_default);
+
+  /* Serial OpenACC constructs must get launched as 1 x 1 x 1.  */
+  {
+    int gangs_min, gangs_max;
+    int workers_min, workers_max;
+    int vectors_min, vectors_max;
+    int gangs_actual, workers_actual, vectors_actual;
+    int i, j, k;
+
+    gangs_min = workers_min = vectors_min = INT_MAX;
+    gangs_max = workers_max = vectors_max = INT_MIN;
+    gangs_actual = workers_actual = vectors_actual = 1;
+#pragma acc serial
+    /* { dg-warning "region contains gang partitoned code but is not gang partitioned" "" { target *-*-* } 60 } */
+    /* { dg-warning "region contains worker partitoned code but is not worker partitioned" "" { target *-*-* } 60 } */
+    /* { dg-warning "region contains vector partitoned code but is not vector partitioned" "" { target *-*-* } 60 } */
+    /* { dg-warning "using vector_length \\(32\\), ignoring 1" "" { target openacc_nvidia_accel_selected } 60 } */
+    {
+      if (acc_on_device (acc_device_nvidia))
+       {
+         /* The GCC nvptx back end enforces vector_length (32).  */
+         vectors_actual = 32;
+       }
+      else if (!acc_on_device (acc_device_host))
+       __builtin_abort ();
+#pragma acc loop gang \
+  reduction (min: gangs_min, workers_min, vectors_min) \
+  reduction (max: gangs_max, workers_max, vectors_max)
+      for (i = 100 * gangs_actual; i > -100 * gangs_actual; i--)
+#pragma acc loop worker \
+  reduction (min: gangs_min, workers_min, vectors_min) \
+  reduction (max: gangs_max, workers_max, vectors_max)
+       for (j = 100 * workers_actual; j > -100 * workers_actual; j--)
+#pragma acc loop vector \
+  reduction (min: gangs_min, workers_min, vectors_min) \
+  reduction (max: gangs_max, workers_max, vectors_max)
+         for (k = 100 * vectors_actual; k > -100 * vectors_actual; k--)
+           {
+             gangs_min = gangs_max = acc_gang ();
+             workers_min = workers_max = acc_worker ();
+             vectors_min = vectors_max = acc_vector ();
+           }
+      if (gangs_min != 0 || gangs_max != gangs_actual - 1
+         || workers_min != 0 || workers_max != workers_actual - 1
+         || vectors_min != 0 || vectors_max != vectors_actual - 1)
+       __builtin_abort ();
+    }
+  }
+
+  return 0;
+}