From patchwork Mon Jun 12 18:14:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 774787 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wmgzX4bk8z9s65 for ; Tue, 13 Jun 2017 04:15:03 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="rxmkJquo"; dkim-atps=neutral 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:subject:message-id:reply-to:mime-version:content-type; q=dns; s=default; b=LIKsSkpvSfjZJVTSB8ju3yQ9rcoa+JVx1AxvuCuSfR7 FcRv07H3FIJRsrMlcHQJ3++gRKWq04BKWsADMjffaBv3pwHg9eL4qTW/sdZ5Ke2X 0qFBNeGsxZONayPfLwsrvKx8//zMcL1c0tewe1jhHqsC6Xj51IXMidTuJKU1Tn40 = 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:subject:message-id:reply-to:mime-version:content-type; s=default; bh=IYJlouSyZF3ep/4Wp1Y54BcN+9M=; b=rxmkJquo/dzYbadOI jLZV07q54orh2PRgSw2woEeTRqc3KS6A4m8W34cWfR2wuy8KFabLdyZMMKpgF92m kRFQMrRuGkq537RrwFBEEen6+uFVd0LsjWjOY/x1U9TP02S4LGMyuIRLFuq1SmzY MD6yY/NKcAMbong8Qurf8G2OSg= Received: (qmail 61796 invoked by alias); 12 Jun 2017 18:14:49 -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 61774 invoked by uid 89); 12 Jun 2017 18:14:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=ort, 4456, 2668 X-HELO: mx1.redhat.com 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; Mon, 12 Jun 2017 18:14:42 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6B39A334594 for ; Mon, 12 Jun 2017 18:14:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 6B39A334594 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 6B39A334594 Received: from tucnak.zalov.cz (ovpn-117-179.ams2.redhat.com [10.36.117.179]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9284117CCB for ; Mon, 12 Jun 2017 18:14:44 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id v5CIEfgR004964 for ; Mon, 12 Jun 2017 20:14:41 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v5CIEeQ1004963 for gcc-patches@gcc.gnu.org; Mon, 12 Jun 2017 20:14:40 +0200 Date: Mon, 12 Jun 2017 20:14:40 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [gomp5] Parsing of in_reduction/task_reduction clauses Message-ID: <20170612181440.GE2099@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) X-IsSubscribed: yes Hi! This patch adds parsing of in_reduction and task_reduction clauses and reduction on taskloop. The lowering/expansion and library side is not done yet. Committed to gomp-5_0-branch. 2017-06-12 Jakub Jelinek * tree.def (OMP_TASKGROUP): Add another operand, move next to other OpenMP constructs with body and clauses operands. * gimple-pretty-print.c (dump_gimple_omp_taskgroup): New function. (pp_gimple_stmt_1): Handle GIMPLE_OMP_TASKGROUP. * gimple.h (gimple_build_omp_taskgroup): Add clauses argument. (gimple_omp_taskgroup_clauses): New inline function. (gimple_omp_taskgroup_clauses_ptr): Likewise. (gimple_omp_taskgroup_set_clauses): Likewise. * tree.h (OMP_BODY): Use OMP_MASTER instead of OMP_TASKGROUP. (OMP_CLAUSES): Use OMP_TASKGROUP instead of OMP_SINGLE. (OMP_TASKGROUP_CLAUSES): Define. (OMP_CLAUSE_REDUCTION_CODE): Handle OMP_CLAUSE_{,IN_,TASK_}REDUCTION. (OMP_CLAUSE_REDUCTION_INIT): Likewise. (OMP_CLAUSE_REDUCTION_MERGE): Likewise. (OMP_CLAUSE_REDUCTION_PLACEHOLDER): Likewise. (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER): Likewise. (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF): Likewise. * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_{TASK,IN}_REDUCTION. (dump_generic_node): Print taskgroup clauses. * gimple.def (GIMPLE_OMP_TASKGROUP): Use GSS_OMP_SINGLE_LAYOUT instead of GSS_OMP. * tree.c (omp_clause_num_ops): Add in_reduction and task_reduction clause entries. (omp_clause_code_name): Likewise. (walk_tree_1): Handle OMP_CLAUSE_{TASK,IN}_REDUCTION. * tree-streamer-out.c (pack_ts_omp_clause_value_fields): Likewise. (write_ts_omp_clause_tree_pointers): Likewise. * tree-streamer-in.c (unpack_ts_omp_clause_value_fields): Likewise. * gimple.c (gimple_build_omp_taskgroup): Add CLAUSES argument. Call gimple_omp_taskgroup_set_clauses. (gimple_copy): Copy taskgroup clauses. * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_{TASK,IN}_REDUCTION like OMP_CLAUSE_REDUCTION. (lower_rec_input_clauses): Likewise. (scan_omp_for): Fix comment formatting. * lto-streamer-out.c (hash_tree): Handle OMP_CLAUSE_{TASK,IN}_REDUCTION. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_TASK_REDUCTION and OMP_CLAUSE_IN_REDUCTION. * gimplify.c (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_{TASK,IN}_REDUCTION. (gimplify_adjust_omp_clauses): Likewise. (gimplify_expr): Handle taskgroup clauses. * tree-inline.c (remap_gimple_stmt): Remap taskgroup clauses. c-family/ * c-common.h (c_finish_omp_taskgroup): Add CLAUSES argument. * c-omp.c (c_finish_omp_taskgroup): Likewise. Set OMP_TASKGROUP_CLAUSES to it. (c_omp_split_clauses): Handle in_reduction clause. Handle reduction clause on taskloop simd. * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_IN_REDUCTION and PRAGMA_OMP_CLAUSE_TASK_REDUCTION. c/ * c-parser.c (c_parser_omp_clause_name): Handle in_reduction and task_reduction clauses. (c_parser_omp_variable_list): Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE_TASK_REDUCTION. (c_parser_omp_clause_reduction): Add KIND argument. Pass it to c_parser_omp_variable_list. (c_parser_oacc_all_clauses): Adjust c_parser_omp_clause_reduction caller. (c_parser_omp_all_clauses): Likewise. Handle PRAGMA_OMP_CLAUSE_IN_REDUCTION and PRAGMA_OMP_CLAUSE_TASK_REDUCTION. (OMP_TASK_CLAUSE_MASK): Add in_reduction clause. (OMP_TASKGROUP_CLAUSE_MASK): Define. (c_parser_omp_taskgroup): Add LOC argument. Parse taskgroup clauses. (OMP_TASKLOOP_CLAUSE_MASK): Add reduction and in_reduction clauses. (c_parser_omp_taskloop): Don't mask off PRAGMA_OMP_CLAUSE_REDUCTION. (c_parser_omp_construct): Adjust c_parser_omp_taskgroup caller. (c_parser_cilk_all_clauses): Adjust c_parser_omp_clause_reduction caller. * c-typeck.c (handle_omp_array_sections_1): Handle OMP_CLAUSE_{IN,TASK}_REDUCTION like OMP_CLAUSE_REDUCTION. (handle_omp_array_sections): Likewise. (c_finish_omp_clauses): Likewise. cp/ * parser.c (cp_parser_omp_clause_name): Handle in_reduction and task_reduction clauses. (cp_parser_omp_var_list_no_open): Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE_TASK_REDUCTION. (cp_parser_omp_clause_reduction): Add KIND argument. Pass it to cp_parser_omp_var_list_no_open. (cp_parser_omp_clause_lastprivate): Remove unused loc argument. (cp_parser_oacc_all_clauses): Adjust cp_parser_omp_clause_reduction caller. (cp_parser_omp_all_clauses): Likewise. Handle PRAGMA_OMP_CLAUSE_IN_REDUCTION and PRAGMA_OMP_CLAUSE_TASK_REDUCTION. Adjust cp_parser_omp_clause_lastprivate caller. (cp_parser_omp_for_loop): Handle OMP_CLAUSE_IN_REDUCTION like OMP_CLAUSE_REDUCTION. (OMP_TASK_CLAUSE_MASK): Add in_reduction clause. (OMP_TASKGROUP_CLAUSE_MASK): Define. (cp_parser_omp_taskgroup): Parse taskgroup clauses, adjust c_finish_omp_taskgroup caller. (OMP_TASKLOOP_CLAUSE_MASK): Add reduction and in_reduction clauses. (cp_parser_cilk_simd_all_clauses): Adjust cp_parser_omp_clause_reduction caller. * semantics.c (handle_omp_array_sections_1): Handle OMP_CLAUSE_{IN,TASK}_REDUCTION like OMP_CLAUSE_REDUCTION. (handle_omp_array_sections): Likewise. (finish_omp_clauses): Likewise. * cp-gimplify.c (cp_genericize_r): Handle OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE_TASK_REDUCTION. * pt.c (tsubst_expr): Handle clauses on OMP_TASKGROUP. Jakub --- gcc/tree.def.jj 2017-05-24 11:33:38.199146293 +0200 +++ gcc/tree.def 2017-05-24 11:56:00.086183470 +0200 @@ -1183,6 +1183,11 @@ DEFTREECODE (OMP_CRITICAL, "omp_critical Operand 1: OMP_SINGLE_CLAUSES: List of clauses. */ DEFTREECODE (OMP_SINGLE, "omp_single", tcc_statement, 2) +/* OpenMP - #pragma omp taskgroup + Operand 0: OMP_TASKGROUP_BODY: Taskgroup body. + Operand 1: OMP_SINGLE_CLAUSES: List of clauses. */ +DEFTREECODE (OMP_TASKGROUP, "omp_taskgroup", tcc_statement, 2) + /* OpenMP - #pragma omp section Operand 0: OMP_SECTION_BODY: Section body. */ DEFTREECODE (OMP_SECTION, "omp_section", tcc_statement, 1) @@ -1191,10 +1196,6 @@ 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) - /* OpenACC - #pragma acc cache (variable1 ... variableN) Operand 0: OACC_CACHE_CLAUSES: List of variables (transformed into OMP_CLAUSE__CACHE_ clauses). */ --- gcc/cp/parser.c.jj 2017-05-24 11:47:22.511726226 +0200 +++ gcc/cp/parser.c 2017-05-24 11:56:00.095183356 +0200 @@ -30607,7 +30607,7 @@ cp_parser_objc_at_dynamic_declaration (c } -/* OpenMP 2.5 / 3.0 / 3.1 / 4.0 parsing routines. */ +/* OpenMP 2.5 / 3.0 / 3.1 / 4.0 / 4.5 / 5.0 parsing routines. */ /* Returns name of the next clause. If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and @@ -30693,7 +30693,9 @@ cp_parser_omp_clause_name (cp_parser *pa result = PRAGMA_OACC_CLAUSE_HOST; break; case 'i': - if (!strcmp ("inbranch", p)) + if (!strcmp ("in_reduction", p)) + result = PRAGMA_OMP_CLAUSE_IN_REDUCTION; + else if (!strcmp ("inbranch", p)) result = PRAGMA_OMP_CLAUSE_INBRANCH; else if (!strcmp ("independent", p)) result = PRAGMA_OACC_CLAUSE_INDEPENDENT; @@ -30785,7 +30787,9 @@ cp_parser_omp_clause_name (cp_parser *pa result = PRAGMA_OMP_CLAUSE_SIMDLEN; break; case 't': - if (!strcmp ("taskgroup", p)) + if (!strcmp ("task_reduction", p)) + result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION; + else if (!strcmp ("taskgroup", p)) result = PRAGMA_OMP_CLAUSE_TASKGROUP; else if (!strcmp ("thread_limit", p)) result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT; @@ -30945,6 +30949,8 @@ cp_parser_omp_var_list_no_open (cp_parse /* FALLTHROUGH. */ case OMP_CLAUSE_DEPEND: case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) { tree low_bound = NULL_TREE, length = NULL_TREE; @@ -32054,10 +32060,15 @@ cp_parser_omp_clause_ordered (cp_parser reduction-operator: One of: + * - & ^ | && || - id-expression */ + id-expression + + OpenMP 5.0: + in_reduction ( reduction-operator : variable-list ) + task_reduction ( reduction-operator : variable-list ) */ static tree -cp_parser_omp_clause_reduction (cp_parser *parser, tree list) +cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind, + tree list) { enum tree_code code = ERROR_MARK; tree nlist, c, id = NULL_TREE; @@ -32137,7 +32148,7 @@ cp_parser_omp_clause_reduction (cp_parse if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) goto resync_fail; - nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_REDUCTION, list, + nlist = cp_parser_omp_var_list_no_open (parser, kind, list, NULL); for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) { @@ -32463,7 +32474,7 @@ cp_parser_omp_clause_aligned (cp_parser lastprivate ( [ lastprivate-modifier : ] variable-list ) */ static tree -cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list, location_t loc) +cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list) { bool conditional = false; @@ -33216,7 +33227,9 @@ cp_parser_oacc_all_clauses (cp_parser *p c_name = "private"; break; case PRAGMA_OACC_CLAUSE_REDUCTION: - clauses = cp_parser_omp_clause_reduction (parser, clauses); + clauses + = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, + clauses); c_name = "reduction"; break; case PRAGMA_OACC_CLAUSE_SELF: @@ -33367,9 +33380,14 @@ cp_parser_omp_all_clauses (cp_parser *pa true); c_name = "if"; break; + case PRAGMA_OMP_CLAUSE_IN_REDUCTION: + clauses + = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION, + clauses); + c_name = "in_reduction"; + break; case PRAGMA_OMP_CLAUSE_LASTPRIVATE: - clauses = cp_parser_omp_clause_lastprivate (parser, clauses, - token->location); + clauses = cp_parser_omp_clause_lastprivate (parser, clauses); c_name = "lastprivate"; break; case PRAGMA_OMP_CLAUSE_MERGEABLE: @@ -33407,7 +33425,9 @@ cp_parser_omp_all_clauses (cp_parser *pa c_name = "private"; break; case PRAGMA_OMP_CLAUSE_REDUCTION: - clauses = cp_parser_omp_clause_reduction (parser, clauses); + clauses + = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, + clauses); c_name = "reduction"; break; case PRAGMA_OMP_CLAUSE_SCHEDULE: @@ -33420,6 +33440,13 @@ cp_parser_omp_all_clauses (cp_parser *pa clauses); c_name = "shared"; break; + case PRAGMA_OMP_CLAUSE_TASK_REDUCTION: + clauses + = cp_parser_omp_clause_reduction (parser, + OMP_CLAUSE_TASK_REDUCTION, + clauses); + c_name = "task_reduction"; + break; case PRAGMA_OMP_CLAUSE_UNTIED: clauses = cp_parser_omp_clause_untied (parser, clauses, token->location); @@ -34694,7 +34721,8 @@ cp_parser_omp_for_loop (cp_parser *parse error_at (loc, "iteration variable %qD " "should not be firstprivate", decl); - else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION) && OMP_CLAUSE_DECL (c) == decl) error_at (loc, "iteration variable %qD should not be reduction", decl); @@ -35340,7 +35368,8 @@ cp_parser_omp_single (cp_parser *parser, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) static tree cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok, bool *if_p) @@ -35379,15 +35408,24 @@ cp_parser_omp_taskyield (cp_parser *pars /* OpenMP 4.0: # pragma omp taskgroup new-line - structured-block */ + structured-block + + OpenMP 5.0: + # pragma omp taskgroup taskgroup-clause[optseq] new-line */ + +#define OMP_TASKGROUP_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) static tree cp_parser_omp_taskgroup (cp_parser *parser, cp_token *pragma_tok, bool *if_p) { - cp_parser_require_pragma_eol (parser, pragma_tok); + tree clauses + = cp_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK, + "#pragma omp taskgroup", pragma_tok); return c_finish_omp_taskgroup (input_location, cp_parser_omp_structured_block (parser, - if_p)); + if_p), + clauses); } @@ -37414,7 +37452,9 @@ cp_parser_omp_declare (cp_parser *parser | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) static tree cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok, @@ -38784,7 +38824,8 @@ cp_parser_cilk_simd_all_clauses (cp_pars clauses); else if (c_kind == PRAGMA_CILK_CLAUSE_REDUCTION) /* Use the OMP 4.0 equivalent function. */ - clauses = cp_parser_omp_clause_reduction (parser, clauses); + clauses = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, + clauses); else { clauses = error_mark_node; --- gcc/cp/semantics.c.jj 2017-05-24 11:47:20.602750358 +0200 +++ gcc/cp/semantics.c 2017-05-24 11:56:00.097183331 +0200 @@ -4591,7 +4591,9 @@ handle_omp_array_sections_1 (tree c, tre } if (ort == C_ORT_OMP - && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) && TREE_CODE (TREE_CHAIN (t)) == FIELD_DECL) TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t), false); ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types, @@ -4650,7 +4652,9 @@ handle_omp_array_sections_1 (tree c, tre if (!integer_nonzerop (length)) { if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { if (integer_zerop (length)) { @@ -4716,7 +4720,9 @@ handle_omp_array_sections_1 (tree c, tre if (tree_int_cst_equal (size, low_bound)) { if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { error_at (OMP_CLAUSE_LOCATION (c), "zero length array section in %qs clause", @@ -4735,7 +4741,9 @@ handle_omp_array_sections_1 (tree c, tre else if (length == NULL_TREE) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND - && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION) + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) maybe_zero_len = true; if (first_non_one == types.length ()) first_non_one++; @@ -4771,7 +4779,9 @@ handle_omp_array_sections_1 (tree c, tre else if (length == NULL_TREE) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND - && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION) + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) maybe_zero_len = true; if (first_non_one == types.length ()) first_non_one++; @@ -4949,7 +4959,9 @@ handle_omp_array_sections (tree c, enum if (i > first_non_one && ((length && integer_nonzerop (length)) - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)) continue; if (length) l = fold_convert (sizetype, length); @@ -4977,7 +4989,9 @@ handle_omp_array_sections (tree c, enum tree eltype = TREE_TYPE (types[num - 1]); while (TREE_CODE (eltype) == ARRAY_TYPE) eltype = TREE_TYPE (eltype); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) size = size_binop (EXACT_DIV_EXPR, size, size_in_bytes (eltype)); size = size_binop (MULT_EXPR, size, l); @@ -4993,7 +5007,9 @@ handle_omp_array_sections (tree c, enum { if (side_effects) size = build2 (COMPOUND_EXPR, sizetype, side_effects, size); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { size = size_binop (MINUS_EXPR, size, size_one_node); tree index_type = build_index_type (size); @@ -5869,6 +5885,8 @@ finish_omp_clauses (tree clauses, enum c field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); goto check_dup_generic; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); t = OMP_CLAUSE_DECL (c); if (TREE_CODE (t) == TREE_LIST) @@ -7208,6 +7226,8 @@ finish_omp_clauses (tree clauses, enum c need_implicitly_determined = true; break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: need_implicitly_determined = true; break; case OMP_CLAUSE_LINEAR: @@ -7294,6 +7314,8 @@ finish_omp_clauses (tree clauses, enum c break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: if (finish_omp_reduction_clause (c, &need_default_ctor, &need_dtor)) remove = true; @@ -7358,7 +7380,9 @@ finish_omp_clauses (tree clauses, enum c inner_type = type = TREE_TYPE (t); if ((need_complete_type || need_copy_assignment - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) && TREE_CODE (inner_type) == REFERENCE_TYPE) inner_type = TREE_TYPE (inner_type); while (TREE_CODE (inner_type) == ARRAY_TYPE) --- gcc/cp/cp-gimplify.c.jj 2017-05-24 11:47:18.921771608 +0200 +++ gcc/cp/cp-gimplify.c 2017-05-24 11:56:00.098183318 +0200 @@ -1171,6 +1171,8 @@ cp_genericize_r (tree *stmt_p, int *walk *walk_subtrees = 0; break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: /* Don't dereference an invisiref in reduction clause's OMP_CLAUSE_DECL either. OMP_CLAUSE_REDUCTION_{INIT,MERGE} still needs to be genericized. */ --- gcc/cp/pt.c.jj 2017-05-24 11:47:20.243754896 +0200 +++ gcc/cp/pt.c 2017-05-24 11:56:00.103183255 +0200 @@ -16267,6 +16267,7 @@ tsubst_expr (tree t, tree args, tsubst_f case OMP_SINGLE: case OMP_TEAMS: case OMP_CRITICAL: + case OMP_TASKGROUP: r = push_omp_privatization_clauses (TREE_CODE (t) == OMP_TEAMS && OMP_TEAMS_COMBINED (t)); tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_OMP, args, complain, @@ -16373,7 +16374,6 @@ tsubst_expr (tree t, tree args, tsubst_f case OMP_SECTION: case OMP_MASTER: - case OMP_TASKGROUP: stmt = push_stmt_list (); RECUR (OMP_BODY (t)); stmt = pop_stmt_list (stmt); --- gcc/gimple-pretty-print.c.jj 2017-05-24 11:47:44.905443143 +0200 +++ gcc/gimple-pretty-print.c 2017-05-24 11:56:00.104183242 +0200 @@ -1544,6 +1544,35 @@ dump_gimple_omp_single (pretty_printer * } } +/* Dump a GIMPLE_OMP_TASKGROUP tuple on the pretty_printer BUFFER. */ + +static void +dump_gimple_omp_taskgroup (pretty_printer *buffer, gimple *gs, + int spc, int flags) +{ + if (flags & TDF_RAW) + { + dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs, + gimple_omp_body (gs)); + dump_omp_clauses (buffer, gimple_omp_taskgroup_clauses (gs), spc, flags); + dump_gimple_fmt (buffer, spc, flags, " >"); + } + else + { + pp_string (buffer, "#pragma omp taskgroup"); + dump_omp_clauses (buffer, gimple_omp_taskgroup_clauses (gs), spc, flags); + if (!gimple_seq_empty_p (gimple_omp_body (gs))) + { + newline_and_indent (buffer, spc + 2); + pp_left_brace (buffer); + pp_newline (buffer); + dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags); + newline_and_indent (buffer, spc + 2); + pp_right_brace (buffer); + } + } +} + /* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER. */ static void @@ -1702,7 +1731,7 @@ dump_gimple_omp_sections (pretty_printer } } -/* Dump a GIMPLE_OMP_{MASTER,TASKGROUP,ORDERED,SECTION} tuple on the +/* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the pretty_printer BUFFER. */ static void @@ -2559,8 +2588,11 @@ pp_gimple_stmt_1 (pretty_printer *buffer pp_string (buffer, "GIMPLE_SECTIONS_SWITCH"); break; - case GIMPLE_OMP_MASTER: case GIMPLE_OMP_TASKGROUP: + dump_gimple_omp_taskgroup (buffer, gs, spc, flags); + break; + + case GIMPLE_OMP_MASTER: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_GRID_BODY: dump_gimple_omp_block (buffer, gs, spc, flags); --- gcc/gimple.h.jj 2017-05-24 11:33:38.378144030 +0200 +++ gcc/gimple.h 2017-05-24 11:56:00.105183229 +0200 @@ -738,7 +738,8 @@ struct GTY((tag("GSS_OMP_CONTINUE"))) tree control_use; }; -/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS, GIMPLE_OMP_ORDERED */ +/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_TEAMS, GIMPLE_OMP_ORDERED, + GIMPLE_OMP_TASKGROUP. */ struct GTY((tag("GSS_OMP_SINGLE_LAYOUT"))) gimple_statement_omp_single_layout : public gimple_statement_omp @@ -1467,7 +1468,7 @@ gomp_task *gimple_build_omp_task (gimple gimple *gimple_build_omp_section (gimple_seq); gimple *gimple_build_omp_master (gimple_seq); gimple *gimple_build_omp_grid_body (gimple_seq); -gimple *gimple_build_omp_taskgroup (gimple_seq); +gimple *gimple_build_omp_taskgroup (gimple_seq, tree); gomp_continue *gimple_build_omp_continue (tree, tree); gomp_ordered *gimple_build_omp_ordered (gimple_seq, tree); gimple *gimple_build_omp_return (bool); @@ -4848,6 +4849,40 @@ gimple_omp_ordered_set_clauses (gomp_ord } +/* Return the clauses associated with OMP_TASKGROUP statement GS. */ + +static inline tree +gimple_omp_taskgroup_clauses (const gimple *gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TASKGROUP); + return + static_cast (gs)->clauses; +} + + +/* Return a pointer to the clauses associated with OMP taskgroup statement + GS. */ + +static inline tree * +gimple_omp_taskgroup_clauses_ptr (gimple *gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TASKGROUP); + return &static_cast (gs)->clauses; +} + + +/* Set CLAUSES to be the clauses associated with OMP taskgroup statement + GS. */ + +static inline void +gimple_omp_taskgroup_set_clauses (gimple *gs, tree clauses) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_TASKGROUP); + static_cast (gs)->clauses + = clauses; +} + + /* Return the kind of the OMP_FOR statemement G. */ static inline int --- gcc/tree.h.jj 2017-05-24 11:46:34.159337458 +0200 +++ gcc/tree.h 2017-05-24 11:56:00.106183217 +0200 @@ -1299,9 +1299,9 @@ extern void protected_set_expr_location /* Generic accessors for OMP nodes that keep the body as operand 0, and clauses as operand 1. */ #define OMP_BODY(NODE) \ - TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_TASKGROUP), 0) + TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_MASTER), 0) #define OMP_CLAUSES(NODE) \ - TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SINGLE), 1) + TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_TASKGROUP), 1) /* Generic accessors for OMP nodes that keep clauses as operand 0. */ #define OMP_STANDALONE_CLAUSES(NODE) \ @@ -1362,6 +1362,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_TASKGROUP_CLAUSES(NODE) \ + TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 1) #define OMP_ORDERED_BODY(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 0) #define OMP_ORDERED_CLAUSES(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 1) @@ -1576,24 +1578,30 @@ extern void protected_set_expr_location OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDERED), 0) #define OMP_CLAUSE_REDUCTION_CODE(NODE) \ - (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->omp_clause.subcode.reduction_code) + (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION)->omp_clause.subcode.reduction_code) #define OMP_CLAUSE_REDUCTION_INIT(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 1) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 1) #define OMP_CLAUSE_REDUCTION_MERGE(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 2) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 2) #define OMP_CLAUSE_REDUCTION_GIMPLE_INIT(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init #define OMP_CLAUSE_REDUCTION_GIMPLE_MERGE(NODE) \ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_merge #define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 3) #define OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER(NODE) \ - OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 4) + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION), 4) /* True if a REDUCTION clause may reference the original list item (omp_orig) in its OMP_CLAUSE_REDUCTION_{,GIMPLE_}INIT. */ #define OMP_CLAUSE_REDUCTION_OMP_ORIG_REF(NODE) \ - (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->base.public_flag) + (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \ + OMP_CLAUSE_IN_REDUCTION)->base.public_flag) /* True if a LINEAR clause doesn't need copy in. True for iterator vars which are always initialized inside of the loop construct, false otherwise. */ --- gcc/tree-pretty-print.c.jj 2017-05-24 11:46:27.181425667 +0200 +++ gcc/tree-pretty-print.c 2017-05-24 11:56:00.107183204 +0200 @@ -428,6 +428,11 @@ dump_omp_clause (pretty_printer *pp, tre pp_right_paren (pp); break; + case OMP_CLAUSE_TASK_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + pp_string (pp, OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_IN_REDUCTION + ? "in_" : "task_"); + /* FALLTHRU */ case OMP_CLAUSE_REDUCTION: pp_string (pp, "reduction("); if (OMP_CLAUSE_REDUCTION_CODE (clause) != ERROR_MARK) @@ -3130,6 +3135,7 @@ dump_generic_node (pretty_printer *pp, t case OMP_TASKGROUP: pp_string (pp, "#pragma omp taskgroup"); + dump_omp_clauses (pp, OMP_TASKGROUP_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_ORDERED: --- gcc/gimple.def.jj 2017-05-24 11:33:38.031148416 +0200 +++ gcc/gimple.def 2017-05-24 11:56:00.107183204 +0200 @@ -279,9 +279,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_TASKGROUP represents #pragma omp taskgroup. + BODY is the sequence of statements inside the taskgroup section. + CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ +DEFGSCODE(GIMPLE_OMP_TASKGROUP, "gimple_omp_taskgroup", GSS_OMP_SINGLE_LAYOUT) /* GIMPLE_OMP_PARALLEL represents --- gcc/c/c-parser.c.jj 2017-05-24 11:46:31.022377113 +0200 +++ gcc/c/c-parser.c 2017-05-24 11:56:00.111183154 +0200 @@ -10515,7 +10515,9 @@ c_parser_omp_clause_name (c_parser *pars result = PRAGMA_OACC_CLAUSE_HOST; break; case 'i': - if (!strcmp ("inbranch", p)) + if (!strcmp ("in_reduction", p)) + result = PRAGMA_OMP_CLAUSE_IN_REDUCTION; + else if (!strcmp ("inbranch", p)) result = PRAGMA_OMP_CLAUSE_INBRANCH; else if (!strcmp ("independent", p)) result = PRAGMA_OACC_CLAUSE_INDEPENDENT; @@ -10609,7 +10611,9 @@ c_parser_omp_clause_name (c_parser *pars result = PRAGMA_OACC_CLAUSE_SELF; break; case 't': - if (!strcmp ("taskgroup", p)) + if (!strcmp ("task_reduction", p)) + result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION; + else if (!strcmp ("taskgroup", p)) result = PRAGMA_OMP_CLAUSE_TASKGROUP; else if (!strcmp ("thread_limit", p)) result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT; @@ -10868,6 +10872,8 @@ c_parser_omp_variable_list (c_parser *pa /* FALLTHROUGH */ case OMP_CLAUSE_DEPEND: case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) { tree low_bound = NULL_TREE, length = NULL_TREE; @@ -12164,10 +12170,15 @@ c_parser_omp_clause_private (c_parser *p reduction-operator: One of: + * - & ^ | && || - identifier */ + identifier + + OpenMP 5.0: + in_reduction ( reduction-operator : variable-list ) + task_reduction ( reduction-operator : variable-list ) */ static tree -c_parser_omp_clause_reduction (c_parser *parser, tree list) +c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind, + tree list) { location_t clause_loc = c_parser_peek_token (parser)->location; if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) @@ -12231,8 +12242,7 @@ c_parser_omp_clause_reduction (c_parser { tree nl, c; - nl = c_parser_omp_variable_list (parser, clause_loc, - OMP_CLAUSE_REDUCTION, list); + nl = c_parser_omp_variable_list (parser, clause_loc, kind, list); for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) { tree d = OMP_CLAUSE_DECL (c), type; @@ -13374,7 +13384,9 @@ c_parser_oacc_all_clauses (c_parser *par c_name = "private"; break; case PRAGMA_OACC_CLAUSE_REDUCTION: - clauses = c_parser_omp_clause_reduction (parser, clauses); + clauses + = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, + clauses); c_name = "reduction"; break; case PRAGMA_OACC_CLAUSE_SELF: @@ -13504,6 +13516,12 @@ c_parser_omp_all_clauses (c_parser *pars clauses = c_parser_omp_clause_if (parser, clauses, true); c_name = "if"; break; + case PRAGMA_OMP_CLAUSE_IN_REDUCTION: + clauses + = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION, + clauses); + c_name = "in_reduction"; + break; case PRAGMA_OMP_CLAUSE_LASTPRIVATE: clauses = c_parser_omp_clause_lastprivate (parser, clauses); c_name = "lastprivate"; @@ -13537,7 +13555,9 @@ c_parser_omp_all_clauses (c_parser *pars c_name = "private"; break; case PRAGMA_OMP_CLAUSE_REDUCTION: - clauses = c_parser_omp_clause_reduction (parser, clauses); + clauses + = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, + clauses); c_name = "reduction"; break; case PRAGMA_OMP_CLAUSE_SCHEDULE: @@ -13548,6 +13568,12 @@ c_parser_omp_all_clauses (c_parser *pars clauses = c_parser_omp_clause_shared (parser, clauses); c_name = "shared"; break; + case PRAGMA_OMP_CLAUSE_TASK_REDUCTION: + clauses + = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION, + clauses); + c_name = "task_reduction"; + break; case PRAGMA_OMP_CLAUSE_UNTIED: clauses = c_parser_omp_clause_untied (parser, clauses); c_name = "untied"; @@ -15817,7 +15843,8 @@ c_parser_omp_single (location_t loc, c_p | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) static tree c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p) @@ -15862,15 +15889,22 @@ c_parser_omp_taskyield (c_parser *parser /* OpenMP 4.0: # pragma omp taskgroup new-line + + OpenMP 5.0: + # pragma omp taskgroup taskgroup-clause[optseq] new-line */ +#define OMP_TASKGROUP_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) + static tree -c_parser_omp_taskgroup (c_parser *parser, bool *if_p) +c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p) { - location_t loc = c_parser_peek_token (parser)->location; - c_parser_skip_to_pragma_eol (parser); - return c_finish_omp_taskgroup (loc, c_parser_omp_structured_block (parser, - if_p)); + tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK, + "#pragma omp taskgroup"); + + tree body = c_parser_omp_structured_block (parser, if_p); + return c_finish_omp_taskgroup (loc, body, clauses); } /* OpenMP 4.0: @@ -17380,7 +17414,9 @@ c_parser_omp_declare (c_parser *parser, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) static tree c_parser_omp_taskloop (location_t loc, c_parser *parser, @@ -17401,7 +17437,6 @@ c_parser_omp_taskloop (location_t loc, c tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; if (cclauses == NULL) cclauses = cclauses_buf; - mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION); c_parser_consume_token (parser); if (!flag_openmp) /* flag_openmp_simd */ return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, @@ -17521,7 +17556,7 @@ c_parser_omp_construct (c_parser *parser stmt = c_parser_omp_task (loc, parser, if_p); break; case PRAGMA_OMP_TASKGROUP: - stmt = c_parser_omp_taskgroup (parser, if_p); + stmt = c_parser_omp_taskgroup (loc, parser, if_p); break; case PRAGMA_OMP_TASKLOOP: strcpy (p_name, "#pragma omp"); @@ -17838,7 +17873,9 @@ c_parser_cilk_all_clauses (c_parser *par break; case PRAGMA_CILK_CLAUSE_REDUCTION: /* Use the OpenMP counterpart. */ - clauses = c_parser_omp_clause_reduction (parser, clauses); + clauses + = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, + clauses); break; default: c_parser_error (parser, "expected %<#pragma simd%> clause"); --- gcc/c/c-typeck.c.jj 2017-05-24 11:46:31.399372347 +0200 +++ gcc/c/c-typeck.c 2017-05-24 11:56:00.114183116 +0200 @@ -12309,7 +12309,9 @@ handle_omp_array_sections_1 (tree c, tre if (!integer_nonzerop (length)) { if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { if (integer_zerop (length)) { @@ -12375,7 +12377,9 @@ handle_omp_array_sections_1 (tree c, tre if (tree_int_cst_equal (size, low_bound)) { if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { error_at (OMP_CLAUSE_LOCATION (c), "zero length array section in %qs clause", @@ -12394,7 +12398,9 @@ handle_omp_array_sections_1 (tree c, tre else if (length == NULL_TREE) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND - && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION) + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) maybe_zero_len = true; if (first_non_one == types.length ()) first_non_one++; @@ -12430,7 +12436,9 @@ handle_omp_array_sections_1 (tree c, tre else if (length == NULL_TREE) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND - && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION) + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) maybe_zero_len = true; if (first_non_one == types.length ()) first_non_one++; @@ -12602,7 +12610,9 @@ handle_omp_array_sections (tree c, enum if (i > first_non_one && ((length && integer_nonzerop (length)) - || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)) continue; if (length) l = fold_convert (sizetype, length); @@ -12630,7 +12640,9 @@ handle_omp_array_sections (tree c, enum tree eltype = TREE_TYPE (types[num - 1]); while (TREE_CODE (eltype) == ARRAY_TYPE) eltype = TREE_TYPE (eltype); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { if (integer_zerop (size) || integer_zerop (size_in_bytes (eltype))) @@ -12654,7 +12666,9 @@ handle_omp_array_sections (tree c, enum } if (side_effects) size = build2 (COMPOUND_EXPR, sizetype, side_effects, size); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) { size = size_binop (MINUS_EXPR, size, size_one_node); size = c_fully_fold (size, false, NULL); @@ -12840,6 +12854,8 @@ c_finish_omp_clauses (tree clauses, enum goto check_dup_generic; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: need_implicitly_determined = true; t = OMP_CLAUSE_DECL (c); if (TREE_CODE (t) == TREE_LIST) --- gcc/tree.c.jj 2017-05-24 11:46:33.961339961 +0200 +++ gcc/tree.c 2017-05-24 11:56:00.116183090 +0200 @@ -266,6 +266,8 @@ unsigned const char omp_clause_num_ops[] 1, /* OMP_CLAUSE_FIRSTPRIVATE */ 2, /* OMP_CLAUSE_LASTPRIVATE */ 5, /* OMP_CLAUSE_REDUCTION */ + 5, /* OMP_CLAUSE_TASK_REDUCTION */ + 5, /* OMP_CLAUSE_IN_REDUCTION */ 1, /* OMP_CLAUSE_COPYIN */ 1, /* OMP_CLAUSE_COPYPRIVATE */ 3, /* OMP_CLAUSE_LINEAR */ @@ -338,6 +340,8 @@ const char * const omp_clause_code_name[ "firstprivate", "lastprivate", "reduction", + "task_reduction", + "in_reduction", "copyin", "copyprivate", "linear", @@ -12042,6 +12046,8 @@ walk_tree_1 (tree *tp, walk_tree_fn func WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: { int i; for (i = 0; i < 5; i++) --- gcc/tree-streamer-out.c.jj 2017-05-24 11:33:38.022148530 +0200 +++ gcc/tree-streamer-out.c 2017-05-24 11:56:00.116183090 +0200 @@ -395,6 +395,8 @@ pack_ts_omp_clause_value_fields (struct OMP_CLAUSE_PROC_BIND_KIND (expr)); break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: bp_pack_enum (bp, tree_code, MAX_TREE_CODES, OMP_CLAUSE_REDUCTION_CODE (expr)); break; @@ -852,12 +854,18 @@ write_ts_omp_clause_tree_pointers (struc int i; for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++) stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p); - if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION) + switch (OMP_CLAUSE_CODE (expr)) { + case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: /* We don't stream these right now, handle it if streaming of them is needed. */ gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL); gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL); + break; + default: + break; } stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p); } --- gcc/tree-streamer-in.c.jj 2017-05-24 11:33:38.363144220 +0200 +++ gcc/tree-streamer-in.c 2017-05-24 11:56:00.117183078 +0200 @@ -445,6 +445,8 @@ unpack_ts_omp_clause_value_fields (struc OMP_CLAUSE_PROC_BIND_LAST); break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: OMP_CLAUSE_REDUCTION_CODE (expr) = bp_unpack_enum (bp, tree_code, MAX_TREE_CODES); break; --- gcc/gimple.c.jj 2017-05-24 11:33:38.369144144 +0200 +++ gcc/gimple.c 2017-05-24 11:56:00.118183065 +0200 @@ -857,7 +857,7 @@ gimple_build_omp_critical (gimple_seq bo BODY is sequence of statements inside the for loop. KIND is the `for' variant. - CLAUSES, are any of the construct's clauses. + CLAUSES are any of the construct's clauses. COLLAPSE is the collapse count. PRE_BODY is the sequence of statements that are loop invariant. */ @@ -883,7 +883,7 @@ gimple_build_omp_for (gimple_seq body, i /* Build a GIMPLE_OMP_PARALLEL statement. BODY is sequence of statements which are executed in parallel. - CLAUSES, are the OMP parallel construct's clauses. + CLAUSES are the OMP parallel construct's clauses. CHILD_FN is the function created for the parallel threads to execute. DATA_ARG are the shared data argument(s). */ @@ -906,7 +906,7 @@ gimple_build_omp_parallel (gimple_seq bo /* Build a GIMPLE_OMP_TASK statement. BODY is sequence of statements which are executed by the explicit task. - CLAUSES, are the OMP parallel construct's clauses. + CLAUSES are the OMP task construct's clauses. CHILD_FN is the function created for the parallel threads to execute. DATA_ARG are the shared data argument(s). COPY_FN is the optional function for firstprivate initialization. @@ -977,12 +977,14 @@ gimple_build_omp_grid_body (gimple_seq b /* Build a GIMPLE_OMP_TASKGROUP statement. BODY is the sequence of statements to be executed by the taskgroup - construct. */ + construct. + CLAUSES are any of the construct's clauses. */ gimple * -gimple_build_omp_taskgroup (gimple_seq body) +gimple_build_omp_taskgroup (gimple_seq body, tree clauses) { gimple *p = gimple_alloc (GIMPLE_OMP_TASKGROUP, 0); + gimple_omp_taskgroup_set_clauses (p, clauses); if (body) gimple_omp_set_body (p, body); @@ -1817,6 +1819,11 @@ gimple_copy (gimple *stmt) gimple_omp_ordered_set_clauses (as_a (copy), t); goto copy_omp_body; + case GIMPLE_OMP_TASKGROUP: + t = unshare_expr (gimple_omp_taskgroup_clauses (stmt)); + gimple_omp_taskgroup_set_clauses (copy, t); + goto copy_omp_body; + case GIMPLE_OMP_SECTIONS: t = unshare_expr (gimple_omp_sections_clauses (stmt)); gimple_omp_sections_set_clauses (copy, t); @@ -1829,7 +1836,6 @@ gimple_copy (gimple *stmt) case GIMPLE_OMP_TEAMS: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: - case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_GRID_BODY: copy_omp_body: new_seq = gimple_seq_copy (gimple_omp_body (stmt)); --- gcc/c-family/c-common.h.jj 2017-05-24 11:46:28.793405290 +0200 +++ gcc/c-family/c-common.h 2017-05-24 11:56:00.118183065 +0200 @@ -1280,7 +1280,7 @@ enum c_omp_region_type }; extern tree c_finish_omp_master (location_t, tree); -extern tree c_finish_omp_taskgroup (location_t, tree); +extern tree c_finish_omp_taskgroup (location_t, tree, tree); extern tree c_finish_omp_critical (location_t, tree, tree, tree); extern tree c_finish_omp_ordered (location_t, tree, tree); extern void c_finish_omp_barrier (location_t); --- gcc/c-family/c-omp.c.jj 2017-05-24 11:33:37.966149238 +0200 +++ gcc/c-family/c-omp.c 2017-05-24 11:56:00.119183052 +0200 @@ -70,7 +70,7 @@ c_finish_oacc_wait (location_t loc, tree } /* Complete a #pragma omp master construct. STMT is the structured-block - that follows the pragma. LOC is the l*/ + that follows the pragma. LOC is the location of the #pragma. */ tree c_finish_omp_master (location_t loc, tree stmt) @@ -80,18 +80,21 @@ 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*/ +/* Complete a #pragma omp taskgroup construct. BODY is the structured-block + that follows the pragma. LOC is the location of the #pragma. */ tree -c_finish_omp_taskgroup (location_t loc, tree stmt) +c_finish_omp_taskgroup (location_t loc, tree body, tree clauses) { - tree t = add_stmt (build1 (OMP_TASKGROUP, void_type_node, stmt)); - SET_EXPR_LOCATION (t, loc); - return t; + tree stmt = make_node (OMP_TASKGROUP); + TREE_TYPE (stmt) = void_type_node; + OMP_TASKGROUP_BODY (stmt) = body; + OMP_TASKGROUP_CLAUSES (stmt) = clauses; + SET_EXPR_LOCATION (stmt, loc); + return add_stmt (stmt); } -/* Complete a #pragma omp critical construct. STMT is the structured-block +/* Complete a #pragma omp critical construct. BODY 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. */ @@ -1031,6 +1034,7 @@ c_omp_split_clauses (location_t loc, enu case OMP_CLAUSE_MERGEABLE: case OMP_CLAUSE_NOGROUP: case OMP_CLAUSE_PRIORITY: + case OMP_CLAUSE_IN_REDUCTION: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break; /* Duplicate this to all of taskloop, distribute, for and simd. */ @@ -1298,7 +1302,24 @@ c_omp_split_clauses (location_t loc, enu else if (code == OMP_SECTIONS || code == OMP_PARALLEL) s = C_OMP_CLAUSE_SPLIT_PARALLEL; else if (code == OMP_SIMD) - s = C_OMP_CLAUSE_SPLIT_SIMD; + { + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) + != 0) + { + c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses), + OMP_CLAUSE_REDUCTION); + OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses); + OMP_CLAUSE_REDUCTION_CODE (c) + = OMP_CLAUSE_REDUCTION_CODE (clauses); + OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) + = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses); + OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) + = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses); + OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; + cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c; + } + s = C_OMP_CLAUSE_SPLIT_SIMD; + } else s = C_OMP_CLAUSE_SPLIT_TEAMS; break; --- gcc/c-family/c-pragma.h.jj 2017-05-24 11:33:37.988148960 +0200 +++ gcc/c-family/c-pragma.h 2017-05-24 11:56:00.119183052 +0200 @@ -80,8 +80,8 @@ enum pragma_kind { }; -/* All clauses defined by OpenACC 2.0, and OpenMP 2.5, 3.0, 3.1, 4.0 and 4.5. - Used internally by both C and C++ parsers. */ +/* All clauses defined by OpenACC 2.0, and OpenMP 2.5, 3.0, 3.1, 4.0, 4.5 + and 5.0. Used internally by both C and C++ parsers. */ enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_NONE = 0, @@ -101,6 +101,7 @@ enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_GRAINSIZE, PRAGMA_OMP_CLAUSE_HINT, PRAGMA_OMP_CLAUSE_IF, + PRAGMA_OMP_CLAUSE_IN_REDUCTION, PRAGMA_OMP_CLAUSE_INBRANCH, PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR, PRAGMA_OMP_CLAUSE_LASTPRIVATE, @@ -126,6 +127,7 @@ enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_SHARED, PRAGMA_OMP_CLAUSE_SIMD, PRAGMA_OMP_CLAUSE_SIMDLEN, + PRAGMA_OMP_CLAUSE_TASK_REDUCTION, PRAGMA_OMP_CLAUSE_TASKGROUP, PRAGMA_OMP_CLAUSE_THREAD_LIMIT, PRAGMA_OMP_CLAUSE_THREADS, --- gcc/omp-low.c.jj 2017-05-24 11:46:38.000000000 +0200 +++ gcc/omp-low.c 2017-05-24 15:16:02.939448638 +0200 @@ -1053,9 +1053,9 @@ scan_sharing_clauses (tree clauses, omp_ goto do_private; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: decl = OMP_CLAUSE_DECL (c); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION - && TREE_CODE (decl) == MEM_REF) + if (TREE_CODE (decl) == MEM_REF) { tree t = TREE_OPERAND (decl, 0); if (TREE_CODE (t) == POINTER_PLUS_EXPR) @@ -1382,6 +1382,7 @@ scan_sharing_clauses (tree clauses, omp_ break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: decl = OMP_CLAUSE_DECL (c); if (TREE_CODE (decl) != MEM_REF) { @@ -1510,7 +1511,9 @@ scan_sharing_clauses (tree clauses, omp_ if (scan_array_reductions) { for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) { scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx); @@ -2196,7 +2199,7 @@ scan_omp_for (gomp_for *stmt, omp_contex if (tgt && is_oacc_kernels (tgt)) { - /* Strip out reductions, as they are not handled yet. */ + /* Strip out reductions, as they are not handled yet. */ tree *prev_ptr = &clauses; while (tree probe = *prev_ptr) @@ -3616,6 +3619,7 @@ lower_rec_input_clauses (tree clauses, g sctx.max_vf = 1; break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF || is_variable_sized (OMP_CLAUSE_DECL (c))) sctx.max_vf = 1; @@ -3666,6 +3670,7 @@ lower_rec_input_clauses (tree clauses, g lastprivate_firstprivate = true; break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)) reduction_omp_orig_ref = true; break; @@ -3732,7 +3737,9 @@ lower_rec_input_clauses (tree clauses, g } new_var = var = OMP_CLAUSE_DECL (c); - if (c_kind == OMP_CLAUSE_REDUCTION && TREE_CODE (var) == MEM_REF) + if ((c_kind == OMP_CLAUSE_REDUCTION + || c_kind == OMP_CLAUSE_IN_REDUCTION) + && TREE_CODE (var) == MEM_REF) { var = TREE_OPERAND (var, 0); if (TREE_CODE (var) == POINTER_PLUS_EXPR) @@ -3759,7 +3766,8 @@ lower_rec_input_clauses (tree clauses, g continue; } /* C/C++ array section reductions. */ - else if (c_kind == OMP_CLAUSE_REDUCTION + else if ((c_kind == OMP_CLAUSE_REDUCTION + || c_kind == OMP_CLAUSE_IN_REDUCTION) && var != OMP_CLAUSE_DECL (c)) { if (pass == 0) @@ -4111,7 +4119,8 @@ lower_rec_input_clauses (tree clauses, g new_var = build_simple_mem_ref_loc (clause_loc, new_var); } - else if (c_kind == OMP_CLAUSE_REDUCTION + else if ((c_kind == OMP_CLAUSE_REDUCTION + || c_kind == OMP_CLAUSE_IN_REDUCTION) && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) { if (pass == 0) @@ -4346,6 +4355,7 @@ lower_rec_input_clauses (tree clauses, g break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: /* OpenACC reductions are initialized using the GOACC_REDUCTION internal function. */ if (is_gimple_omp_oacc (ctx->stmt)) --- gcc/lto-streamer-out.c.jj 2017-05-24 11:33:38.108147443 +0200 +++ gcc/lto-streamer-out.c 2017-05-24 11:56:00.120183040 +0200 @@ -1346,6 +1346,8 @@ hash_tree (struct streamer_tree_cache_d val = OMP_CLAUSE_PROC_BIND_KIND (t); break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: val = OMP_CLAUSE_REDUCTION_CODE (t); break; default: --- gcc/tree-core.h.jj 2017-05-24 11:48:23.287957942 +0200 +++ gcc/tree-core.h 2017-05-24 11:56:00.120183040 +0200 @@ -269,6 +269,12 @@ enum omp_clause_code { reductions. */ OMP_CLAUSE_REDUCTION, + /* OpenMP clause: task_reduction (operator:variable_list). */ + OMP_CLAUSE_TASK_REDUCTION, + + /* OpenMP clause: in_reduction (operator:variable_list). */ + OMP_CLAUSE_IN_REDUCTION, + /* OpenMP clause: copyin (variable_list). */ OMP_CLAUSE_COPYIN, @@ -1086,7 +1092,7 @@ struct GTY(()) tree_base { OMP_CLAUSE_MAP OMP_CLAUSE_REDUCTION_OMP_ORIG_REF in - OMP_CLAUSE_REDUCTION + OMP_CLAUSE_{,TASK_,IN_}REDUCTION TRANSACTION_EXPR_RELAXED in TRANSACTION_EXPR --- gcc/gimplify.c.jj 2017-05-24 11:47:49.536384602 +0200 +++ gcc/gimplify.c 2017-05-24 14:45:26.612050315 +0200 @@ -7550,10 +7550,14 @@ gimplify_scan_omp_clauses (tree *list_p, } goto do_add; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT; /* OpenACC permits reductions on private variables. */ - if (!(region_type & ORT_ACC)) - check_non_private = "reduction"; + if (!(region_type & ORT_ACC) + /* taskgroup is actually not a worksharing region. */ + && code != OMP_TASKGROUP) + check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)]; decl = OMP_CLAUSE_DECL (c); if (TREE_CODE (decl) == MEM_REF) { @@ -8239,7 +8243,9 @@ gimplify_scan_omp_clauses (tree *list_p, && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) flags |= GOVD_MAP_0LEN_ARRAY; omp_add_variable (ctx, decl, flags); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) { omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c), @@ -9155,6 +9161,8 @@ gimplify_adjust_omp_clauses (gimple_seq break; case OMP_CLAUSE_REDUCTION: + case OMP_CLAUSE_IN_REDUCTION: + case OMP_CLAUSE_TASK_REDUCTION: decl = OMP_CLAUSE_DECL (c); /* OpenACC reductions need a present_or_copy data clause. Add one if necessary. Error is the reduction is private. */ @@ -11859,7 +11867,12 @@ gimplify_expr (tree *expr_p, gimple_seq g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY); body = NULL; gimple_seq_add_stmt (&body, g); - g = gimple_build_omp_taskgroup (body); + tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p); + gimplify_scan_omp_clauses (pclauses, pre_p, ORT_WORKSHARE, + OMP_TASKGROUP); + gimplify_adjust_omp_clauses (pre_p, body, pclauses, + OMP_TASKGROUP); + g = gimple_build_omp_taskgroup (body, *pclauses); } break; case OMP_ORDERED: --- gcc/tree-inline.c.jj 2017-05-24 11:48:20.650991277 +0200 +++ gcc/tree-inline.c 2017-05-24 11:56:00.124182989 +0200 @@ -1495,7 +1495,8 @@ remap_gimple_stmt (gimple *stmt, copy_bo case GIMPLE_OMP_TASKGROUP: s1 = remap_gimple_seq (gimple_omp_body (stmt), id); - copy = gimple_build_omp_taskgroup (s1); + copy = gimple_build_omp_taskgroup + (s1, gimple_omp_taskgroup_clauses (stmt)); break; case GIMPLE_OMP_ORDERED: