]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Various OpenACC reduction enhancements - FE changes
authorJulian Brown <julian@codesourcery.com>
Tue, 12 Feb 2019 22:56:12 +0000 (14:56 -0800)
committerThomas Schwinge <thomas@codesourcery.com>
Tue, 3 Mar 2020 11:13:30 +0000 (12:13 +0100)
This version differs somewhat from the last version posted upstream
(and addresses some of Jakub's review comments).

2018-12-13  Cesar Philippidis  <cesar@codesourcery.com>
            Nathan Sidwell  <nathan@acm.org>
            Julian Brown  <julian@codesourcery.com>

        gcc/c/
        * c-parser.c (c_parser_omp_variable_list): New c_omp_region_type
        argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
        OpenACC.
(c_parser_oacc_data_clause): Add region-type argument.
(c_parser_oacc_data_clause_deviceptr): Likewise.
        (c_parser_omp_clause_reduction): Change is_omp boolean parameter to
        c_omp_region_type.  Update call to c_parser_omp_variable_list.
        (c_parser_oacc_all_clauses): Update calls to
        c_parser_omp_clause_reduction.
        (c_parser_omp_all_clauses): Likewise.
(c_parser_oacc_cache): Update call to c_parser_omp_var_list_parens.
        * c-typeck.c (c_finish_omp_clauses): Emit an error on orphan OpenACC
        gang reductions.  Suppress user-defined reduction error for OpenACC.

        gcc/cp/
        * parser.c (cp_parser_omp_var_list_no_open):  New c_omp_region_type
        argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
        OpenACC.
(cp_parser_omp_var_list): Add c_omp_region_type argument. Update call
to cp_parser_omp_var_list_parens.
(cp_parser_oacc_data_clause): Update call to cp_parser_omp_var_list.
        (cp_parser_omp_clause_reduction): Change is_omp boolean parameter to
        c_omp_region_type.  Update call to cp_parser_omp_var_list_no_open.
        (cp_parser_oacc_all_clauses): Update call to
        cp_parser_omp_clause_reduction.
        (cp_parser_omp_all_clauses): Likewise.
        * semantics.c (finish_omp_reduction_clause): Add c_omp_region_type
argument.  Suppress user-defined reduction error for OpenACC.
(finish_omp_clauses): Emit an error on orphan OpenACC gang reductions.

        gcc/fortran/
        * openmp.c (resolve_oacc_loop_blocks): Emit an error on orphan OpenACC
        gang reductions.
        * trans-openmp.c (gfc_omp_clause_copy_ctor): Permit reductions.

(cherry picked from openacc-gcc-9-branch commit
533beb2ec19f8486e4b1b645a153746f96b41f04)

gcc/c/ChangeLog.omp
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/cp/ChangeLog.omp
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/fortran/ChangeLog.omp
gcc/fortran/openmp.c
gcc/fortran/trans-openmp.c

index ed7b8b9e73e7c4bc5c9ebebde580a6b178924328..db92b2422816ac5dcb800ad888063898a555a6ff 100644 (file)
@@ -1,3 +1,21 @@
+2018-12-13  Cesar Philippidis  <cesar@codesourcery.com>
+            Nathan Sidwell  <nathan@acm.org>
+            Julian Brown  <julian@codesourcery.com>
+
+        * c-parser.c (c_parser_omp_variable_list): New c_omp_region_type
+        argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
+        OpenACC.
+       (c_parser_oacc_data_clause): Add region-type argument.
+       (c_parser_oacc_data_clause_deviceptr): Likewise.
+        (c_parser_omp_clause_reduction): Change is_omp boolean parameter to
+        c_omp_region_type.  Update call to c_parser_omp_variable_list.
+        (c_parser_oacc_all_clauses): Update calls to
+        c_parser_omp_clause_reduction.
+        (c_parser_omp_all_clauses): Likewise.
+       (c_parser_oacc_cache): Update call to c_parser_omp_var_list_parens.
+        * c-typeck.c (c_finish_omp_clauses): Emit an error on orphan OpenACC
+        gang reductions.  Suppress user-defined reduction error for OpenACC.
+
 2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
index 7c2907a765c2cad10d066a6ec95a1329886b990f..0e49167381d3789fd9390db3786b6654db4fc0c1 100644 (file)
@@ -11938,6 +11938,7 @@ static tree
 c_parser_omp_variable_list (c_parser *parser,
                            location_t clause_loc,
                            enum omp_clause_code kind, tree list,
+                           enum c_omp_region_type ort = C_ORT_OMP,
                            bool allow_deref = false)
 {
   auto_vec<c_token> tokens;
@@ -12077,7 +12078,8 @@ c_parser_omp_variable_list (c_parser *parser,
            case OMP_CLAUSE_REDUCTION:
            case OMP_CLAUSE_IN_REDUCTION:
            case OMP_CLAUSE_TASK_REDUCTION:
-             while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
+             while ((ort != C_ORT_ACC || kind != OMP_CLAUSE_REDUCTION)
+                    && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
                {
                  tree low_bound = NULL_TREE, length = NULL_TREE;
 
@@ -12183,7 +12185,9 @@ c_parser_omp_variable_list (c_parser *parser,
 
 static tree
 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
-                             tree list, bool allow_deref = false)
+                             tree list,
+                             enum c_omp_region_type ort = C_ORT_OMP,
+                             bool allow_deref = false)
 {
   /* The clauses location.  */
   location_t loc = c_parser_peek_token (parser)->location;
@@ -12191,7 +12195,8 @@ c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
   matching_parens parens;
   if (parens.require_open (parser))
     {
-      list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
+      list = c_parser_omp_variable_list (parser, loc, kind, list, ort,
+                                        allow_deref);
       parens.skip_until_found_close (parser);
     }
   return list;
@@ -12254,7 +12259,8 @@ c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
       gcc_unreachable ();
     }
   tree nl, c;
-  nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
+  nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, C_ORT_ACC,
+                                    true);
 
   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
     OMP_CLAUSE_SET_MAP_KIND (c, kind);
@@ -12274,7 +12280,8 @@ c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
      c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
      variable-list must only allow for pointer variables.  */
-  vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
+  vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL,
+                                      C_ORT_ACC);
   for (t = vars; t && t; t = TREE_CHAIN (t))
     {
       tree v = TREE_PURPOSE (t);
@@ -13536,7 +13543,7 @@ c_parser_omp_clause_private (c_parser *parser, tree list)
 
 static tree
 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
-                              bool is_omp, tree list)
+                              enum c_omp_region_type ort, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   matching_parens parens;
@@ -13547,7 +13554,7 @@ c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
       enum tree_code code = ERROR_MARK;
       tree reduc_id = NULL_TREE;
 
-      if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+      if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_OMP)
        {
          if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
              && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
@@ -13632,7 +13639,8 @@ c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
        {
          tree nl, c;
 
-         nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
+         nl = c_parser_omp_variable_list (parser, clause_loc, kind, list, ort);
+
          for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
            {
              tree d = OMP_CLAUSE_DECL (c), type;
@@ -14950,7 +14958,7 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
        case PRAGMA_OACC_CLAUSE_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                            false, clauses);
+                                            C_ORT_ACC, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SEQ:
@@ -15079,7 +15087,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
-                                            true, clauses);
+                                            C_ORT_OMP, clauses);
          c_name = "in_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -15117,7 +15125,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                            true, clauses);
+                                            C_ORT_OMP, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -15131,7 +15139,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
-                                            true, clauses);
+                                            C_ORT_OMP, clauses);
          c_name = "task_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_UNTIED:
@@ -15335,7 +15343,8 @@ c_parser_oacc_cache (location_t loc, c_parser *parser)
 {
   tree stmt, clauses;
 
-  clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
+  clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL,
+                                         C_ORT_ACC);
   clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
 
   c_parser_skip_to_pragma_eol (parser);
index 481b55b065b950c690cdbce44e835f2a2da634ff..a4a78cf8f36b539a35b1a14dcabeacba167453a9 100644 (file)
@@ -13737,6 +13737,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
   bool last_iterators_remove = false;
   tree *nogroup_seen = NULL;
   bool reduction_seen = false;
+  bool oacc_gang_seen = false;
 
   bitmap_obstack_initialize (NULL);
   bitmap_initialize (&generic_head, &bitmap_default_obstack);
@@ -13751,10 +13752,15 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 
   if (ort & C_ORT_ACC)
     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
-      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
-       {
+      switch (OMP_CLAUSE_CODE (c))
+        {
+       case OMP_CLAUSE_ASYNC:
          oacc_async = true;
          break;
+       case OMP_CLAUSE_GANG:
+         oacc_gang_seen = true;
+         break;
+       default:;
        }
 
   for (pc = &clauses, c = clauses; c ; c = *pc)
@@ -13775,6 +13781,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          goto check_dup_generic;
 
        case OMP_CLAUSE_REDUCTION:
+         if (oacc_gang_seen && oacc_get_fn_attrib (current_function_decl))
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "gang reduction on an orphan loop");
+             remove = true;
+             break;
+           }
          reduction_seen = true;
          /* FALLTHRU */
        case OMP_CLAUSE_IN_REDUCTION:
@@ -13917,8 +13930,11 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
            }
          else if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
            {
-             error_at (OMP_CLAUSE_LOCATION (c),
-                       "user defined reduction not found for %qE", t);
+             /* There are no user-defined reductions in OpenACC (as of
+                2.6).  */
+             if (ort & C_ORT_OMP)
+               error_at (OMP_CLAUSE_LOCATION (c),
+                         "user defined reduction not found for %qE", t);
              remove = true;
              break;
            }
index 63bae9714ff052c97489039c85c60ccb7f35487a..370d895d2c5f5fc0633e834570a003bb0cfeec7b 100644 (file)
@@ -1,3 +1,22 @@
+2018-12-13  Cesar Philippidis  <cesar@codesourcery.com>
+            Nathan Sidwell  <nathan@acm.org>
+            Julian Brown  <julian@codesourcery.com>
+
+        * parser.c (cp_parser_omp_var_list_no_open):  New c_omp_region_type
+        argument.  Use it to specialize handling of OMP_CLAUSE_REDUCTION for
+        OpenACC.
+       (cp_parser_omp_var_list): Add c_omp_region_type argument. Update call
+       to cp_parser_omp_var_list_parens.
+       (cp_parser_oacc_data_clause): Update call to cp_parser_omp_var_list.
+        (cp_parser_omp_clause_reduction): Change is_omp boolean parameter to
+        c_omp_region_type.  Update call to cp_parser_omp_var_list_no_open.
+        (cp_parser_oacc_all_clauses): Update call to
+        cp_parser_omp_clause_reduction.
+        (cp_parser_omp_all_clauses): Likewise.
+        * semantics.c (finish_omp_reduction_clause): Add c_omp_region_type
+       argument.  Suppress user-defined reduction error for OpenACC.
+       (finish_omp_clauses): Emit an error on orphan OpenACC gang reductions.
+
 2018-10-02  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
index 4e3993c0f69f5f4f1f3117919e4811c64d2524a8..b8de1427650a266df9b5d42075474e4033d42637 100644 (file)
@@ -32437,6 +32437,7 @@ check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
 static tree
 cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
                                tree list, bool *colon,
+                               enum c_omp_region_type ort = C_ORT_OMP,
                                bool allow_deref = false)
 {
   cp_token *token;
@@ -32532,7 +32533,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
            case OMP_CLAUSE_REDUCTION:
            case OMP_CLAUSE_IN_REDUCTION:
            case OMP_CLAUSE_TASK_REDUCTION:
-             while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+             while ((ort != C_ORT_ACC || kind != OMP_CLAUSE_REDUCTION)
+                    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
                {
                  tree low_bound = NULL_TREE, length = NULL_TREE;
 
@@ -32642,10 +32644,11 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 
 static tree
 cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list,
+                       enum c_omp_region_type ort = C_ORT_OMP,
                        bool allow_deref = false)
 {
   if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
-    return cp_parser_omp_var_list_no_open (parser, kind, list, NULL,
+    return cp_parser_omp_var_list_no_open (parser, kind, list, NULL, ort,
                                           allow_deref);
   return list;
 }
@@ -32707,7 +32710,7 @@ cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
       gcc_unreachable ();
     }
   tree nl, c;
-  nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_MAP, list, true);
+  nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_MAP, list, C_ORT_ACC, true);
 
   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
     OMP_CLAUSE_SET_MAP_KIND (c, kind);
@@ -33790,7 +33793,7 @@ cp_parser_omp_clause_ordered (cp_parser *parser,
 
 static tree
 cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
-                               bool is_omp, tree list)
+                               enum c_omp_region_type ort, tree list)
 {
   enum tree_code code = ERROR_MARK;
   tree nlist, c, id = NULL_TREE;
@@ -33800,7 +33803,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
-  if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+  if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_OMP)
     {
       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)
          && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
@@ -33901,8 +33904,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
     goto resync_fail;
 
-  nlist = cp_parser_omp_var_list_no_open (parser, kind, list,
-                                         NULL);
+  nlist = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, ort);
   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
     {
       OMP_CLAUSE_REDUCTION_CODE (c) = code;
@@ -35157,7 +35159,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
        case PRAGMA_OACC_CLAUSE_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                             false, clauses);
+                                             C_ORT_ACC, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SEQ:
@@ -35312,7 +35314,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
-                                             true, clauses);
+                                             C_ORT_OMP, clauses);
          c_name = "in_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -35356,7 +35358,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
        case PRAGMA_OMP_CLAUSE_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                             true, clauses);
+                                             C_ORT_OMP, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -35373,7 +35375,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
          clauses
            = cp_parser_omp_clause_reduction (parser,
                                              OMP_CLAUSE_TASK_REDUCTION,
-                                             true, clauses);
+                                             C_ORT_OMP, clauses);
          c_name = "task_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_UNTIED:
index 15519e773e38b535047764f98783444e3cd2602e..12ab7ceed9d24e77f76a2b93e41e1533b70842f6 100644 (file)
@@ -5704,7 +5704,8 @@ find_omp_placeholder_r (tree *tp, int *, void *data)
    Return true if there is some error and the clause should be removed.  */
 
 static bool
-finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
+finish_omp_reduction_clause (tree c, enum c_omp_region_type ort,
+                            bool *need_default_ctor, bool *need_dtor)
 {
   tree t = OMP_CLAUSE_DECL (c);
   bool predefined = false;
@@ -5949,9 +5950,11 @@ finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
     *need_dtor = true;
   else
     {
-      error_at (OMP_CLAUSE_LOCATION (c),
-               "user defined reduction not found for %qE",
-               omp_clause_printable_decl (t));
+      /* There are no user-defined reductions for OpenACC (as of 2.6).  */
+      if (ort & C_ORT_OMP)
+       error_at (OMP_CLAUSE_LOCATION (c),
+                 "user defined reduction not found for %qE",
+                 omp_clause_printable_decl (t));
       return true;
     }
   if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
@@ -6234,6 +6237,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
   tree last_iterators = NULL_TREE;
   bool last_iterators_remove = false;
   bool reduction_seen = false;
+  bool oacc_gang_seen = false;
 
   bitmap_obstack_initialize (NULL);
   bitmap_initialize (&generic_head, &bitmap_default_obstack);
@@ -6248,10 +6252,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 
   if (ort & C_ORT_ACC)
     for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
-      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
-       {
+      switch (OMP_CLAUSE_CODE (c))
+        {
+       case OMP_CLAUSE_ASYNC:
          oacc_async = true;
          break;
+       case OMP_CLAUSE_GANG:
+         oacc_gang_seen = true;
+         break;
+       default:;
        }
 
   for (pc = &clauses, c = clauses; c ; c = *pc)
@@ -6268,6 +6277,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
          field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
          goto check_dup_generic;
        case OMP_CLAUSE_REDUCTION:
+         if (oacc_gang_seen && oacc_get_fn_attrib (current_function_decl))
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "gang reduction on an orphan loop");
+             remove = true;
+             break;
+           }
          reduction_seen = true;
          /* FALLTHRU */
        case OMP_CLAUSE_IN_REDUCTION:
@@ -7848,7 +7864,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
        case OMP_CLAUSE_REDUCTION:
        case OMP_CLAUSE_IN_REDUCTION:
        case OMP_CLAUSE_TASK_REDUCTION:
-         if (finish_omp_reduction_clause (c, &need_default_ctor,
+         if (finish_omp_reduction_clause (c, ort, &need_default_ctor,
                                           &need_dtor))
            remove = true;
          else
index e36d18b3c88935c60b34498a111ed01a1a03f50b..63658705490219a574f468a0e9295f5e473c98bb 100644 (file)
@@ -1,3 +1,11 @@
+2018-12-13  Cesar Philippidis  <cesar@codesourcery.com>
+            Nathan Sidwell  <nathan@acm.org>
+            Julian Brown  <julian@codesourcery.com>
+
+        * openmp.c (resolve_oacc_loop_blocks): Emit an error on orphan OpenACC
+        gang reductions.
+        * trans-openmp.c (gfc_omp_clause_copy_ctor): Permit reductions.
+
 2018-06-29  Cesar Philippidis  <cesar@codesourcery.com>
            James Norris  <jnorris@codesourcery.com>
 
index fa0a67399c04106d75b74e07e9f9259ca96c985b..81b69b9c7af740a6e5761eef3bb832742b6f1349 100644 (file)
@@ -5993,6 +5993,18 @@ resolve_oacc_loop_blocks (gfc_code *code)
   if (!oacc_is_loop (code))
     return;
 
+  if (code->op == EXEC_OACC_LOOP
+      && code->ext.omp_clauses->lists[OMP_LIST_REDUCTION]
+      && code->ext.omp_clauses->gang)
+    {
+      fortran_omp_context *c;
+      for (c = omp_current_ctx; c; c = c->previous)
+       if (!oacc_is_loop (c->code))
+         break;
+      if (c == NULL || !oacc_is_parallel (c->code))
+       gfc_error ("gang reduction on an orphan loop at %L", &code->loc);
+    }
+
   if (code->ext.omp_clauses->tile_list && code->ext.omp_clauses->gang
       && code->ext.omp_clauses->worker && code->ext.omp_clauses->vector)
     gfc_error ("Tiled loop cannot be parallelized across gangs, workers and "
index 3911945a2b363a9aadf2b36e714bf29a3debfc44..aa6c51116c351eb18cce7a23517f25bbfdd65a81 100644 (file)
@@ -581,7 +581,8 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
   stmtblock_t block, cond_block;
 
   gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE
-             || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);
+             || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR
+             || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION);
 
   if ((! GFC_DESCRIPTOR_TYPE_P (type)
        || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)