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
This commit is contained in:
parent
07ca30a0d7
commit
bf38f7e9aa
32 changed files with 957 additions and 30 deletions
|
@ -1,8 +1,55 @@
|
|||
2019-06-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-06-10 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* ipa-cp.c (ignore_edge_p): New function.
|
||||
(build_toporder_info): Use it.
|
||||
* ipa-inline.c (ignore_edge_p): New function/
|
||||
* ipa-inline.c (ignore_edge_p): New function.
|
||||
(inline_small_functions): Use it.
|
||||
* ipa-pure-const.c (ignore_edge_for_nothrow):
|
||||
Verify opt_for_fn for caller and callee.
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2019-06-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-06-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
* c-attribs.c (handle_mode_attribute): Adjust quoting and hyphenation.
|
||||
|
|
|
@ -1659,6 +1659,18 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
|
|||
OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
|
||||
}
|
||||
}
|
||||
if (OMP_CLAUSE_REDUCTION_INSCAN (clauses)
|
||||
&& ((mask & ((OMP_CLAUSE_MASK_1
|
||||
<< PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)
|
||||
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)))
|
||||
!= 0))
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (clauses),
|
||||
"%<inscan%> %<reduction%> clause on construct other "
|
||||
"than %<for%>, %<simd%>, %<for simd%>, "
|
||||
"%<parallel for%>, %<parallel for simd%>");
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (clauses) = 0;
|
||||
}
|
||||
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
|
||||
{
|
||||
if (code == OMP_SIMD)
|
||||
|
@ -1672,6 +1684,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
|
|||
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
|
||||
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
|
||||
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c)
|
||||
= OMP_CLAUSE_REDUCTION_INSCAN (clauses);
|
||||
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
|
||||
cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
|
||||
}
|
||||
|
@ -1687,6 +1701,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
|
|||
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
|
||||
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
|
||||
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c)
|
||||
= OMP_CLAUSE_REDUCTION_INSCAN (clauses);
|
||||
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
|
||||
cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
|
||||
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
|
||||
|
@ -1717,6 +1733,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
|
|||
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
|
||||
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
|
||||
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c)
|
||||
= OMP_CLAUSE_REDUCTION_INSCAN (clauses);
|
||||
OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
|
||||
cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
|
||||
}
|
||||
|
|
|
@ -1320,6 +1320,7 @@ static const struct omp_pragma_def omp_pragmas_simd[] = {
|
|||
{ "for", PRAGMA_OMP_FOR },
|
||||
{ "ordered", PRAGMA_OMP_ORDERED },
|
||||
{ "parallel", PRAGMA_OMP_PARALLEL },
|
||||
{ "scan", PRAGMA_OMP_SCAN },
|
||||
{ "simd", PRAGMA_OMP_SIMD },
|
||||
{ "target", PRAGMA_OMP_TARGET },
|
||||
{ "taskloop", PRAGMA_OMP_TASKLOOP },
|
||||
|
|
|
@ -56,6 +56,7 @@ enum pragma_kind {
|
|||
PRAGMA_OMP_ORDERED,
|
||||
PRAGMA_OMP_PARALLEL,
|
||||
PRAGMA_OMP_REQUIRES,
|
||||
PRAGMA_OMP_SCAN,
|
||||
PRAGMA_OMP_SECTION,
|
||||
PRAGMA_OMP_SECTIONS,
|
||||
PRAGMA_OMP_SIMD,
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2019-06-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-06-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/90737
|
||||
|
|
|
@ -11494,6 +11494,13 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
|
|||
c_parser_omp_end_declare_target (parser);
|
||||
return false;
|
||||
|
||||
case PRAGMA_OMP_SCAN:
|
||||
error_at (c_parser_peek_token (parser)->location,
|
||||
"%<#pragma omp scan%> may only be used in "
|
||||
"a loop construct with %<inscan%> %<reduction%> clause");
|
||||
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
|
||||
return false;
|
||||
|
||||
case PRAGMA_OMP_SECTION:
|
||||
error_at (c_parser_peek_token (parser)->location,
|
||||
"%<#pragma omp section%> may only be used in "
|
||||
|
@ -13558,11 +13565,7 @@ c_parser_omp_clause_reduction (c_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)
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
|
@ -16738,6 +16741,71 @@ c_parser_omp_flush (c_parser *parser)
|
|||
c_finish_omp_flush (loc, mo);
|
||||
}
|
||||
|
||||
/* OpenMP 5.0:
|
||||
|
||||
scan-loop-body:
|
||||
{ structured-block scan-directive structured-block } */
|
||||
|
||||
static void
|
||||
c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
|
||||
{
|
||||
tree substmt;
|
||||
location_t loc;
|
||||
tree clauses = NULL_TREE;
|
||||
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
if (!open_brace_parsed
|
||||
&& !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
|
||||
{
|
||||
/* Avoid skipping until the end of the block. */
|
||||
parser->error = false;
|
||||
return;
|
||||
}
|
||||
|
||||
substmt = c_parser_omp_structured_block (parser, NULL);
|
||||
substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
|
||||
SET_EXPR_LOCATION (substmt, loc);
|
||||
add_stmt (substmt);
|
||||
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
|
||||
{
|
||||
enum omp_clause_code clause = OMP_CLAUSE_ERROR;
|
||||
|
||||
c_parser_consume_pragma (parser);
|
||||
|
||||
if (c_parser_next_token_is (parser, CPP_NAME))
|
||||
{
|
||||
const char *p
|
||||
= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
|
||||
if (strcmp (p, "inclusive") == 0)
|
||||
clause = OMP_CLAUSE_INCLUSIVE;
|
||||
else if (strcmp (p, "exclusive") == 0)
|
||||
clause = OMP_CLAUSE_EXCLUSIVE;
|
||||
}
|
||||
if (clause != OMP_CLAUSE_ERROR)
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
|
||||
}
|
||||
else
|
||||
c_parser_error (parser, "expected %<inclusive%> or "
|
||||
"%<exclusive%> clause");
|
||||
c_parser_skip_to_pragma_eol (parser);
|
||||
}
|
||||
else
|
||||
error ("expected %<#pragma omp scan%>");
|
||||
|
||||
clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
|
||||
substmt = c_parser_omp_structured_block (parser, NULL);
|
||||
substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
|
||||
SET_EXPR_LOCATION (substmt, loc);
|
||||
add_stmt (substmt);
|
||||
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
|
||||
"expected %<}%>");
|
||||
}
|
||||
|
||||
/* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
|
||||
The real trick here is to determine the loop control variable early
|
||||
so that we can push a new decl if necessary to make it private.
|
||||
|
@ -16756,6 +16824,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
|
|||
int i, collapse = 1, ordered = 0, count, nbraces = 0;
|
||||
location_t for_loc;
|
||||
bool tiling = false;
|
||||
bool inscan = false;
|
||||
vec<tree, va_gc> *for_block = make_tree_vector ();
|
||||
|
||||
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
|
||||
|
@ -16772,6 +16841,10 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
|
|||
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)
|
||||
{
|
||||
|
@ -16992,7 +17065,9 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
|
|||
c_cont_label = NULL_TREE;
|
||||
body = push_stmt_list ();
|
||||
|
||||
if (open_brace_parsed)
|
||||
if (inscan)
|
||||
c_parser_omp_scan_loop_body (parser, open_brace_parsed);
|
||||
else if (open_brace_parsed)
|
||||
{
|
||||
location_t here = c_parser_peek_token (parser)->location;
|
||||
stmt = c_begin_compound_stmt (true);
|
||||
|
|
|
@ -13661,13 +13661,15 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
bool copyprivate_seen = false;
|
||||
bool linear_variable_step_check = false;
|
||||
tree *nowait_clause = NULL;
|
||||
bool ordered_seen = false;
|
||||
tree ordered_clause = NULL_TREE;
|
||||
tree schedule_clause = NULL_TREE;
|
||||
bool oacc_async = false;
|
||||
tree last_iterators = NULL_TREE;
|
||||
bool last_iterators_remove = false;
|
||||
tree *nogroup_seen = NULL;
|
||||
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);
|
||||
|
@ -13706,7 +13708,17 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
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:
|
||||
|
@ -13721,6 +13733,15 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
}
|
||||
|
||||
t = OMP_CLAUSE_DECL (c);
|
||||
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;
|
||||
}
|
||||
}
|
||||
t = require_complete_type (OMP_CLAUSE_LOCATION (c), t);
|
||||
if (t == error_mark_node)
|
||||
|
@ -14661,7 +14682,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
continue;
|
||||
|
||||
case OMP_CLAUSE_ORDERED:
|
||||
ordered_seen = true;
|
||||
ordered_clause = c;
|
||||
pc = &OMP_CLAUSE_CHAIN (c);
|
||||
continue;
|
||||
|
||||
|
@ -14688,6 +14709,20 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
pc = &OMP_CLAUSE_CHAIN (c);
|
||||
continue;
|
||||
|
||||
case OMP_CLAUSE_INCLUSIVE:
|
||||
case OMP_CLAUSE_EXCLUSIVE:
|
||||
need_complete = true;
|
||||
need_implicitly_determined = true;
|
||||
t = OMP_CLAUSE_DECL (c);
|
||||
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
|
||||
{
|
||||
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 ();
|
||||
}
|
||||
|
@ -14760,7 +14795,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
= OMP_CLAUSE_SAFELEN_EXPR (safelen);
|
||||
}
|
||||
|
||||
if (ordered_seen
|
||||
if (ordered_clause
|
||||
&& schedule_clause
|
||||
&& (OMP_CLAUSE_SCHEDULE_KIND (schedule_clause)
|
||||
& OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
|
||||
|
@ -14774,7 +14809,23 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
& ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
|
||||
}
|
||||
|
||||
if (linear_variable_step_check)
|
||||
if (reduction_seen < 0 && ordered_clause)
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (ordered_clause),
|
||||
"%qs clause specified together with %<inscan%> "
|
||||
"%<reduction%> clause", "ordered");
|
||||
reduction_seen = -2;
|
||||
}
|
||||
|
||||
if (reduction_seen < 0 && schedule_clause)
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (schedule_clause),
|
||||
"%qs clause specified together with %<inscan%> "
|
||||
"%<reduction%> clause", "schedule");
|
||||
reduction_seen = -2;
|
||||
}
|
||||
|
||||
if (linear_variable_step_check || reduction_seen == -2)
|
||||
for (pc = &clauses, c = clauses; c ; c = *pc)
|
||||
{
|
||||
bool remove = false;
|
||||
|
@ -14789,6 +14840,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
OMP_CLAUSE_LINEAR_STEP (c));
|
||||
remove = true;
|
||||
}
|
||||
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
|
||||
|
||||
if (remove)
|
||||
*pc = OMP_CLAUSE_CHAIN (c);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -336,6 +336,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
|
|||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_TASKGROUP:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
case GIMPLE_OMP_RETURN:
|
||||
case GIMPLE_OMP_ATOMIC_LOAD:
|
||||
|
|
|
@ -1799,9 +1799,6 @@ dump_gimple_omp_block (pretty_printer *buffer, gimple *gs, int spc,
|
|||
case GIMPLE_OMP_MASTER:
|
||||
pp_string (buffer, "#pragma omp master");
|
||||
break;
|
||||
case GIMPLE_OMP_TASKGROUP:
|
||||
pp_string (buffer, "#pragma omp taskgroup");
|
||||
break;
|
||||
case GIMPLE_OMP_SECTION:
|
||||
pp_string (buffer, "#pragma omp section");
|
||||
break;
|
||||
|
@ -1880,6 +1877,34 @@ dump_gimple_omp_ordered (pretty_printer *buffer, gomp_ordered *gs,
|
|||
}
|
||||
}
|
||||
|
||||
/* Dump a GIMPLE_OMP_SCAN tuple on the pretty_printer BUFFER. */
|
||||
|
||||
static void
|
||||
dump_gimple_omp_scan (pretty_printer *buffer, gomp_scan *gs,
|
||||
int spc, dump_flags_t flags)
|
||||
{
|
||||
if (flags & TDF_RAW)
|
||||
dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
|
||||
gimple_omp_body (gs));
|
||||
else
|
||||
{
|
||||
if (gimple_omp_scan_clauses (gs))
|
||||
{
|
||||
pp_string (buffer, "#pragma omp scan");
|
||||
dump_omp_clauses (buffer, gimple_omp_scan_clauses (gs), spc, flags);
|
||||
}
|
||||
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
|
||||
{
|
||||
newline_and_indent (buffer, spc + 2);
|
||||
pp_left_brace (buffer);
|
||||
pp_newline (buffer);
|
||||
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
|
||||
newline_and_indent (buffer, spc + 2);
|
||||
pp_right_brace (buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump a GIMPLE_OMP_RETURN tuple on the pretty_printer BUFFER. */
|
||||
|
||||
static void
|
||||
|
@ -2652,6 +2677,11 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple *gs, int spc,
|
|||
flags);
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_SCAN:
|
||||
dump_gimple_omp_scan (buffer, as_a <gomp_scan *> (gs), spc,
|
||||
flags);
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
dump_gimple_omp_critical (buffer, as_a <gomp_critical *> (gs), spc,
|
||||
flags);
|
||||
|
|
|
@ -336,6 +336,16 @@ walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
|
|||
}
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_SCAN:
|
||||
{
|
||||
gomp_scan *scan_stmt = as_a <gomp_scan *> (stmt);
|
||||
ret = walk_tree (gimple_omp_scan_clauses_ptr (scan_stmt),
|
||||
callback_op, wi, pset);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_FOR:
|
||||
ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
|
||||
pset);
|
||||
|
@ -650,6 +660,7 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
|
|||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_TASKGROUP:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_SECTION:
|
||||
case GIMPLE_OMP_PARALLEL:
|
||||
case GIMPLE_OMP_TASK:
|
||||
|
|
25
gcc/gimple.c
25
gcc/gimple.c
|
@ -1108,6 +1108,25 @@ gimple_build_omp_return (bool wait_p)
|
|||
}
|
||||
|
||||
|
||||
/* Build a GIMPLE_OMP_SCAN statement.
|
||||
|
||||
BODY is the sequence of statements to be executed by the scan
|
||||
construct.
|
||||
CLAUSES are any of the construct's clauses. */
|
||||
|
||||
gomp_scan *
|
||||
gimple_build_omp_scan (gimple_seq body, tree clauses)
|
||||
{
|
||||
gomp_scan *p
|
||||
= as_a <gomp_scan *> (gimple_alloc (GIMPLE_OMP_SCAN, 0));
|
||||
gimple_omp_scan_set_clauses (p, clauses);
|
||||
if (body)
|
||||
gimple_omp_set_body (p, body);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Build a GIMPLE_OMP_SECTIONS statement.
|
||||
|
||||
BODY is a sequence of section statements.
|
||||
|
@ -1943,6 +1962,12 @@ gimple_copy (gimple *stmt)
|
|||
gimple_omp_ordered_set_clauses (as_a <gomp_ordered *> (copy), t);
|
||||
goto copy_omp_body;
|
||||
|
||||
case GIMPLE_OMP_SCAN:
|
||||
t = gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt));
|
||||
t = unshare_expr (t);
|
||||
gimple_omp_scan_set_clauses (as_a <gomp_scan *> (copy), t);
|
||||
goto copy_omp_body;
|
||||
|
||||
case GIMPLE_OMP_TASKGROUP:
|
||||
t = unshare_expr (gimple_omp_taskgroup_clauses (stmt));
|
||||
gimple_omp_taskgroup_set_clauses (copy, t);
|
||||
|
|
|
@ -331,6 +331,11 @@ DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK)
|
|||
/* OMP_RETURN marks the end of an OpenMP directive. */
|
||||
DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_OMP_ATOMIC_STORE_LAYOUT)
|
||||
|
||||
/* GIMPLE_OMP_SCAN <BODY, CLAUSES> represents #pragma omp scan
|
||||
BODY is the sequence of statements inside the single section.
|
||||
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
|
||||
DEFGSCODE(GIMPLE_OMP_SCAN, "gimple_omp_scan", GSS_OMP_SINGLE_LAYOUT)
|
||||
|
||||
/* OMP_SECTION <BODY> represents #pragma omp section.
|
||||
BODY is the sequence of statements in the section body. */
|
||||
DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
|
||||
|
|
57
gcc/gimple.h
57
gcc/gimple.h
|
@ -741,7 +741,8 @@ struct GTY((tag("GSS_OMP_CONTINUE")))
|
|||
tree control_use;
|
||||
};
|
||||
|
||||
/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_ORDERED, GIMPLE_OMP_TASKGROUP. */
|
||||
/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_ORDERED, GIMPLE_OMP_TASKGROUP,
|
||||
GIMPLE_OMP_SCAN. */
|
||||
|
||||
struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
|
||||
gimple_statement_omp_single_layout : public gimple_statement_omp
|
||||
|
@ -773,6 +774,13 @@ struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
|
|||
stmt->code == GIMPLE_OMP_ORDERED. */
|
||||
};
|
||||
|
||||
struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
|
||||
gomp_scan : public gimple_statement_omp_single_layout
|
||||
{
|
||||
/* No extra fields; adds invariant:
|
||||
stmt->code == GIMPLE_OMP_SCAN. */
|
||||
};
|
||||
|
||||
|
||||
/* GIMPLE_OMP_ATOMIC_LOAD.
|
||||
Note: This is based on gimple, not g_s_omp, because g_s_omp
|
||||
|
@ -1112,6 +1120,14 @@ is_a_helper <gomp_ordered *>::test (gimple *gs)
|
|||
return gs->code == GIMPLE_OMP_ORDERED;
|
||||
}
|
||||
|
||||
template <>
|
||||
template <>
|
||||
inline bool
|
||||
is_a_helper <gomp_scan *>::test (gimple *gs)
|
||||
{
|
||||
return gs->code == GIMPLE_OMP_SCAN;
|
||||
}
|
||||
|
||||
template <>
|
||||
template <>
|
||||
inline bool
|
||||
|
@ -1330,6 +1346,14 @@ is_a_helper <const gomp_ordered *>::test (const gimple *gs)
|
|||
return gs->code == GIMPLE_OMP_ORDERED;
|
||||
}
|
||||
|
||||
template <>
|
||||
template <>
|
||||
inline bool
|
||||
is_a_helper <const gomp_scan *>::test (const gimple *gs)
|
||||
{
|
||||
return gs->code == GIMPLE_OMP_SCAN;
|
||||
}
|
||||
|
||||
template <>
|
||||
template <>
|
||||
inline bool
|
||||
|
@ -1475,6 +1499,7 @@ gimple *gimple_build_omp_taskgroup (gimple_seq, tree);
|
|||
gomp_continue *gimple_build_omp_continue (tree, tree);
|
||||
gomp_ordered *gimple_build_omp_ordered (gimple_seq, tree);
|
||||
gimple *gimple_build_omp_return (bool);
|
||||
gomp_scan *gimple_build_omp_scan (gimple_seq, tree);
|
||||
gomp_sections *gimple_build_omp_sections (gimple_seq, tree);
|
||||
gimple *gimple_build_omp_sections_switch (void);
|
||||
gomp_single *gimple_build_omp_single (gimple_seq, tree);
|
||||
|
@ -4946,6 +4971,35 @@ gimple_omp_ordered_set_clauses (gomp_ordered *ord_stmt, tree clauses)
|
|||
}
|
||||
|
||||
|
||||
/* Return the clauses associated with OMP_SCAN statement SCAN_STMT. */
|
||||
|
||||
static inline tree
|
||||
gimple_omp_scan_clauses (const gomp_scan *scan_stmt)
|
||||
{
|
||||
return scan_stmt->clauses;
|
||||
}
|
||||
|
||||
|
||||
/* Return a pointer to the clauses associated with OMP scan statement
|
||||
ORD_STMT. */
|
||||
|
||||
static inline tree *
|
||||
gimple_omp_scan_clauses_ptr (gomp_scan *scan_stmt)
|
||||
{
|
||||
return &scan_stmt->clauses;
|
||||
}
|
||||
|
||||
|
||||
/* Set CLAUSES to be the clauses associated with OMP scan statement
|
||||
ORD_STMT. */
|
||||
|
||||
static inline void
|
||||
gimple_omp_scan_set_clauses (gomp_scan *scan_stmt, tree clauses)
|
||||
{
|
||||
scan_stmt->clauses = clauses;
|
||||
}
|
||||
|
||||
|
||||
/* Return the clauses associated with OMP_TASKGROUP statement GS. */
|
||||
|
||||
static inline tree
|
||||
|
@ -6379,6 +6433,7 @@ gimple_return_set_retval (greturn *gs, tree retval)
|
|||
case GIMPLE_OMP_TASKGROUP: \
|
||||
case GIMPLE_OMP_ORDERED: \
|
||||
case GIMPLE_OMP_CRITICAL: \
|
||||
case GIMPLE_OMP_SCAN: \
|
||||
case GIMPLE_OMP_RETURN: \
|
||||
case GIMPLE_OMP_ATOMIC_LOAD: \
|
||||
case GIMPLE_OMP_ATOMIC_STORE: \
|
||||
|
|
109
gcc/gimplify.c
109
gcc/gimplify.c
|
@ -118,6 +118,9 @@ enum gimplify_omp_var_data
|
|||
|
||||
GOVD_CONDTEMP = 0x1000000,
|
||||
|
||||
/* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause. */
|
||||
GOVD_REDUCTION_INSCAN = 0x2000000,
|
||||
|
||||
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
|
||||
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
|
||||
| GOVD_LOCAL)
|
||||
|
@ -5492,6 +5495,7 @@ is_gimple_stmt (tree t)
|
|||
case OMP_SIMD:
|
||||
case OMP_DISTRIBUTE:
|
||||
case OACC_LOOP:
|
||||
case OMP_SCAN:
|
||||
case OMP_SECTIONS:
|
||||
case OMP_SECTION:
|
||||
case OMP_SINGLE:
|
||||
|
@ -8119,13 +8123,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
|
|||
case OMP_DISTRIBUTE:
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"conditional %<lastprivate%> clause on "
|
||||
"%<distribute%> construct");
|
||||
"%qs construct", "distribute");
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
|
||||
break;
|
||||
case OMP_TASKLOOP:
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"conditional %<lastprivate%> clause on "
|
||||
"%<taskloop%> construct");
|
||||
"%qs construct", "taskloop");
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -8242,6 +8246,36 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
|
|||
OMP_CLAUSE_REDUCTION_TASK (c) = 0;
|
||||
}
|
||||
}
|
||||
if (OMP_CLAUSE_REDUCTION_INSCAN (c))
|
||||
switch (code)
|
||||
{
|
||||
case OMP_SECTIONS:
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<inscan%> %<reduction%> clause on "
|
||||
"%qs construct", "sections");
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
|
||||
break;
|
||||
case OMP_PARALLEL:
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<inscan%> %<reduction%> clause on "
|
||||
"%qs construct", "parallel");
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
|
||||
break;
|
||||
case OMP_TEAMS:
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<inscan%> %<reduction%> clause on "
|
||||
"%qs construct", "teams");
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
|
||||
break;
|
||||
case OMP_TASKLOOP:
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<inscan%> %<reduction%> clause on "
|
||||
"%qs construct", "taskloop");
|
||||
OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case OMP_CLAUSE_IN_REDUCTION:
|
||||
case OMP_CLAUSE_TASK_REDUCTION:
|
||||
|
@ -9290,6 +9324,36 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
|
|||
ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
|
||||
break;
|
||||
|
||||
case OMP_CLAUSE_INCLUSIVE:
|
||||
case OMP_CLAUSE_EXCLUSIVE:
|
||||
decl = OMP_CLAUSE_DECL (c);
|
||||
{
|
||||
splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
|
||||
(splay_tree_key) decl);
|
||||
if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%qD specified in %qs clause but not in %<inscan%> "
|
||||
"%<reduction%> clause on the containing construct",
|
||||
decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
|
||||
remove = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
n->value |= GOVD_REDUCTION_INSCAN;
|
||||
if (outer_ctx->region_type == ORT_SIMD
|
||||
&& outer_ctx->outer_context
|
||||
&& outer_ctx->outer_context->region_type == ORT_WORKSHARE)
|
||||
{
|
||||
n = splay_tree_lookup (outer_ctx->outer_context->variables,
|
||||
(splay_tree_key) decl);
|
||||
if (n && (n->value & GOVD_REDUCTION) != 0)
|
||||
n->value |= GOVD_REDUCTION_INSCAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -9683,7 +9747,9 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
|
|||
enum tree_code code)
|
||||
{
|
||||
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
|
||||
tree *orig_list_p = list_p;
|
||||
tree c, decl;
|
||||
bool has_inscan_reductions = false;
|
||||
|
||||
if (body)
|
||||
{
|
||||
|
@ -10024,6 +10090,21 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
|
|||
break;
|
||||
|
||||
case OMP_CLAUSE_REDUCTION:
|
||||
if (OMP_CLAUSE_REDUCTION_INSCAN (c))
|
||||
{
|
||||
decl = OMP_CLAUSE_DECL (c);
|
||||
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
|
||||
if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
|
||||
{
|
||||
remove = true;
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%qD specified in %<inscan%> %<reduction%> clause "
|
||||
"but not in %<scan%> directive clause", decl);
|
||||
break;
|
||||
}
|
||||
has_inscan_reductions = true;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case OMP_CLAUSE_IN_REDUCTION:
|
||||
case OMP_CLAUSE_TASK_REDUCTION:
|
||||
decl = OMP_CLAUSE_DECL (c);
|
||||
|
@ -10105,6 +10186,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
|
|||
case OMP_CLAUSE_TILE:
|
||||
case OMP_CLAUSE_IF_PRESENT:
|
||||
case OMP_CLAUSE_FINALIZE:
|
||||
case OMP_CLAUSE_INCLUSIVE:
|
||||
case OMP_CLAUSE_EXCLUSIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -10123,6 +10206,18 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
|
|||
data.pre_p = pre_p;
|
||||
splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
|
||||
|
||||
if (has_inscan_reductions)
|
||||
for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
|
||||
&& !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<inscan%> %<reduction%> clause used together with "
|
||||
"%<linear%> clause for a variable other than loop "
|
||||
"iterator");
|
||||
break;
|
||||
}
|
||||
|
||||
gimplify_omp_ctxp = ctx->outer_context;
|
||||
delete_omp_context (ctx);
|
||||
}
|
||||
|
@ -13124,6 +13219,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
case OMP_MASTER:
|
||||
case OMP_ORDERED:
|
||||
case OMP_CRITICAL:
|
||||
case OMP_SCAN:
|
||||
{
|
||||
gimple_seq body = NULL;
|
||||
gimple *g;
|
||||
|
@ -13150,6 +13246,14 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
OMP_CRITICAL_NAME (*expr_p),
|
||||
OMP_CRITICAL_CLAUSES (*expr_p));
|
||||
break;
|
||||
case OMP_SCAN:
|
||||
gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
|
||||
pre_p, ORT_WORKSHARE, OMP_SCAN);
|
||||
gimplify_adjust_omp_clauses (pre_p, body,
|
||||
&OMP_SCAN_CLAUSES (*expr_p),
|
||||
OMP_SCAN);
|
||||
g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -13514,6 +13618,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
|||
&& code != OMP_TASKGROUP
|
||||
&& code != OMP_ORDERED
|
||||
&& code != OMP_PARALLEL
|
||||
&& code != OMP_SCAN
|
||||
&& code != OMP_SECTIONS
|
||||
&& code != OMP_SECTION
|
||||
&& code != OMP_SINGLE);
|
||||
|
|
|
@ -2574,6 +2574,10 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
|
|||
|
||||
if (ctx != NULL)
|
||||
{
|
||||
if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN
|
||||
&& ctx->outer
|
||||
&& gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
|
||||
ctx = ctx->outer;
|
||||
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
|
||||
&& gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
|
||||
{
|
||||
|
@ -2600,7 +2604,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
|
|||
}
|
||||
}
|
||||
else if (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
|
||||
|| gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE)
|
||||
|| gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
|
||||
|| gimple_code (stmt) == GIMPLE_OMP_SCAN)
|
||||
return true;
|
||||
error_at (gimple_location (stmt),
|
||||
"OpenMP constructs other than %<#pragma omp ordered simd%>"
|
||||
|
@ -3328,6 +3333,7 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
|
|||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_GRID_BODY:
|
||||
ctx = new_omp_context (stmt, ctx);
|
||||
scan_omp (gimple_omp_body_ptr (stmt), ctx);
|
||||
|
@ -10834,6 +10840,15 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
gcc_assert (ctx);
|
||||
lower_omp_ordered (gsi_p, ctx);
|
||||
break;
|
||||
case GIMPLE_OMP_SCAN:
|
||||
ctx = maybe_lookup_ctx (stmt);
|
||||
gcc_assert (ctx);
|
||||
gsi_insert_seq_after (gsi_p, gimple_omp_body (stmt), GSI_SAME_STMT);
|
||||
if (gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)))
|
||||
sorry_at (gimple_location (stmt),
|
||||
"%<#pragma omp scan%> not supported yet");
|
||||
gsi_replace (gsi_p, gimple_build_nop (), true);
|
||||
break;
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
ctx = maybe_lookup_ctx (stmt);
|
||||
gcc_assert (ctx);
|
||||
|
@ -10925,6 +10940,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
|||
|| gimple_code (up->stmt) == GIMPLE_OMP_CRITICAL
|
||||
|| gimple_code (up->stmt) == GIMPLE_OMP_TASKGROUP
|
||||
|| gimple_code (up->stmt) == GIMPLE_OMP_SECTION
|
||||
|| gimple_code (up->stmt) == GIMPLE_OMP_SCAN
|
||||
|| (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
|
||||
&& (gimple_omp_target_kind (up->stmt)
|
||||
== GF_OMP_TARGET_KIND_DATA)))
|
||||
|
@ -11195,6 +11211,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
|
|||
case GIMPLE_OMP_SECTION:
|
||||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
case GIMPLE_OMP_TARGET:
|
||||
case GIMPLE_OMP_TEAMS:
|
||||
|
@ -11255,6 +11272,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
|
|||
case GIMPLE_OMP_SECTION:
|
||||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
case GIMPLE_OMP_TARGET:
|
||||
case GIMPLE_OMP_TEAMS:
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2019-06-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-06-10 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* gcc.dg/no_profile_instrument_function-attr-1.c: Fix
|
||||
|
|
209
gcc/testsuite/c-c++-common/gomp/scan-1.c
Normal file
209
gcc/testsuite/c-c++-common/gomp/scan-1.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
int a, b;
|
||||
|
||||
void
|
||||
f1 (void)
|
||||
{
|
||||
#pragma omp scan inclusive (a) /* { dg-error "'#pragma omp scan' may only be used in a loop construct with 'inscan' 'reduction' clause" } */
|
||||
#pragma omp scan exclusive (b) /* { dg-error "'#pragma omp scan' may only be used in a loop construct with 'inscan' 'reduction' clause" } */
|
||||
}
|
||||
|
||||
void
|
||||
f2 (int *c, int *d, int *e, int *f)
|
||||
{
|
||||
int i, l = 1;
|
||||
#pragma omp for reduction (inscan, +: a) reduction (+: b) /* { dg-error "'inscan' and non-'inscan' 'reduction' clauses on the same construct" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
{ b++; a += c[i]; }
|
||||
#pragma omp scan inclusive (a) /* { dg-error "" } */
|
||||
d[i] = a;
|
||||
}
|
||||
#pragma omp for reduction (+: a) reduction (inscan, +: b) /* { dg-error "'inscan' and non-'inscan' 'reduction' clauses on the same construct" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
{ a++; b += c[i]; }
|
||||
#pragma omp scan inclusive (b) /* { dg-error "" } */
|
||||
d[i] = b;
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: e[:2]) /* { dg-error "'inscan' 'reduction' clause with array section" } */
|
||||
for (i = 0; i < 64; ++i)
|
||||
{
|
||||
{ e[0] += c[i]; e[1] += c[i]; }
|
||||
#pragma omp scan inclusive (a, e[:2]) /* { dg-error "" } */
|
||||
{ d[i] = e[0]; f[i] = e[1]; }
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a) ordered /* { dg-error "'ordered' clause specified together with 'inscan' 'reduction' clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
a += c[i];
|
||||
#pragma omp scan inclusive (a) /* { dg-error "" } */
|
||||
d[i] = a;
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a) ordered(1) /* { dg-error "'ordered' clause specified together with 'inscan' 'reduction' clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
a += c[i];
|
||||
#pragma omp scan inclusive (a) /* { dg-error "" } */
|
||||
d[i] = a;
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a) schedule(static) /* { dg-error "'schedule' clause specified together with 'inscan' 'reduction' clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
a += c[i];
|
||||
#pragma omp scan inclusive (a) /* { dg-error "" } */
|
||||
d[i] = a;
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a) schedule(static, 2) /* { dg-error "'schedule' clause specified together with 'inscan' 'reduction' clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
a += c[i];
|
||||
#pragma omp scan inclusive (a) /* { dg-error "" } */
|
||||
d[i] = a;
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a) schedule(nonmonotonic: dynamic, 2) /* { dg-error "'schedule' clause specified together with 'inscan' 'reduction' clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
a += c[i];
|
||||
#pragma omp scan inclusive (a) /* { dg-error "" } */
|
||||
d[i] = a;
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a) linear (l) /* { dg-error "'inscan' 'reduction' clause used together with 'linear' clause for a variable other than loop iterator" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
{ a += c[i]; ++l; }
|
||||
#pragma omp scan inclusive (a)
|
||||
d[i] = a;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f3 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp teams reduction (inscan, +: a) /* { dg-error "'inscan' 'reduction' clause on 'teams' construct" } */
|
||||
;
|
||||
#pragma omp parallel reduction (inscan, +: a) /* { dg-error "'inscan' 'reduction' clause on 'parallel' construct" } */
|
||||
;
|
||||
#pragma omp sections reduction (inscan, +: a) /* { dg-error "'inscan' 'reduction' clause on 'sections' construct" } */
|
||||
{
|
||||
#pragma omp section
|
||||
;
|
||||
}
|
||||
#pragma omp target parallel for reduction (inscan, +: a) map (c[:64], d[:64]) /* { dg-error "'inscan' 'reduction' clause on construct other than 'for', 'simd', 'for simd', 'parallel for', 'parallel for simd'" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a) /* { dg-error "" } */
|
||||
a += c[i];
|
||||
}
|
||||
#pragma omp teams
|
||||
{
|
||||
#pragma omp distribute parallel for reduction (inscan, +: a) /* { dg-error "'inscan' 'reduction' clause on construct other than 'for', 'simd', 'for simd', 'parallel for', 'parallel for simd'" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a) /* { dg-error "" } */
|
||||
a += c[i];
|
||||
}
|
||||
#pragma omp distribute parallel for simd reduction (inscan, +: a) /* { dg-error "'inscan' 'reduction' clause on construct other than 'for', 'simd', 'for simd', 'parallel for', 'parallel for simd'" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a) /* { dg-error "" } */
|
||||
a += c[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f4 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp taskloop reduction (inscan, +: a) /* { dg-error "'inscan' 'reduction' clause on 'taskloop' construct" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a) /* { dg-error "" } */
|
||||
a += c[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f5 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd reduction (inscan, +: a)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a, b) /* { dg-error "'b' specified in 'exclusive' clause but not in 'inscan' 'reduction' clause on the containing construct" } */
|
||||
a += c[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f6 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd reduction (inscan, +: a, b) /* { dg-error "'b' specified in 'inscan' 'reduction' clause but not in 'scan' directive clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a)
|
||||
a += c[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f7 (void)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd reduction (inscan, +: a)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (i == 23) /* { dg-error "invalid exit from OpenMP structured block" "" { target c++ } .+1 } */
|
||||
continue; /* { dg-error "invalid branch to/from OpenMP structured block" "" { target c } } */
|
||||
else if (i == 27)
|
||||
goto l1; /* { dg-error "invalid branch to/from OpenMP structured block" } */
|
||||
#pragma omp scan exclusive (a)
|
||||
{
|
||||
l1: a = 0; /* { dg-error "jump to label 'l1'" "" { target c++ } } */
|
||||
if (i == 33) /* { dg-error "invalid exit from OpenMP structured block" "" { target c++ } .+1 } */
|
||||
continue; /* { dg-error "invalid branch to/from OpenMP structured block" "" { target c } } */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f8 (int *c, int *d, int *e, int *f)
|
||||
{
|
||||
int i;
|
||||
#pragma omp for reduction (inscan, +: a, b) /* { dg-error "'b' specified in 'inscan' 'reduction' clause but not in 'scan' directive clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
{ a += c[i]; b += d[i]; }
|
||||
#pragma omp scan inclusive (a) inclusive (b) /* { dg-error "expected end of line before 'inclusive'" } */
|
||||
{ e[i] = a; f[i] = b; }
|
||||
}
|
||||
#pragma omp for reduction (inscan, +: a, b) /* { dg-error "'.' specified in 'inscan' 'reduction' clause but not in 'scan' directive clause" } */
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
{ a += c[i]; b += d[i]; }
|
||||
#pragma omp scan /* { dg-error "expected 'inclusive' or 'exclusive' clause before end of line" } */
|
||||
{ e[i] = a; f[i] = b; }
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
f9 (void)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd reduction (inscan, +: a)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (i == 23) /* { dg-error "invalid exit from OpenMP structured block" "" { target c++ } .+1 } */
|
||||
break; /* { dg-error "break statement used with OpenMP for loop" "" { target c } } */
|
||||
#pragma omp scan exclusive (a)
|
||||
a++;
|
||||
}
|
||||
}
|
14
gcc/testsuite/c-c++-common/gomp/scan-2.c
Normal file
14
gcc/testsuite/c-c++-common/gomp/scan-2.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
int a, b;
|
||||
|
||||
void
|
||||
f1 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp simd reduction (inscan, +: a)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a) /* { dg-message "sorry, unimplemented: '#pragma omp scan' not supported yet" } */
|
||||
a += c[i];
|
||||
}
|
||||
}
|
14
gcc/testsuite/c-c++-common/gomp/scan-3.c
Normal file
14
gcc/testsuite/c-c++-common/gomp/scan-3.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
int a, b;
|
||||
|
||||
void
|
||||
f1 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp for reduction (inscan, +: a)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan inclusive (a) /* { dg-message "sorry, unimplemented: '#pragma omp scan' not supported yet" } */
|
||||
a += c[i];
|
||||
}
|
||||
}
|
14
gcc/testsuite/c-c++-common/gomp/scan-4.c
Normal file
14
gcc/testsuite/c-c++-common/gomp/scan-4.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
int a, b;
|
||||
|
||||
void
|
||||
f1 (int *c, int *d)
|
||||
{
|
||||
int i;
|
||||
#pragma omp for simd reduction (inscan, +: a)
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
d[i] = a;
|
||||
#pragma omp scan exclusive (a) /* { dg-message "sorry, unimplemented: '#pragma omp scan' not supported yet" } */
|
||||
a += c[i];
|
||||
}
|
||||
}
|
|
@ -306,13 +306,19 @@ enum omp_clause_code {
|
|||
OpenMP clause: map ({alloc:,to:,from:,tofrom:,}variable-list). */
|
||||
OMP_CLAUSE_MAP,
|
||||
|
||||
/* OpenACC clause: use_device (variable_list).
|
||||
/* OpenACC clause: use_device (variable-list).
|
||||
OpenMP clause: use_device_ptr (variable-list). */
|
||||
OMP_CLAUSE_USE_DEVICE_PTR,
|
||||
|
||||
/* OpenMP clause: is_device_ptr (variable-list). */
|
||||
OMP_CLAUSE_IS_DEVICE_PTR,
|
||||
|
||||
/* OpenMP clause: inclusive (variable-list). */
|
||||
OMP_CLAUSE_INCLUSIVE,
|
||||
|
||||
/* OpenMP clause: exclusive (variable-list). */
|
||||
OMP_CLAUSE_EXCLUSIVE,
|
||||
|
||||
/* Internal structure to hold OpenACC cache directive's variable-list.
|
||||
#pragma acc cache (variable-list). */
|
||||
OMP_CLAUSE__CACHE_,
|
||||
|
|
|
@ -1638,6 +1638,12 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
|
|||
gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt)));
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_SCAN:
|
||||
s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
|
||||
copy = gimple_build_omp_scan
|
||||
(s1, gimple_omp_scan_clauses (as_a <gomp_scan *> (stmt)));
|
||||
break;
|
||||
|
||||
case GIMPLE_OMP_SECTION:
|
||||
s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
|
||||
copy = gimple_build_omp_section (s1);
|
||||
|
@ -4365,6 +4371,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
|
|||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_TASKGROUP:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_SECTION:
|
||||
case GIMPLE_OMP_SECTIONS:
|
||||
case GIMPLE_OMP_SINGLE:
|
||||
|
|
|
@ -1619,6 +1619,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
|
|||
case GIMPLE_OMP_SECTION:
|
||||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
|
||||
info, gimple_omp_body_ptr (stmt));
|
||||
break;
|
||||
|
@ -2322,6 +2323,7 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
|
|||
case GIMPLE_OMP_SECTION:
|
||||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
walk_body (convert_local_reference_stmt, convert_local_reference_op,
|
||||
info, gimple_omp_body_ptr (stmt));
|
||||
break;
|
||||
|
@ -2831,6 +2833,7 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
|
|||
case GIMPLE_OMP_MASTER:
|
||||
case GIMPLE_OMP_TASKGROUP:
|
||||
case GIMPLE_OMP_ORDERED:
|
||||
case GIMPLE_OMP_SCAN:
|
||||
case GIMPLE_OMP_CRITICAL:
|
||||
walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
|
||||
break;
|
||||
|
|
|
@ -467,6 +467,12 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
|
|||
case OMP_CLAUSE_IS_DEVICE_PTR:
|
||||
name = "is_device_ptr";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE_INCLUSIVE:
|
||||
name = "inclusive";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE_EXCLUSIVE:
|
||||
name = "exclusive";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE__LOOPTEMP_:
|
||||
name = "_looptemp_";
|
||||
goto print_remap;
|
||||
|
@ -3308,6 +3314,14 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
|
|||
pp_string (pp, "#pragma omp section");
|
||||
goto dump_omp_body;
|
||||
|
||||
case OMP_SCAN:
|
||||
if (OMP_SCAN_CLAUSES (node))
|
||||
{
|
||||
pp_string (pp, "#pragma omp scan");
|
||||
dump_omp_clauses (pp, OMP_SCAN_CLAUSES (node), spc, flags);
|
||||
}
|
||||
goto dump_omp_body;
|
||||
|
||||
case OMP_MASTER:
|
||||
pp_string (pp, "#pragma omp master");
|
||||
goto dump_omp_body;
|
||||
|
|
|
@ -300,6 +300,8 @@ unsigned const char omp_clause_num_ops[] =
|
|||
2, /* OMP_CLAUSE_MAP */
|
||||
1, /* OMP_CLAUSE_USE_DEVICE_PTR */
|
||||
1, /* OMP_CLAUSE_IS_DEVICE_PTR */
|
||||
1, /* OMP_CLAUSE_INCLUSIVE */
|
||||
1, /* OMP_CLAUSE_EXCLUSIVE */
|
||||
2, /* OMP_CLAUSE__CACHE_ */
|
||||
2, /* OMP_CLAUSE_GANG */
|
||||
1, /* OMP_CLAUSE_ASYNC */
|
||||
|
@ -378,6 +380,8 @@ const char * const omp_clause_code_name[] =
|
|||
"map",
|
||||
"use_device_ptr",
|
||||
"is_device_ptr",
|
||||
"inclusive",
|
||||
"exclusive",
|
||||
"_cache_",
|
||||
"gang",
|
||||
"async",
|
||||
|
@ -12295,6 +12299,8 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
|
|||
case OMP_CLAUSE_LINK:
|
||||
case OMP_CLAUSE_USE_DEVICE_PTR:
|
||||
case OMP_CLAUSE_IS_DEVICE_PTR:
|
||||
case OMP_CLAUSE_INCLUSIVE:
|
||||
case OMP_CLAUSE_EXCLUSIVE:
|
||||
case OMP_CLAUSE__LOOPTEMP_:
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
|
|
|
@ -1191,6 +1191,11 @@ DEFTREECODE (OMP_SINGLE, "omp_single", tcc_statement, 2)
|
|||
Operand 1: OMP_SINGLE_CLAUSES: List of clauses. */
|
||||
DEFTREECODE (OMP_TASKGROUP, "omp_taskgroup", tcc_statement, 2)
|
||||
|
||||
/* OpenMP - #pragma omp scan
|
||||
Operand 0: OMP_SCAN_BODY: Scan body.
|
||||
Operand 1: OMP_SCAN_CLAUSES: List of clauses. */
|
||||
DEFTREECODE (OMP_SCAN, "omp_scan", tcc_statement, 2)
|
||||
|
||||
/* OpenMP - #pragma omp section
|
||||
Operand 0: OMP_SECTION_BODY: Section body. */
|
||||
DEFTREECODE (OMP_SECTION, "omp_section", tcc_statement, 1)
|
||||
|
|
|
@ -1344,7 +1344,7 @@ class auto_suppress_location_wrappers
|
|||
#define OMP_BODY(NODE) \
|
||||
TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_MASTER), 0)
|
||||
#define OMP_CLAUSES(NODE) \
|
||||
TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_TASKGROUP), 1)
|
||||
TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SCAN), 1)
|
||||
|
||||
/* Generic accessors for OMP nodes that keep clauses as operand 0. */
|
||||
#define OMP_STANDALONE_CLAUSES(NODE) \
|
||||
|
@ -1435,6 +1435,9 @@ class auto_suppress_location_wrappers
|
|||
#define OMP_TARGET_EXIT_DATA_CLAUSES(NODE)\
|
||||
TREE_OPERAND (OMP_TARGET_EXIT_DATA_CHECK (NODE), 0)
|
||||
|
||||
#define OMP_SCAN_BODY(NODE) TREE_OPERAND (OMP_SCAN_CHECK (NODE), 0)
|
||||
#define OMP_SCAN_CLAUSES(NODE) TREE_OPERAND (OMP_SCAN_CHECK (NODE), 1)
|
||||
|
||||
#define OMP_CLAUSE_SIZE(NODE) \
|
||||
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
|
||||
OMP_CLAUSE_FROM, \
|
||||
|
|
Loading…
Add table
Reference in a new issue