This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] various OpenACC reduction enhancements - FE changes
- From: Cesar Philippidis <cesar at codesourcery dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>, Tom de Vries <tdevries at suse dot de>, Fortran List <fortran at gcc dot gnu dot org>
- Date: Fri, 29 Jun 2018 11:22:00 -0700
- Subject: Re: [patch] various OpenACC reduction enhancements - FE changes
- References: <ae587152-072d-52b0-0129-99de0ed40d03@codesourcery.com>
Attaches are the FE changes for the OpenACC reduction enhancements. It
depends on the ME patch.
Is this patch OK for trunk? It bootstrapped / regression tested cleanly
for x86_64 with nvptx offloading.
Thanks,
Cesar
2018-06-29 Cesar Philippidis <cesar@codesourcery.com>
Nathan Sidwell <nathan@acm.org>
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_omp_clause_reduction): Update call to
c_parser_omp_variable_list. Propage OpenACC errors as necessary.
(c_parser_oacc_all_clauses): Update call to
p_parser_omp_clause_reduction.
(c_parser_omp_all_clauses): Likewise.
* c-typeck.c (c_finish_omp_clauses): Emit an error on orphan OpenACC
gang reductions.
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_clause_reduction): Update call to
cp_parser_omp_variable_list. Propage OpenACC errors as necessary.
(cp_parser_oacc_all_clauses): Update call to
cp_parser_omp_clause_reduction.
(cp_parser_omp_all_clauses): Likewise.
* semantics.c (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.
---
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7a926285f3a..a6f453dae54 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -965,12 +965,13 @@ class token_pair
/* Like token_pair::require_close, except that tokens will be skipped
until the desired token is found. An error message is still produced
- if the next token is not as expected. */
+ if the next token is not as expected, unless QUIET is set. */
- void skip_until_found_close (c_parser *parser) const
+ void skip_until_found_close (c_parser *parser, bool quiet = false) const
{
c_parser_skip_until_found (parser, traits_t::close_token_type,
- traits_t::close_gmsgid, m_open_loc);
+ quiet ? NULL : traits_t::close_gmsgid,
+ m_open_loc);
}
private:
@@ -11498,7 +11499,8 @@ c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
static tree
c_parser_omp_variable_list (c_parser *parser,
location_t clause_loc,
- enum omp_clause_code kind, tree list)
+ enum omp_clause_code kind, tree list,
+ enum c_omp_region_type ort = C_ORT_OMP)
{
if (c_parser_next_token_is_not (parser, CPP_NAME)
|| c_parser_peek_token (parser)->id_kind != C_ID_ID)
@@ -11557,6 +11559,22 @@ c_parser_omp_variable_list (c_parser *parser,
/* FALLTHROUGH */
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_REDUCTION:
+ if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_ACC)
+ {
+ switch (c_parser_peek_token (parser)->type)
+ {
+ case CPP_OPEN_PAREN:
+ case CPP_OPEN_SQUARE:
+ case CPP_DOT:
+ case CPP_DEREF:
+ error ("invalid reduction variable");
+ t = error_mark_node;
+ default:;
+ break;
+ }
+ if (t == error_mark_node)
+ break;
+ }
while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
{
tree low_bound = NULL_TREE, length = NULL_TREE;
@@ -12789,9 +12807,12 @@ c_parser_omp_clause_private (c_parser *parser, tree list)
identifier */
static tree
-c_parser_omp_clause_reduction (c_parser *parser, tree list)
+c_parser_omp_clause_reduction (c_parser *parser, tree list,
+ enum c_omp_region_type ort)
{
location_t clause_loc = c_parser_peek_token (parser)->location;
+ bool seen_error = false;
+
matching_parens parens;
if (parens.require_open (parser))
{
@@ -12855,7 +12876,13 @@ c_parser_omp_clause_reduction (c_parser *parser, tree list)
tree nl, c;
nl = c_parser_omp_variable_list (parser, clause_loc,
- OMP_CLAUSE_REDUCTION, list);
+ OMP_CLAUSE_REDUCTION, list, ort);
+ if (c_parser_peek_token (parser)->type != CPP_CLOSE_PAREN)
+ {
+ seen_error = true;
+ goto cleanup;
+ }
+
for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
{
tree d = OMP_CLAUSE_DECL (c), type;
@@ -12891,7 +12918,8 @@ c_parser_omp_clause_reduction (c_parser *parser, tree list)
list = nl;
}
- parens.skip_until_found_close (parser);
+ cleanup:
+ parens.skip_until_found_close (parser, seen_error);
}
return list;
}
@@ -13998,7 +14026,7 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
c_name = "private";
break;
case PRAGMA_OACC_CLAUSE_REDUCTION:
- clauses = c_parser_omp_clause_reduction (parser, clauses);
+ clauses = c_parser_omp_clause_reduction (parser, clauses, C_ORT_ACC);
c_name = "reduction";
break;
case PRAGMA_OACC_CLAUSE_SEQ:
@@ -14157,7 +14185,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
c_name = "private";
break;
case PRAGMA_OMP_CLAUSE_REDUCTION:
- clauses = c_parser_omp_clause_reduction (parser, clauses);
+ clauses = c_parser_omp_clause_reduction (parser, clauses, C_ORT_OMP);
c_name = "reduction";
break;
case PRAGMA_OMP_CLAUSE_SCHEDULE:
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 90ae306c99a..944db3fa8be 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -13087,6 +13087,14 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
goto check_dup_generic;
case OMP_CLAUSE_REDUCTION:
+ if (ort == C_ORT_ACC && oacc_get_fn_attrib (current_function_decl)
+ && omp_find_clause (clauses, OMP_CLAUSE_GANG))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "gang reduction on an orphan loop");
+ remove = true;
+ break;
+ }
need_implicitly_determined = true;
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a076de146e6..6444293bb82 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -31592,7 +31592,8 @@ 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)
+ tree list, bool *colon,
+ enum c_omp_region_type ort = C_ORT_OMP)
{
cp_token *token;
bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
@@ -31668,6 +31669,21 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
/* FALLTHROUGH. */
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_REDUCTION:
+ if (kind == OMP_CLAUSE_REDUCTION && ort == C_ORT_ACC)
+ {
+ switch (cp_lexer_peek_token (parser->lexer)->type)
+ {
+ case CPP_OPEN_PAREN:
+ case CPP_OPEN_SQUARE:
+ case CPP_DOT:
+ case CPP_DEREF:
+ error ("invalid reduction variable");
+ decl = error_mark_node;
+ goto skip_comma;
+ default:;
+ break;
+ }
+ }
while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{
tree low_bound = NULL_TREE, length = NULL_TREE;
@@ -32746,7 +32762,8 @@ cp_parser_omp_clause_ordered (cp_parser *parser,
id-expression */
static tree
-cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
+cp_parser_omp_clause_reduction (cp_parser *parser, tree list,
+ enum c_omp_region_type ort)
{
enum tree_code code = ERROR_MARK;
tree nlist, c, id = NULL_TREE;
@@ -32827,7 +32844,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
goto resync_fail;
nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_REDUCTION, list,
- NULL);
+ NULL, ort);
for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
{
OMP_CLAUSE_REDUCTION_CODE (c) = code;
@@ -33868,7 +33885,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "private";
break;
case PRAGMA_OACC_CLAUSE_REDUCTION:
- clauses = cp_parser_omp_clause_reduction (parser, clauses);
+ clauses = cp_parser_omp_clause_reduction (parser, clauses, C_ORT_ACC);
c_name = "reduction";
break;
case PRAGMA_OACC_CLAUSE_SEQ:
@@ -34055,7 +34072,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "private";
break;
case PRAGMA_OMP_CLAUSE_REDUCTION:
- clauses = cp_parser_omp_clause_reduction (parser, clauses);
+ clauses = cp_parser_omp_clause_reduction (parser, clauses, C_ORT_OMP);
c_name = "reduction";
break;
case PRAGMA_OMP_CLAUSE_SCHEDULE:
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c779137da45..177acdd9cc4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5875,6 +5875,14 @@ 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 (ort == C_ORT_ACC && oacc_get_fn_attrib (current_function_decl)
+ && omp_find_clause (clauses, OMP_CLAUSE_GANG))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "gang reduction on an orphan loop");
+ remove = true;
+ break;
+ }
field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 94a7f7eaa50..38d857c14e5 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -5878,6 +5878,18 @@ resolve_oacc_loop_blocks (gfc_code *code)
break;
}
+ if (code->op == EXEC_OACC_LOOP
+ && code->ext.omp_clauses->lists[OMP_LIST_REDUCTION]
+ && code->ext.omp_clauses->gang)
+ {
+ for (c = omp_current_ctx; c; c = c->previous)
+ if (!oacc_is_loop (c->code))
+ break;
+ if (c == NULL || !(oacc_is_parallel (c->code)
+ || oacc_is_kernels (c->code)))
+ gfc_error ("gang reduction on an orphan loop at %L", &code->loc);
+ }
+
if (code->ext.omp_clauses->seq)
{
if (code->ext.omp_clauses->independent)
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index f038f4c5bf8..c6484d62916 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -563,7 +563,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)