commit 0fcaa69b46d2661c3b133c42e0ce73693088b04e Author: Julian Brown Date: Wed Dec 12 11:09:29 2018 -0800 Various OpenACC reduction enhancements - FE changes 2018-xx-xx Cesar Philippidis Nathan Sidwell Julian Brown 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): 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-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): 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_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 b875c4f..59a461b 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11869,7 +11869,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) { auto_vec tokens; unsigned int tokens_avail = 0; @@ -12004,7 +12005,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 + && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) { tree low_bound = NULL_TREE, length = NULL_TREE; @@ -12074,6 +12076,10 @@ c_parser_omp_variable_list (c_parser *parser, } } } + if (ort == C_ORT_ACC + && c_parser_next_token_is_not (parser, CPP_COMMA) + && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) + t = error_mark_node; break; default: break; @@ -13446,7 +13452,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; @@ -13457,7 +13463,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) @@ -13542,7 +13548,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; @@ -14847,7 +14854,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: @@ -14976,7 +14983,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: @@ -15014,7 +15021,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: @@ -15028,7 +15035,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: diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 1a89727..a251447 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13683,6 +13683,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); @@ -13697,10 +13698,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) @@ -13721,6 +13727,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: diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8b669a8..71e84ea 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -32111,7 +32111,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; @@ -32201,7 +32202,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 + && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { tree low_bound = NULL_TREE, length = NULL_TREE; @@ -32262,10 +32264,18 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, cp_parser_parse_definitely (parser); } - tree u = build_omp_clause (token->location, kind); - OMP_CLAUSE_DECL (u) = decl; - OMP_CLAUSE_CHAIN (u) = list; - list = u; + if (ort == C_ORT_ACC + && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA) + && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) + decl = error_mark_node; + + if (decl != error_mark_node) + { + tree u = build_omp_clause (token->location, kind); + OMP_CLAUSE_DECL (u) = decl; + OMP_CLAUSE_CHAIN (u) = list; + list = u; + } } else list = tree_cons (decl, NULL_TREE, list); @@ -33442,7 +33452,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; @@ -33452,7 +33462,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)) @@ -33553,8 +33563,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; @@ -34798,7 +34807,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: @@ -34948,7 +34957,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: @@ -34992,7 +35001,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: @@ -35009,7 +35018,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 c1240cc..fc63e3c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -6055,6 +6055,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); @@ -6069,10 +6070,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) @@ -6089,6 +6095,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: diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 261a54a..ffa04e6 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -5843,6 +5843,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 bf3f469..fbe0d3c 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -564,7 +564,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)