Hi!
This patch:
1) defers expansion of taskgroup into GOMP_taskgroup_start and
GOMP_taskgroup_end until omplower/ompexp, mainly so that e.g. invalid
nesting can be diagnosed (e.g. #pragma omp cancel * inside of
#pragma omp taskgroup nested in some other construct)
2) diagnoses structured block restrictions also for #pragma omp target{,data}
and #pragma omp teams and taskgroup
3) fixes a bug, where cancellation of sections, for and parallel/task
jumped to after the dtors rather than before them, because then some
variables won't be properly destructed
Will commit tomorrow to gomp-4_0-branch unless somebody finds issues with
this.
2013-09-24 Jakub Jelinek <[email protected]>
* omp-low.c (lower_omp_sections, lower_omp_for, lower_omp_taskreg):
Emit ctx->cancel_label before destructors.
* gimple-pretty-print.c (dump_gimple_omp_block,
pp_gimple_stmt_1): Handle GIMPLE_OMP_TASKGROUP.
* tree-nested.c (convert_nonlocal_reference_stmt,
convert_local_reference_stmt, convert_gimple_call): Likewise.
* tree-cfg.c (make_edges): Likewise.
* gimple.h (gimple_build_omp_taskgroup): New prototype.
(gimple_has_substatement): Handle GIMPLE_OMP_TASKGROUP.
(CASE_GIMPLE_OMP): Likewise.
* gimplify.c (is_gimple_stmt, gimplify_expr): Handle OMP_TASKGROUP.
* omp-low.c (check_omp_nesting_restrictions): Warn if #pragma omp
cancel is used in nowait loop or sections construct.
(scan_omp_1_stmt, expand_omp_synch, expand_omp, lower_omp_1): Handle
GIMPLE_OMP_TASKGROUP.
(diagnose_sb_1, diagnose_sb_2): Likewise. Handle GIMPLE_OMP_TARGET
and GIMPLE_OMP_TEAMS.
(lower_omp_taskgroup): New function.
* tree-inline.c (remap_gimple_stmt, estimate_num_insns): Handle
GIMPLE_OMP_TASKGROUP.
* gimple-low.c (lower_stmt): Likewise.
* tree.h (OMP_TASKGROUP_BODY): Define.
* tree.def (OMP_TASKGROUP): New tree.
* tree-pretty-print.c (dump_generic_node): Handle OMP_TASKGROUP.
* gimple.c (gimple_build_omp_taskgroup): New function.
(walk_gimple_stmt, gimple_copy): Handle GIMPLE_OMP_TASKGROUP.
* gimple.def (GIMPLE_OMP_TASKGROUP): New GIMPLE code.
c-family/
* c-common.h (c_finish_omp_taskgroup): New prototype.
* c-omp.c (c_finish_omp_taskgroup): New function.
c/
* c-parser.c (c_parser_omp_taskgroup): Return tree.
Don't call c_begin_omp_taskgroup.
(c_parser_omp_construct): Adjust caller.
* c-typeck.c (c_begin_omp_taskgroup, c_finish_omp_taskgroup): Remove.
* c-tree.h (c_begin_omp_taskgroup, c_finish_omp_taskgroup): Remove.
cp/
* parser.c (cp_parser_omp_taskgroup): Return tree. Use
c_finish_omp_taskgroup.
(cp_parser_omp_construct): Adjust caller.
* cp-array-notation.c (expand_array_notation_exprs): Handle
OMP_TASKGROUP.
* pt.c (tsubst_expr): Handle OMP_TASKGROUP.
* semantics.c (finish_omp_taskgroup): Remove.
* cp-tree.h (finish_omp_taskgroup): Remove.
testsuite/
* g++.dg/gomp/target-1.C: New test.
* g++.dg/gomp/target-2.C: New test.
* g++.dg/gomp/teams-1.C: New test.
* g++.dg/gomp/taskgroup-1.C: New test.
* gcc.dg/gomp/teams-1.c: New test.
* gcc.dg/gomp/taskgroup-1.c: New test.
* gcc.dg/gomp/target-1.c: New test.
* gcc.dg/gomp/target-2.c: New test.
* c-c++-common/gomp/cancel-1.c: New test.
--- gcc/gimple-pretty-print.c.jj 2013-09-13 16:48:21.000000000 +0200
+++ gcc/gimple-pretty-print.c 2013-09-23 15:06:23.857832390 +0200
@@ -1360,8 +1360,8 @@ dump_gimple_omp_sections (pretty_printer
}
}
-/* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the pretty_printer
- BUFFER. */
+/* Dump a GIMPLE_OMP_{MASTER,TASKGROUP,ORDERED,SECTION} tuple on the
+ pretty_printer BUFFER. */
static void
dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -1376,6 +1376,9 @@ dump_gimple_omp_block (pretty_printer *b
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_ORDERED:
pp_string (buffer, "#pragma omp ordered");
break;
@@ -2131,6 +2134,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer
break;
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
dump_gimple_omp_block (buffer, gs, spc, flags);
--- gcc/tree-nested.c.jj 2013-09-13 16:49:05.000000000 +0200
+++ gcc/tree-nested.c 2013-09-23 15:06:23.857832390 +0200
@@ -1309,6 +1309,7 @@ convert_nonlocal_reference_stmt (gimple_
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op,
info, gimple_omp_body_ptr (stmt));
@@ -1748,6 +1749,7 @@ convert_local_reference_stmt (gimple_stm
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
walk_body (convert_local_reference_stmt, convert_local_reference_op,
info, gimple_omp_body_ptr (stmt));
@@ -2106,6 +2108,7 @@ convert_gimple_call (gimple_stmt_iterato
case GIMPLE_OMP_TARGET:
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
--- gcc/c/c-parser.c.jj 2013-09-19 09:12:43.000000000 +0200
+++ gcc/c/c-parser.c 2013-09-23 15:07:45.788417931 +0200
@@ -11861,15 +11861,12 @@ c_parser_omp_taskyield (c_parser *parser
# pragma omp taskgroup new-line
*/
-static void
+static tree
c_parser_omp_taskgroup (c_parser *parser)
{
location_t loc = c_parser_peek_token (parser)->location;
c_parser_skip_to_pragma_eol (parser);
-
- tree block = c_begin_omp_taskgroup ();
- c_parser_statement (parser);
- c_finish_omp_taskgroup (loc, block);
+ return c_finish_omp_taskgroup (loc, c_parser_omp_structured_block (parser));
}
/* OpenMP 4.0:
@@ -12891,8 +12888,8 @@ c_parser_omp_construct (c_parser *parser
stmt = c_parser_omp_task (loc, parser);
break;
case PRAGMA_OMP_TASKGROUP:
- c_parser_omp_taskgroup (parser);
- return;
+ stmt = c_parser_omp_taskgroup (parser);
+ break;
case PRAGMA_OMP_TEAMS:
strcpy (p_name, "#pragma omp");
stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL);
--- gcc/c/c-typeck.c.jj 2013-09-19 19:00:43.000000000 +0200
+++ gcc/c/c-typeck.c 2013-09-24 20:46:42.886738344 +0200
@@ -10693,34 +10693,6 @@ c_finish_omp_task (location_t loc, tree
return add_stmt (stmt);
}
-/* Like c_begin_compound_stmt, except force the retention of the BLOCK. */
-
-tree
-c_begin_omp_taskgroup (void)
-{
- tree block;
-
- keep_next_level ();
- block = c_begin_compound_stmt (true);
-
- return block;
-}
-
-/* Generate code for #pragma omp taskgroup. */
-
-void
-c_finish_omp_taskgroup (location_t loc, tree block)
-{
- tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START);
- tree stmt = build_call_expr_loc (loc, fn, 0);
- block = c_end_compound_stmt (loc, block, true);
- add_stmt (stmt);
- add_stmt (block);
- fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
- stmt = build_call_expr_loc (loc, fn, 0);
- add_stmt (stmt);
-}
-
/* Generate GOMP_cancel call for #pragma omp cancel. */
void
--- gcc/c/c-tree.h.jj 2013-09-19 09:12:43.000000000 +0200
+++ gcc/c/c-tree.h 2013-09-24 20:46:32.673788355 +0200
@@ -639,8 +639,6 @@ extern tree c_begin_omp_parallel (void);
extern tree c_finish_omp_parallel (location_t, tree, tree);
extern tree c_begin_omp_task (void);
extern tree c_finish_omp_task (location_t, tree, tree);
-extern tree c_begin_omp_taskgroup (void);
-extern void c_finish_omp_taskgroup (location_t, tree);
extern void c_finish_omp_cancel (location_t, tree);
extern void c_finish_omp_cancellation_point (location_t, tree);
extern tree c_finish_omp_clauses (tree);
--- gcc/tree-cfg.c.jj 2013-09-13 16:52:37.000000000 +0200
+++ gcc/tree-cfg.c 2013-09-23 15:06:23.857832390 +0200
@@ -612,6 +612,7 @@ make_edges (void)
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_SECTION:
--- gcc/cp/parser.c.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/cp/parser.c 2013-09-23 15:06:23.857832390 +0200
@@ -29331,26 +29331,15 @@ cp_parser_omp_taskyield (cp_parser *pars
# pragma omp taskgroup new-line
structured-block */
-static void
+static tree
cp_parser_omp_taskgroup (cp_parser *parser, cp_token *pragma_tok)
{
- tree sb;
- unsigned int save;
- location_t saved_loc;
-
cp_parser_require_pragma_eol (parser, pragma_tok);
- sb = begin_omp_structured_block ();
- save = cp_parser_begin_omp_structured_block (parser);
- cp_parser_statement (parser, NULL_TREE, false, NULL);
- cp_parser_end_omp_structured_block (parser, save);
- saved_loc = input_location;
- input_location = pragma_tok->location;
- finish_omp_taskgroup (finish_omp_structured_block (sb));
- input_location = saved_loc;
+ return c_finish_omp_taskgroup (input_location,
+ cp_parser_omp_structured_block (parser));
}
-
/* OpenMP 2.5:
# pragma omp threadprivate (variable-list) */
@@ -30340,8 +30329,8 @@ cp_parser_omp_construct (cp_parser *pars
stmt = cp_parser_omp_task (parser, pragma_tok);
break;
case PRAGMA_OMP_TASKGROUP:
- cp_parser_omp_taskgroup (parser, pragma_tok);
- return;
+ stmt = cp_parser_omp_taskgroup (parser, pragma_tok);
+ break;
case PRAGMA_OMP_TEAMS:
strcpy (p_name, "#pragma omp");
stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL);
--- gcc/cp/cp-array-notation.c.jj 2013-08-27 20:50:54.000000000 +0200
+++ gcc/cp/cp-array-notation.c 2013-09-23 15:06:23.857832390 +0200
@@ -1193,6 +1193,7 @@ expand_array_notation_exprs (tree t)
case OMP_SECTION:
case OMP_SECTIONS:
case OMP_MASTER:
+ case OMP_TASKGROUP:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_ATOMIC:
--- gcc/cp/pt.c.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/cp/pt.c 2013-09-23 15:06:23.857832390 +0200
@@ -13634,6 +13634,7 @@ tsubst_expr (tree t, tree args, tsubst_f
case OMP_SECTION:
case OMP_CRITICAL:
case OMP_MASTER:
+ case OMP_TASKGROUP:
case OMP_ORDERED:
stmt = push_stmt_list ();
RECUR (OMP_BODY (t));
--- gcc/cp/semantics.c.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/cp/semantics.c 2013-09-23 15:06:23.857832390 +0200
@@ -6529,20 +6529,6 @@ finish_omp_taskyield (void)
}
void
-finish_omp_taskgroup (tree block_stmt)
-{
- tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START);
- vec<tree, va_gc> *vec = make_tree_vector ();
- tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
- finish_expr_stmt (stmt);
- finish_expr_stmt (block_stmt);
- fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
- stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
- finish_expr_stmt (stmt);
- release_tree_vector (vec);
-}
-
-void
finish_omp_cancel (tree clauses)
{
tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
--- gcc/cp/cp-tree.h.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/cp/cp-tree.h 2013-09-23 14:58:59.927014761 +0200
@@ -5806,7 +5806,6 @@ extern void finish_omp_barrier (void);
extern void finish_omp_flush (void);
extern void finish_omp_taskwait (void);
extern void finish_omp_taskyield (void);
-extern void finish_omp_taskgroup (tree);
extern void finish_omp_cancel (tree);
extern void finish_omp_cancellation_point (tree);
extern tree begin_transaction_stmt (location_t, tree *, int);
--- gcc/gimple.h.jj 2013-09-13 16:52:36.000000000 +0200
+++ gcc/gimple.h 2013-09-23 14:22:00.694017141 +0200
@@ -815,6 +815,7 @@ gimple gimple_build_omp_critical (gimple
gimple gimple_build_omp_section (gimple_seq);
gimple gimple_build_omp_continue (tree, tree);
gimple gimple_build_omp_master (gimple_seq);
+gimple gimple_build_omp_taskgroup (gimple_seq);
gimple gimple_build_omp_return (bool);
gimple gimple_build_omp_ordered (gimple_seq);
gimple gimple_build_omp_sections (gimple_seq, tree);
@@ -1264,6 +1265,7 @@ gimple_has_substatements (gimple g)
case GIMPLE_TRY:
case GIMPLE_OMP_FOR:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_PARALLEL:
@@ -5180,6 +5182,7 @@ gimple_return_set_retval (gimple gs, tre
case GIMPLE_OMP_TEAMS: \
case GIMPLE_OMP_SECTION: \
case GIMPLE_OMP_MASTER: \
+ case GIMPLE_OMP_TASKGROUP: \
case GIMPLE_OMP_ORDERED: \
case GIMPLE_OMP_CRITICAL: \
case GIMPLE_OMP_RETURN: \
--- gcc/gimplify.c.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/gimplify.c 2013-09-23 15:06:23.857832390 +0200
@@ -4729,6 +4729,7 @@ is_gimple_stmt (tree t)
case OMP_SECTION:
case OMP_SINGLE:
case OMP_MASTER:
+ case OMP_TASKGROUP:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_TASK:
@@ -8236,6 +8237,7 @@ gimplify_expr (tree *expr_p, gimple_seq
case OMP_SECTION:
case OMP_MASTER:
+ case OMP_TASKGROUP:
case OMP_ORDERED:
case OMP_CRITICAL:
{
@@ -8251,6 +8253,19 @@ gimplify_expr (tree *expr_p, gimple_seq
case OMP_MASTER:
g = gimple_build_omp_master (body);
break;
+ case OMP_TASKGROUP:
+ {
+ gimple_seq cleanup = NULL;
+ tree fn
+ = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
+ g = gimple_build_call (fn, 0);
+ gimple_seq_add_stmt (&cleanup, g);
+ g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
+ body = NULL;
+ gimple_seq_add_stmt (&body, g);
+ g = gimple_build_omp_taskgroup (body);
+ }
+ break;
case OMP_ORDERED:
g = gimple_build_omp_ordered (body);
break;
@@ -8583,6 +8598,7 @@ gimplify_expr (tree *expr_p, gimple_seq
&& code != OMP_CRITICAL
&& code != OMP_FOR
&& code != OMP_MASTER
+ && code != OMP_TASKGROUP
&& code != OMP_ORDERED
&& code != OMP_PARALLEL
&& code != OMP_SECTIONS
--- gcc/omp-low.c.jj 2013-09-19 19:00:45.000000000 +0200
+++ gcc/omp-low.c 2013-09-24 18:47:57.457861620 +0200
@@ -2272,7 +2272,19 @@ check_omp_nesting_restrictions (gimple s
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
- ctx->cancellable = true;
+ {
+ ctx->cancellable = true;
+ if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
+ OMP_CLAUSE_NOWAIT))
+ warning_at (gimple_location (stmt), 0,
+ "%<#pragma omp cancel for%> inside "
+ "%<nowait%> for construct");
+ if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
+ OMP_CLAUSE_ORDERED))
+ warning_at (gimple_location (stmt), 0,
+ "%<#pragma omp cancel for%> inside "
+ "%<ordered%> for construct");
+ }
kind = "for";
break;
case 4:
@@ -2284,13 +2296,27 @@ check_omp_nesting_restrictions (gimple s
&& !integer_zerop (gimple_call_arg (stmt, 1)))
{
if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
- ctx->cancellable = true;
+ {
+ ctx->cancellable = true;
+ if (find_omp_clause (gimple_omp_sections_clauses
+ (ctx->stmt),
+ OMP_CLAUSE_NOWAIT))
+ warning_at (gimple_location (stmt), 0,
+ "%<#pragma omp cancel sections%> inside "
+ "%<nowait%> sections construct");
+ }
else
{
gcc_assert (ctx->outer
&& gimple_code (ctx->outer->stmt)
== GIMPLE_OMP_SECTIONS);
ctx->outer->cancellable = true;
+ if (find_omp_clause (gimple_omp_sections_clauses
+ (ctx->outer->stmt),
+ OMP_CLAUSE_NOWAIT))
+ warning_at (gimple_location (stmt), 0,
+ "%<#pragma omp cancel sections%> inside "
+ "%<nowait%> sections construct");
}
}
kind = "sections";
@@ -2553,6 +2579,7 @@ scan_omp_1_stmt (gimple_stmt_iterator *g
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
ctx = new_omp_context (stmt, ctx);
@@ -7034,6 +7061,7 @@ expand_omp_synch (struct omp_region *reg
si = gsi_last_bb (entry_bb);
gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
|| gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
+ || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP
|| gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
|| gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL
|| gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TEAMS);
@@ -7988,6 +8016,7 @@ expand_omp (struct omp_region *region)
break;
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_TEAMS:
@@ -8309,12 +8338,12 @@ lower_omp_sections (gimple_stmt_iterator
gimple_seq_add_stmt (&new_body, t);
gimple_seq_add_seq (&new_body, olist);
+ if (ctx->cancellable)
+ gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
gimple_seq_add_seq (&new_body, dlist);
new_body = maybe_catch_exception (new_body);
- if (ctx->cancellable)
- gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
t = gimple_build_omp_return
(!!find_omp_clause (gimple_omp_sections_clauses (stmt),
OMP_CLAUSE_NOWAIT));
@@ -8543,6 +8572,33 @@ lower_omp_master (gimple_stmt_iterator *
}
+/* Expand code for an OpenMP taskgroup directive. */
+
+static void
+lower_omp_taskgroup (gimple_stmt_iterator *gsi_p, omp_context *ctx)
+{
+ gimple stmt = gsi_stmt (*gsi_p), bind, x;
+ tree block = make_node (BLOCK);
+
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
+
+ x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START),
+ 0);
+ gimple_bind_add_stmt (bind, x);
+
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
+ gimple_bind_add_seq (bind, gimple_omp_body (stmt));
+ gimple_omp_set_body (stmt, NULL);
+
+ gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
+
+ gimple_bind_append_vars (bind, ctx->block_vars);
+ BLOCK_VARS (block) = ctx->block_vars;
+}
+
+
/* Expand code for an OpenMP ordered directive. */
static void
@@ -8846,13 +8902,14 @@ lower_omp_for (gimple_stmt_iterator *gsi
/* After the loop, add exit clauses. */
lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
+ if (ctx->cancellable)
+ gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
+
gimple_seq_add_seq (&body, dlist);
body = maybe_catch_exception (body);
/* Region exit marker goes at the end of the loop body. */
- if (ctx->cancellable)
- gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
maybe_add_implicit_barrier_cancel (ctx, &body);
pop_gimplify_context (new_stmt);
@@ -9264,10 +9321,10 @@ lower_omp_taskreg (gimple_stmt_iterator
gimple_seq_add_seq (&new_body, par_ilist);
gimple_seq_add_seq (&new_body, par_body);
gimple_seq_add_seq (&new_body, par_rlist);
- gimple_seq_add_seq (&new_body, par_olist);
- new_body = maybe_catch_exception (new_body);
if (ctx->cancellable)
gimple_seq_add_stmt (&new_body, gimple_build_label (ctx->cancel_label));
+ gimple_seq_add_seq (&new_body, par_olist);
+ new_body = maybe_catch_exception (new_body);
gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
gimple_omp_set_body (stmt, new_body);
@@ -9759,6 +9816,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p
gcc_assert (ctx);
lower_omp_master (gsi_p, ctx);
break;
+ case GIMPLE_OMP_TASKGROUP:
+ ctx = maybe_lookup_ctx (stmt);
+ gcc_assert (ctx);
+ lower_omp_taskgroup (gsi_p, ctx);
+ break;
case GIMPLE_OMP_ORDERED:
ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
@@ -10025,6 +10087,9 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_TARGET:
+ case GIMPLE_OMP_TEAMS:
+ case GIMPLE_OMP_TASKGROUP:
/* The minimal context here is just the current OMP construct. */
inner_context = stmt;
wi->info = inner_context;
@@ -10080,6 +10145,9 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_TARGET:
+ case GIMPLE_OMP_TEAMS:
+ case GIMPLE_OMP_TASKGROUP:
wi->info = stmt;
walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL,
wi);
wi->info = context;
--- gcc/tree-inline.c.jj 2013-09-18 12:17:56.000000000 +0200
+++ gcc/tree-inline.c 2013-09-23 15:06:23.857832390 +0200
@@ -1345,6 +1345,11 @@ remap_gimple_stmt (gimple stmt, copy_bod
copy = gimple_build_omp_master (s1);
break;
+ case GIMPLE_OMP_TASKGROUP:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_taskgroup (s1);
+ break;
+
case GIMPLE_OMP_ORDERED:
s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
copy = gimple_build_omp_ordered (s1);
@@ -3841,6 +3846,7 @@ estimate_num_insns (gimple stmt, eni_wei
case GIMPLE_OMP_TASK:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_SECTIONS:
--- gcc/gimple-low.c.jj 2013-09-13 16:46:32.000000000 +0200
+++ gcc/gimple-low.c 2013-09-23 15:06:23.857832390 +0200
@@ -424,6 +424,7 @@ lower_stmt (gimple_stmt_iterator *gsi, s
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_SINGLE:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_RETURN:
--- gcc/tree.h.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/tree.h 2013-09-23 14:21:16.824238761 +0200
@@ -1185,6 +1185,8 @@ extern void protected_set_expr_location
#define OMP_MASTER_BODY(NODE) TREE_OPERAND (OMP_MASTER_CHECK (NODE), 0)
+#define OMP_TASKGROUP_BODY(NODE) TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 0)
+
#define OMP_ORDERED_BODY(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 0)
#define OMP_CRITICAL_BODY(NODE) TREE_OPERAND (OMP_CRITICAL_CHECK (NODE), 0)
--- gcc/tree.def.jj 2013-08-27 22:06:18.000000000 +0200
+++ gcc/tree.def 2013-09-23 14:19:07.617876632 +0200
@@ -1071,6 +1071,10 @@ DEFTREECODE (OMP_SECTION, "omp_section",
Operand 0: OMP_MASTER_BODY: Master section body. */
DEFTREECODE (OMP_MASTER, "omp_master", tcc_statement, 1)
+/* OpenMP - #pragma omp taskgroup
+ Operand 0: OMP_TASKGROUP_BODY: Taskgroup body. */
+DEFTREECODE (OMP_TASKGROUP, "omp_taskgroup", tcc_statement, 1)
+
/* OpenMP - #pragma omp ordered
Operand 0: OMP_ORDERED_BODY: Master section body. */
DEFTREECODE (OMP_ORDERED, "omp_ordered", tcc_statement, 1)
--- gcc/testsuite/g++.dg/gomp/target-1.C.jj 2013-09-24 10:26:09.896136098
+0200
+++ gcc/testsuite/g++.dg/gomp/target-1.C 2013-09-24 10:29:46.237046033
+0200
@@ -0,0 +1,32 @@
+// { dg-do compile }
+
+void
+foo (int x)
+{
+ bad1: // { dg-error "jump to label" }
+ #pragma omp target
+ goto bad1; // { dg-error "from here|exits OpenMP" }
+
+ goto bad2; // { dg-error "from here" }
+ #pragma omp target
+ {
+ bad2: ; // { dg-error "jump to label|enters OpenMP" }
+ }
+
+ #pragma omp target
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x)
+ {
+ #pragma omp target
+ { case 0:; } // { dg-error "jump|enters" }
+ }
+}
+
+// { dg-error "invalid branch to/from an OpenMP structured block" "" { target
*-*-* } 8 }
+// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* }
10 }
--- gcc/testsuite/g++.dg/gomp/target-2.C.jj 2013-09-24 10:26:09.896136098
+0200
+++ gcc/testsuite/g++.dg/gomp/target-2.C 2013-09-24 10:30:17.235890414
+0200
@@ -0,0 +1,32 @@
+// { dg-do compile }
+
+void
+foo (int x, int y)
+{
+ bad1: // { dg-error "jump to label" }
+ #pragma omp target data map(tofrom: y)
+ goto bad1; // { dg-error "from here|exits OpenMP" }
+
+ goto bad2; // { dg-error "from here" }
+ #pragma omp target data map(tofrom: y)
+ {
+ bad2: ; // { dg-error "jump to label|enters OpenMP" }
+ }
+
+ #pragma omp target data map(tofrom: y)
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x)
+ {
+ #pragma omp target data map(tofrom: y)
+ { case 0:; } // { dg-error "jump|enters" }
+ }
+}
+
+// { dg-error "invalid branch to/from an OpenMP structured block" "" { target
*-*-* } 8 }
+// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* }
10 }
--- gcc/testsuite/g++.dg/gomp/teams-1.C.jj 2013-09-24 10:26:09.896136098
+0200
+++ gcc/testsuite/g++.dg/gomp/teams-1.C 2013-09-24 10:31:45.907449396 +0200
@@ -0,0 +1,66 @@
+// { dg-do compile }
+
+void
+foo (int x)
+{
+ bad1: // { dg-error "jump to label" }
+ #pragma omp target teams
+ goto bad1; // { dg-error "from here|exits OpenMP" }
+
+ goto bad2; // { dg-error "from here" }
+ #pragma omp target teams
+ {
+ bad2: ; // { dg-error "jump to label|enters OpenMP" }
+ }
+
+ #pragma omp target teams
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x)
+ {
+ #pragma omp target teams
+ { case 0:; } // { dg-error "jump|enters" }
+ }
+}
+
+void
+bar (int x)
+{
+ bad1: // { dg-error "jump to label" }
+ #pragma omp target
+ #pragma omp teams
+ goto bad1; // { dg-error "from here|exits OpenMP" }
+
+ goto bad2; // { dg-error "from here" }
+ #pragma omp target
+ #pragma omp teams
+ {
+ bad2: ; // { dg-error "jump to label|enters OpenMP" }
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x)
+ {
+ #pragma omp target
+ #pragma omp teams
+ { case 0:; } // { dg-error "jump|enters" }
+ }
+}
+
+// { dg-error "invalid branch to/from an OpenMP structured block" "" { target
*-*-* } 8 }
+// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* }
10 }
+// { dg-error "invalid branch to/from an OpenMP structured block" "" { target
*-*-* } 37 }
+// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* }
39 }
--- gcc/testsuite/g++.dg/gomp/taskgroup-1.C.jj 2013-09-24 10:26:09.896136098
+0200
+++ gcc/testsuite/g++.dg/gomp/taskgroup-1.C 2013-09-24 10:30:38.378788871
+0200
@@ -0,0 +1,32 @@
+// { dg-do compile }
+
+void
+foo (int x)
+{
+ bad1: // { dg-error "jump to label" }
+ #pragma omp taskgroup
+ goto bad1; // { dg-error "from here|exits OpenMP" }
+
+ goto bad2; // { dg-error "from here" }
+ #pragma omp taskgroup
+ {
+ bad2: ; // { dg-error "jump to label|enters OpenMP" }
+ }
+
+ #pragma omp taskgroup
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x)
+ {
+ #pragma omp taskgroup
+ { case 0:; } // { dg-error "jump|enters" }
+ }
+}
+
+// { dg-error "invalid branch to/from an OpenMP structured block" "" { target
*-*-* } 8 }
+// { dg-error "invalid entry to OpenMP structured block" "" { target *-*-* }
10 }
--- gcc/testsuite/gcc.dg/gomp/teams-1.c.jj 2013-09-24 10:20:26.073866380
+0200
+++ gcc/testsuite/gcc.dg/gomp/teams-1.c 2013-09-24 10:21:11.990638320 +0200
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+
+void
+foo (int x)
+{
+ bad1:
+ #pragma omp target teams
+ goto bad1; /* { dg-error "invalid branch" } */
+
+ goto bad2; /* { dg-error "invalid entry" } */
+ #pragma omp target teams
+ {
+ bad2: ;
+ }
+
+ #pragma omp target teams
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x) /* { dg-error "invalid entry" } */
+ {
+ #pragma omp target teams
+ { case 0:; }
+ }
+}
+
+void
+bar (int x)
+{
+ bad1:
+ #pragma omp target
+ #pragma omp teams
+ goto bad1; /* { dg-error "invalid branch" } */
+
+ goto bad2; /* { dg-error "invalid entry" } */
+ #pragma omp target
+ #pragma omp teams
+ {
+ bad2: ;
+ }
+
+ #pragma omp target
+ #pragma omp teams
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x) /* { dg-error "invalid entry" } */
+ {
+ #pragma omp target
+ #pragma omp teams
+ { case 0:; }
+ }
+}
--- gcc/testsuite/gcc.dg/gomp/taskgroup-1.c.jj 2013-09-24 10:19:33.056133832
+0200
+++ gcc/testsuite/gcc.dg/gomp/taskgroup-1.c 2013-09-24 10:19:46.514062767
+0200
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+void
+foo (int x)
+{
+ bad1:
+ #pragma omp taskgroup
+ goto bad1; /* { dg-error "invalid branch" } */
+
+ goto bad2; /* { dg-error "invalid entry" } */
+ #pragma omp taskgroup
+ {
+ bad2: ;
+ }
+
+ #pragma omp taskgroup
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x) /* { dg-error "invalid entry" } */
+ {
+ #pragma omp taskgroup
+ { case 0:; }
+ }
+}
--- gcc/testsuite/gcc.dg/gomp/target-2.c.jj 2013-09-24 10:18:35.710422631
+0200
+++ gcc/testsuite/gcc.dg/gomp/target-2.c 2013-09-24 10:19:19.410224872
+0200
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+void
+foo (int x, int y)
+{
+ bad1:
+ #pragma omp target data map(tofrom: y)
+ goto bad1; /* { dg-error "invalid branch" } */
+
+ goto bad2; /* { dg-error "invalid entry" } */
+ #pragma omp target data map(tofrom: y)
+ {
+ bad2: ;
+ }
+
+ #pragma omp target data map(tofrom: y)
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x) /* { dg-error "invalid entry" } */
+ {
+ #pragma omp target data map(tofrom: y)
+ { case 0:; }
+ }
+}
--- gcc/testsuite/gcc.dg/gomp/target-1.c.jj 2013-09-24 10:18:27.956460166
+0200
+++ gcc/testsuite/gcc.dg/gomp/target-1.c 2013-09-24 10:17:59.216584442
+0200
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+void
+foo (int x)
+{
+ bad1:
+ #pragma omp target
+ goto bad1; /* { dg-error "invalid branch" } */
+
+ goto bad2; /* { dg-error "invalid entry" } */
+ #pragma omp target
+ {
+ bad2: ;
+ }
+
+ #pragma omp target
+ {
+ int i;
+ goto ok1;
+ for (i = 0; i < 10; ++i)
+ { ok1: break; }
+ }
+
+ switch (x) /* { dg-error "invalid entry" } */
+ {
+ #pragma omp target
+ { case 0:; }
+ }
+}
--- gcc/testsuite/c-c++-common/gomp/cancel-1.c.jj 2013-09-23
14:07:57.200202039 +0200
+++ gcc/testsuite/c-c++-common/gomp/cancel-1.c 2013-09-24 10:32:34.261202645
+0200
@@ -0,0 +1,396 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void
+f1 (void)
+{
+ #pragma omp cancel parallel /* { dg-error "orphaned" } */
+ #pragma omp cancel for /* { dg-error "orphaned" } */
+ #pragma omp cancel sections /* { dg-error "orphaned" } */
+ #pragma omp cancel taskgroup /* { dg-error "orphaned" } */
+ #pragma omp cancellation point parallel /* { dg-error "orphaned" } */
+ #pragma omp cancellation point for /* { dg-error "orphaned" } */
+ #pragma omp cancellation point sections /* { dg-error "orphaned" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "orphaned" } */
+}
+
+void
+f2 (void)
+{
+ int i;
+ #pragma omp parallel
+ {
+ #pragma omp cancel parallel
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp master
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp single
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp critical
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp taskgroup
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp task
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup
+ }
+ #pragma omp for
+ for (i = 0; i < 10; i++)
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup/* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp for ordered
+ for (i = 0; i < 10; i++)
+ #pragma omp ordered
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup/* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp sections
+ {
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections
+ #pragma omp cancellation point taskgroup/* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp section
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections
+ #pragma omp cancellation point taskgroup/* { dg-error "not closely
nested inside" } */
+ }
+ }
+ #pragma omp target data
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp target
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ }
+ #pragma omp target data
+ {
+ #pragma omp cancel parallel /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp target
+ {
+ #pragma omp cancel parallel /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp target teams
+ {
+ #pragma omp cancel parallel /* { dg-error "only
distribute or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancel for /* { dg-error "only distribute
or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancel sections /* { dg-error "only
distribute or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancel taskgroup /* { dg-error "only distribute
or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancellation point parallel /* { dg-error "only distribute
or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancellation point for /* { dg-error "only distribute
or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancellation point sections /* { dg-error "only distribute
or parallel constructs are allowed to be closely nested" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "only distribute
or parallel constructs are allowed to be closely nested" } */
+ }
+ #pragma omp target teams distribute
+ for (i = 0; i < 10; i++)
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp for
+ for (i = 0; i < 10; i++)
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp for
+ for (i = 0; i < 10; i++)
+ #pragma omp target data
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp for
+ for (i = 0; i < 10; i++)
+ #pragma omp target
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp for ordered
+ for (i = 0; i < 10; i++)
+ #pragma omp ordered
+ #pragma omp target data
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup/* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp for ordered
+ for (i = 0; i < 10; i++)
+ #pragma omp ordered
+ #pragma omp target
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup/* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp sections
+ {
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp section
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ }
+ #pragma omp sections
+ {
+ #pragma omp target data
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp section
+ #pragma omp target data
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ }
+ #pragma omp sections
+ {
+ #pragma omp target
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ #pragma omp section
+ #pragma omp target
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ }
+ #pragma omp task
+ {
+ #pragma omp cancel parallel /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not
closely nested inside" } */
+ #pragma omp cancel taskgroup
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup
+ #pragma omp taskgroup
+ {
+ #pragma omp cancel parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancel taskgroup /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point parallel /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point for /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point sections /* { dg-error "not closely
nested inside" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "not closely
nested inside" } */
+ }
+ }
+}
+
+void
+f3 (void)
+{
+ int i;
+ #pragma omp for nowait
+ for (i = 0; i < 10; i++)
+ {
+ #pragma omp cancel for /* { dg-warning "nowait" } */
+ }
+ #pragma omp sections nowait
+ {
+ {
+ #pragma omp cancel sections /* { dg-warning "nowait" } */
+ }
+ #pragma omp section
+ {
+ #pragma omp cancel sections /* { dg-warning "nowait" } */
+ }
+ }
+ #pragma omp for ordered
+ for (i = 0; i < 10; i++)
+ {
+ #pragma omp cancel for /* { dg-warning "ordered" } */
+ #pragma omp ordered
+ {
+ }
+ }
+}
--- gcc/tree-pretty-print.c.jj 2013-09-18 12:43:23.000000000 +0200
+++ gcc/tree-pretty-print.c 2013-09-23 15:06:23.857832390 +0200
@@ -2478,6 +2478,10 @@ dump_generic_node (pretty_printer *buffe
pp_string (buffer, "#pragma omp master");
goto dump_omp_body;
+ case OMP_TASKGROUP:
+ pp_string (buffer, "#pragma omp taskgroup");
+ goto dump_omp_body;
+
case OMP_ORDERED:
pp_string (buffer, "#pragma omp ordered");
goto dump_omp_body;
--- gcc/gimple.c.jj 2013-09-13 16:52:32.000000000 +0200
+++ gcc/gimple.c 2013-09-23 15:06:23.857832390 +0200
@@ -1007,6 +1007,22 @@ gimple_build_omp_master (gimple_seq body
}
+/* Build a GIMPLE_OMP_TASKGROUP statement.
+
+ BODY is the sequence of statements to be executed by the taskgroup
+ construct. */
+
+gimple
+gimple_build_omp_taskgroup (gimple_seq body)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_TASKGROUP, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+
+ return p;
+}
+
+
/* Build a GIMPLE_OMP_CONTINUE statement.
CONTROL_DEF is the definition of the control variable.
@@ -1837,6 +1853,7 @@ walk_gimple_stmt (gimple_stmt_iterator *
/* FALL THROUGH. */
case GIMPLE_OMP_CRITICAL:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_PARALLEL:
@@ -2371,6 +2388,7 @@ gimple_copy (gimple stmt)
case GIMPLE_OMP_TEAMS:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
case GIMPLE_OMP_ORDERED:
copy_omp_body:
new_seq = gimple_seq_copy (gimple_omp_body (stmt));
--- gcc/c-family/c-common.h.jj 2013-09-13 16:45:28.000000000 +0200
+++ gcc/c-family/c-common.h 2013-09-23 14:53:25.558665832 +0200
@@ -1172,6 +1172,7 @@ enum c_omp_clause_split
};
extern tree c_finish_omp_master (location_t, tree);
+extern tree c_finish_omp_taskgroup (location_t, tree);
extern tree c_finish_omp_critical (location_t, tree, tree);
extern tree c_finish_omp_ordered (location_t, tree);
extern void c_finish_omp_barrier (location_t);
--- gcc/c-family/c-omp.c.jj 2013-08-19 12:07:50.000000000 +0200
+++ gcc/c-family/c-omp.c 2013-09-23 15:06:23.857832390 +0200
@@ -42,6 +42,17 @@ c_finish_omp_master (location_t loc, tre
return t;
}
+/* Complete a #pragma omp taskgroup construct. STMT is the structured-block
+ that follows the pragma. LOC is the l*/
+
+tree
+c_finish_omp_taskgroup (location_t loc, tree stmt)
+{
+ tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt));
+ SET_EXPR_LOCATION (t, loc);
+ return t;
+}
+
/* Complete a #pragma omp critical construct. STMT is the structured-block
that follows the pragma, NAME is the identifier in the pragma, or null
if it was omitted. LOC is the location of the #pragma. */
--- gcc/gimple.def.jj 2013-09-05 09:19:03.000000000 +0200
+++ gcc/gimple.def 2013-09-23 14:20:39.121419992 +0200
@@ -276,6 +276,10 @@ DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_fo
BODY is the sequence of statements to execute in the master section. */
DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP)
+/* GIMPLE_OMP_TASKGROUP <BODY> represents #pragma omp taskgroup.
+ BODY is the sequence of statements to execute in the taskgroup section. */
+DEFGSCODE(GIMPLE_OMP_TASKGROUP, "gimple_omp_taskgroup", GSS_OMP)
+
/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
BODY is the sequence of statements to execute in the ordered section. */
DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
Jakub