From patchwork Tue Sep 24 19:15:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 277603 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A5C2A2C00BB for ; Wed, 25 Sep 2013 05:15:48 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=lf3Qpk5U/TKq69hiUBxPWZ9ygRWKd qca/LJDEg8FDFT4uffF93FBq6LGtIVlDNxaP6inNplY/jEqvP2MGgrehSF9sW6t8 yNiHUv85rMBDssR4nFs729nOO2MZVjf8LyaxySdqrBptm2VkiNEnrCP5vwoHP3VD mZ5CyGEZYq27U4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=c2xRR6rfGK+gPapkO4XAbuUm36Y=; b=F/b 74Hfc/XwC71k3TpAKcPgQxnU0qIUqq0Pk4Lz51USAZM7Cx4pMQRtHWnnl/vK49Hh ntotT1LHOpKTRFbBoJBZOpJpw6JW/DuuIdbrN1fOe3KBfbVa+XBwWWk5NYdZmj13 DwOhVvjX8URA/64tBiZaLUk/7ypMq+Kd9BMHIyjw= Received: (qmail 14447 invoked by alias); 24 Sep 2013 19:15:41 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 14435 invoked by uid 89); 24 Sep 2013 19:15:41 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 24 Sep 2013 19:15:41 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r8OJFY7E019306 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 24 Sep 2013 15:15:35 -0400 Received: from tucnak.zalov.cz (vpn1-6-71.ams2.redhat.com [10.36.6.71]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r8OJFVCL007163 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 24 Sep 2013 15:15:33 -0400 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.14.7/8.14.7) with ESMTP id r8OJFVb1003369; Tue, 24 Sep 2013 21:15:31 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.14.7/8.14.7/Submit) id r8OJFVYW003368; Tue, 24 Sep 2013 21:15:31 +0200 Date: Tue, 24 Sep 2013 21:15:31 +0200 From: Jakub Jelinek To: Richard Henderson , Torvald Riegel Cc: gcc-patches@gcc.gnu.org Subject: [gomp4] Taskgroup and cancellation compiler fixes Message-ID: <20130924191531.GU30970@tucnak.zalov.cz> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 * 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. Jakub --- 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 *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 " + "% 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 " + "% 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 " + "% 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 " + "% 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 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 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)