aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2019-06-10 14:20:30 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-06-10 14:20:30 +0200
commitbf38f7e9aa76856a7c8ac57988600ce9de7cafbd (patch)
tree9e298ccc80525cad1ce63b382a393a876b5071aa /gcc/cp
parent07ca30a0d76c970bbf59a4bce04be41fa297d213 (diff)
downloadgcc-bf38f7e9aa76856a7c8ac57988600ce9de7cafbd.zip
gcc-bf38f7e9aa76856a7c8ac57988600ce9de7cafbd.tar.gz
gcc-bf38f7e9aa76856a7c8ac57988600ce9de7cafbd.tar.bz2
tree.def (OMP_SCAN): New tree code.
* tree.def (OMP_SCAN): New tree code. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_INCLUSIVE and OMP_CLAUSE_EXCLUSIVE. * tree.h (OMP_CLAUSES): Use OMP_SCAN instead of OMP_TASKGROUP. (OMP_SCAN_BODY, OMP_SCAN_CLAUSES): Define. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add entries for OMP_CLAUSE_{IN,EX}CLUSIVE. (walk_tree_1): Handle OMP_CLAUSE_{IN,EX}CLUSIVE. * tree-nested.c (convert_nonlocal_reference_stmt, convert_local_reference_stmt, convert_gimple_call): Handle GIMPLE_OMP_SCAN. * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_{IN,EX}CLUSIVE. (dump_generic_node): Handle OMP_SCAN. * gimple.def (GIMPLE_OMP_SCAN): New gimple code. * gimple.h (gomp_scan): New type. (is_a_helper <gomp_scan *>::test, is_a_helper <const gomp_scan *>::test): New templates. (gimple_build_omp_scan): Declare. (gimple_omp_scan_clauses, gimple_omp_scan_clauses_ptr, gimple_omp_scan_set_clauses): New inline functions. (CASE_GIMPLE_OMP): Add case GIMPLE_OMP_SCAN:. * gimple.c (gimple_build_omp_scan): New function. (gimple_copy): Handle GIMPLE_OMP_SCAN. * gimple-walk.c (walk_gimple_op, walk_gimple_stmt): Likewise. * gimple-pretty-print.c (dump_gimple_omp_block): Don't handle GIMPLE_OMP_TASKGROUP. (dump_gimple_omp_scan): New function. (pp_gimple_stmt_1): Handle GIMPLE_OMP_SCAN. * gimple-low.c (lower_stmt): Handle GIMPLE_OMP_SCAN. * tree-inline.c (remap_gimple_stmt, estimate_num_insns): Likewise. * gimplify.c (enum gimplify_omp_var_data): Add GOVD_REDUCTION_INSCAN. (is_gimple_stmt): Handle OMP_SCAN. (gimplify_scan_omp_clauses): Reject inscan reductions on constructs other than OMP_FOR or OMP_SIMD. Handle OMP_CLAUSE_{IN,EX}CLUSIVE. (gimplify_adjust_omp_clauses): Diagnose inscan reductions not mentioned in nested #pragma omp scan. Handle OMP_CLAUSE_{IN,EX}CLUSIVE. (gimplify_expr): Handle OMP_SCAN. * omp-low.c (check_omp_nesting_restrictions): For parent context, look through GIMPLE_OMP_SCAN context. Allow #pragma omp scan in simd constructs. (scan_omp_1_stmt, lower_omp_1, diagnose_sb_1, diagnose_sb_2): Handle GIMPLE_OMP_SCAN. c-family/ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_SCAN. * c-pragma.c (omp_pragmas_simd): Add #pragma omp scan. * c-omp.c (c_omp_split_clauses): Diagnose inscan reductions on combined/composite constructs where it is not allowed. Copy over OMP_CLAUSE_REDUCTION_INSCAN. c/ * c-parser.c (c_parser_pragma): Reject PRAGMA_OMP_SCAN. (c_parser_omp_clause_reduction): Don't sorry_at on inscan reductions. (c_parser_omp_scan_loop_body): New function. (c_parser_omp_for_loop): Call c_parser_omp_scan_loop_body if there are inscan reduction clauses. * c-typeck.c (c_finish_omp_clauses): Reject mixing inscan with non-inscan reductions on the same construct, or inscan reductions with ordered or schedule clauses, or inscan array reductions. cp/ * parser.c (cp_parser_omp_clause_reduction): Don't sorry_at on inscan reductions. (cp_parser_omp_scan_loop_body): New function. (cp_parser_omp_for_loop): Call cp_parser_omp_scan_loop_body if there are inscan reduction clauses. (cp_parser_pragma): Reject PRAGMA_OMP_SCAN. * semantics.c (finish_omp_clauses): Reject mixing inscan with non-inscan reductions on the same construct, or inscan reductions with ordered or schedule clauses, or inscan array reductions. * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_{IN,EX}CLUSIVE. (tsubst_expr): Handle OMP_SCAN. testsuite/ * c-c++-common/gomp/scan-1.c: New test. * c-c++-common/gomp/scan-2.c: New test. * c-c++-common/gomp/scan-3.c: New test. * c-c++-common/gomp/scan-4.c: New test. From-SVN: r272117
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/parser.c79
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/semantics.c79
4 files changed, 169 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c072040..188752c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2019-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_clause_reduction): Don't sorry_at on inscan
+ reductions.
+ (cp_parser_omp_scan_loop_body): New function.
+ (cp_parser_omp_for_loop): Call cp_parser_omp_scan_loop_body if there
+ are inscan reduction clauses.
+ (cp_parser_pragma): Reject PRAGMA_OMP_SCAN.
+ * semantics.c (finish_omp_clauses): Reject mixing inscan with
+ non-inscan reductions on the same construct, or inscan reductions with
+ ordered or schedule clauses, or inscan array reductions.
+ * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_{IN,EX}CLUSIVE.
+ (tsubst_expr): Handle OMP_SCAN.
+
2019-06-07 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_constant_expression): Call
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 308b2d4a..e699fbc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -33773,11 +33773,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
if (strcmp (p, "task") == 0)
task = true;
else if (strcmp (p, "inscan") == 0)
- {
- inscan = true;
- sorry ("%<inscan%> modifier on %<reduction%> clause "
- "not supported yet");
- }
+ inscan = true;
if (task || inscan)
{
cp_lexer_consume_token (parser->lexer);
@@ -36820,6 +36816,63 @@ cp_finish_omp_range_for (tree orig, tree begin)
cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
}
+/* OpenMP 5.0:
+
+ scan-loop-body:
+ { structured-block scan-directive structured-block } */
+
+static void
+cp_parser_omp_scan_loop_body (cp_parser *parser)
+{
+ tree substmt, clauses = NULL_TREE;
+
+ matching_braces braces;
+ if (!braces.require_open (parser))
+ return;
+
+ substmt = cp_parser_omp_structured_block (parser, NULL);
+ substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
+ add_stmt (substmt);
+
+ cp_token *tok = cp_lexer_peek_token (parser->lexer);
+ if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SCAN)
+ {
+ enum omp_clause_code clause = OMP_CLAUSE_ERROR;
+
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "inclusive") == 0)
+ clause = OMP_CLAUSE_INCLUSIVE;
+ else if (strcmp (p, "exclusive") == 0)
+ clause = OMP_CLAUSE_EXCLUSIVE;
+ }
+ if (clause != OMP_CLAUSE_ERROR)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ clauses = cp_parser_omp_var_list (parser, clause, NULL_TREE);
+ }
+ else
+ cp_parser_error (parser, "expected %<inclusive%> or "
+ "%<exclusive%> clause");
+
+ cp_parser_require_pragma_eol (parser, tok);
+ }
+ else
+ error ("expected %<#pragma omp scan%>");
+
+ clauses = finish_omp_clauses (clauses, C_ORT_OMP);
+ substmt = cp_parser_omp_structured_block (parser, NULL);
+ substmt = build2_loc (tok->location, OMP_SCAN, void_type_node, substmt,
+ clauses);
+ add_stmt (substmt);
+
+ braces.require_close (parser);
+}
+
/* Parse the restricted form of the for statement allowed by OpenMP. */
static tree
@@ -36836,6 +36889,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
releasing_vec for_block;
auto_vec<tree, 4> orig_inits;
bool tiling = false;
+ bool inscan = false;
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
@@ -36851,6 +36905,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
ordered_cl = cl;
ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
}
+ else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_REDUCTION_INSCAN (cl)
+ && (code == OMP_SIMD || code == OMP_FOR))
+ inscan = true;
if (ordered && ordered < collapse)
{
@@ -37179,7 +37237,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
}
else
body = push_stmt_list ();
- cp_parser_statement (parser, NULL_TREE, false, if_p);
+ if (inscan)
+ cp_parser_omp_scan_loop_body (parser);
+ else
+ cp_parser_statement (parser, NULL_TREE, false, if_p);
if (orig_declv)
body = finish_omp_structured_block (body);
else
@@ -41044,6 +41105,12 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
cp_parser_omp_end_declare_target (parser, pragma_tok);
return false;
+ case PRAGMA_OMP_SCAN:
+ error_at (pragma_tok->location,
+ "%<#pragma omp scan%> may only be used in "
+ "a loop construct with %<inscan%> %<reduction%> clause");
+ break;
+
case PRAGMA_OMP_SECTION:
error_at (pragma_tok->location,
"%<#pragma omp section%> may only be used in "
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d2cf345..ebaab27 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16323,6 +16323,8 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_NONTEMPORAL:
case OMP_CLAUSE_USE_DEVICE_PTR:
case OMP_CLAUSE_IS_DEVICE_PTR:
+ case OMP_CLAUSE_INCLUSIVE:
+ case OMP_CLAUSE_EXCLUSIVE:
OMP_CLAUSE_DECL (nc)
= tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain,
in_decl, iterator_cache);
@@ -16443,6 +16445,8 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_TASK_REDUCTION:
case OMP_CLAUSE_USE_DEVICE_PTR:
case OMP_CLAUSE_IS_DEVICE_PTR:
+ case OMP_CLAUSE_INCLUSIVE:
+ case OMP_CLAUSE_EXCLUSIVE:
/* tsubst_expr on SCOPE_REF results in returning
finish_non_static_data_member result. Undo that here. */
if (TREE_CODE (OMP_CLAUSE_DECL (oc)) == SCOPE_REF
@@ -17639,6 +17643,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_TEAMS:
case OMP_CRITICAL:
case OMP_TASKGROUP:
+ case OMP_SCAN:
r = push_omp_privatization_clauses (TREE_CODE (t) == OMP_TEAMS
&& OMP_TEAMS_COMBINED (t));
tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_OMP, args, complain,
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fc5edde..8e354a2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -6126,10 +6126,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
bool branch_seen = false;
bool copyprivate_seen = false;
bool ordered_seen = false;
+ bool schedule_seen = false;
bool oacc_async = false;
tree last_iterators = NULL_TREE;
bool last_iterators_remove = false;
- bool reduction_seen = false;
+ /* 1 if normal/task reduction has been seen, -1 if inscan reduction
+ has been seen, -2 if mixed inscan/normal reduction diagnosed. */
+ int reduction_seen = 0;
bitmap_obstack_initialize (NULL);
bitmap_initialize (&generic_head, &bitmap_default_obstack);
@@ -6164,7 +6167,17 @@ 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:
- reduction_seen = true;
+ if (reduction_seen == 0)
+ reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1;
+ else if (reduction_seen != -2
+ && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c)
+ ? -1 : 1))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<inscan%> and non-%<inscan%> %<reduction%> clauses "
+ "on the same construct");
+ reduction_seen = -2;
+ }
/* FALLTHRU */
case OMP_CLAUSE_IN_REDUCTION:
case OMP_CLAUSE_TASK_REDUCTION:
@@ -6177,6 +6190,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
remove = true;
break;
}
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_REDUCTION_INSCAN (c))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<inscan%> %<reduction%> clause with array "
+ "section");
+ remove = true;
+ break;
+ }
if (TREE_CODE (t) == TREE_LIST)
{
while (TREE_CODE (t) == TREE_LIST)
@@ -6684,6 +6706,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
}
+ if (!remove)
+ schedule_seen = true;
break;
case OMP_CLAUSE_SIMDLEN:
@@ -7583,6 +7607,37 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
branch_seen = true;
break;
+ case OMP_CLAUSE_INCLUSIVE:
+ case OMP_CLAUSE_EXCLUSIVE:
+ t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
+ if (!t)
+ t = OMP_CLAUSE_DECL (c);
+ if (t == current_class_ptr)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<this%> allowed in OpenMP only in %<declare simd%>"
+ " clauses");
+ remove = true;
+ break;
+ }
+ if (!VAR_P (t)
+ && TREE_CODE (t) != PARM_DECL
+ && TREE_CODE (t) != FIELD_DECL)
+ {
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
+ break;
+ if (DECL_P (t))
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD is not a variable in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ else
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is not a variable in clause %qs", t,
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ break;
+
default:
gcc_unreachable ();
}
@@ -7593,6 +7648,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
pc = &OMP_CLAUSE_CHAIN (c);
}
+ if (reduction_seen < 0 && (ordered_seen || schedule_seen))
+ reduction_seen = -2;
+
for (pc = &clauses, c = clauses; c ; c = *pc)
{
enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
@@ -7628,8 +7686,14 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
need_implicitly_determined = true;
break;
case OMP_CLAUSE_REDUCTION:
+ if (reduction_seen == -2)
+ OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
+ need_implicitly_determined = true;
+ break;
case OMP_CLAUSE_IN_REDUCTION:
case OMP_CLAUSE_TASK_REDUCTION:
+ case OMP_CLAUSE_INCLUSIVE:
+ case OMP_CLAUSE_EXCLUSIVE:
need_implicitly_determined = true;
break;
case OMP_CLAUSE_LINEAR:
@@ -7680,6 +7744,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
(OMP_CLAUSE_SCHEDULE_KIND (c)
& ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
}
+ if (reduction_seen == -2)
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs clause specified together with %<inscan%> "
+ "%<reduction%> clause", "schedule");
pc = &OMP_CLAUSE_CHAIN (c);
continue;
case OMP_CLAUSE_NOGROUP:
@@ -7693,6 +7761,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
}
pc = &OMP_CLAUSE_CHAIN (c);
continue;
+ case OMP_CLAUSE_ORDERED:
+ if (reduction_seen == -2)
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs clause specified together with %<inscan%> "
+ "%<reduction%> clause", "ordered");
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
case OMP_CLAUSE_NOWAIT:
if (copyprivate_seen)
{