summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2019-02-12 14:56:12 -0800
committerThomas Schwinge <thomas@codesourcery.com>2020-03-03 12:13:30 +0100
commit3fa4bb72dcb3b9171952a0eca5310bb8811d5ffd (patch)
tree9495b8c26b118c25983a5fa4a15a7f45ad4a4e42
parent2d11254d63174644a80a869f031a3d929d7d4e4f (diff)
downloadgcc-3fa4bb72dcb3b9171952a0eca5310bb8811d5ffd.tar.gz
Various OpenACC reduction enhancements - FE changes
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)
-rw-r--r--gcc/c/ChangeLog.omp18
-rw-r--r--gcc/c/c-parser.c35
-rw-r--r--gcc/c/c-typeck.c24
-rw-r--r--gcc/cp/ChangeLog.omp19
-rw-r--r--gcc/cp/parser.c24
-rw-r--r--gcc/cp/semantics.c30
-rw-r--r--gcc/fortran/ChangeLog.omp8
-rw-r--r--gcc/fortran/openmp.c12
-rw-r--r--gcc/fortran/trans-openmp.c3
9 files changed, 137 insertions, 36 deletions
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index ed7b8b9e73e..db92b242281 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -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>
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7c2907a765c..0e49167381d 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -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);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 481b55b065b..a4a78cf8f36 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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;
}
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index 63bae9714ff..370d895d2c5 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -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>
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4e3993c0f69..b8de1427650 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 15519e773e3..12ab7ceed9d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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
diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index e36d18b3c88..63658705490 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -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>
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index fa0a67399c0..81b69b9c7af 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -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 "
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 3911945a2b3..aa6c51116c3 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -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)