From patchwork Fri Jul 12 07:58:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1131193 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-504964-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="VrR8Ig8v"; dkim-atps=neutral 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 45lQL26Q5kz9s8m for ; Fri, 12 Jul 2019 17:59:05 +1000 (AEST) 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=NqH7cFyszjnqQl7GvtzbdvrbDdFSAIj9Wm9Zz16k6p5 nA8aFA4rPj8uS35jEYOaY8rxPWMTctH/QFUflcI70zv+GMez5el4xdgo2RvPNwf/ WqT98G0ZSkEwrRuulmxLCMvlzkrBe/xd0OPdkyrs8SIMJrc6WQT1R+7xHfE3uiaY = 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=QBDbPB9aLuX9ejRS/vGHqaTu28s=; b=VrR8Ig8vfjLNmoIYm cqvR/PyAnOQF5o3hOGuxuIu1tl7qCLBQXf0pkCdY0UznY2/s7D0DZeiYpHV09Wf4 cTDqHvRSu6sarfNfOghV56iKkukqj/i7o33hv+4jD/QHfkuh2bWFOFsL1K0p8g5z QxpQXM226seCxCHhOoq9VH7w4I= Received: (qmail 32567 invoked by alias); 12 Jul 2019 07:58:58 -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 32559 invoked by uid 89); 12 Jul 2019 07:58:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=sk:tree-pr, sk:treepr, Internally, semanticsc 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; Fri, 12 Jul 2019 07:58:55 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3868683F40 for ; Fri, 12 Jul 2019 07:58:54 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-236.ams2.redhat.com [10.36.116.236]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B00D4600CD for ; Fri, 12 Jul 2019 07:58:53 +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 x6C7wpeJ008515 for ; Fri, 12 Jul 2019 09:58:51 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id x6C7wnMH008514 for gcc-patches@gcc.gnu.org; Fri, 12 Jul 2019 09:58:49 +0200 Date: Fri, 12 Jul 2019 09:58:49 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [committed] Add OpenMP 5.0 order(concurrent) clause parsing support Message-ID: <20190712075849.GW2125@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.11.3 (2019-02-01) X-IsSubscribed: yes Hi! This adds parsing support for a new clause, but currently just ignores it besides checking some restrictions (will add further ones later). For worksharing loop the spec says: "If an order(concurrent) clause is present, then after assigning the iterations of the associated loops to their respective threads, as specified in ..., the iterations may be executed in any order, including concurrently." so to some extent it is a hint to the compiler to do lots of smarts it might want. It is stronger than say the loop->safelen = INT_MAX, in that in the source code except for the data sharing clauses on the constructs there should be no dependencies; but the problem might be with the data sharing clauses, the loop can have e.g. reductions and we need to carefully think about the consequences. 2019-07-12 Jakub Jelinek * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_ORDER. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add order clause entries. (walk_tree_1): Handle OMP_CLAUSE_ORDER. * tree-pretty-print.c (dump_omp_clause): Likewise. * gimplify.c (gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses): Likewise. * omp-low.c (scan_sharing_clauses): Likewise. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Likewise. c-family/ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ORDER. * c-omp.c (c_omp_split_clauses): Handle splitting of OMP_CLAUSE_ORDER. c/ * c-parser.c (c_parser_omp_clause_name): Handle order clause. (c_parser_omp_clause_order): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ORDER. (OMP_SIMD_CLAUSE_MASK, OMP_FOR_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_ORDER. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_ORDER. cp/ * parser.c (cp_parser_omp_clause_name): Handle order clause. (cp_parser_omp_clause_order): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ORDER. (OMP_SIMD_CLAUSE_MASK, OMP_FOR_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_ORDER. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_ORDER. * pt.c (tsubst_omp_clauses): Likewise. testsuite/ * c-c++-common/gomp/order-1.c: New test. * c-c++-common/gomp/order-2.c: New test. Jakub --- gcc/tree-core.h.jj 2019-07-10 15:53:01.150520339 +0200 +++ gcc/tree-core.h 2019-07-11 12:22:46.116779007 +0200 @@ -448,6 +448,9 @@ enum omp_clause_code { /* OpenMP clause: defaultmap (tofrom: scalar). */ OMP_CLAUSE_DEFAULTMAP, + /* OpenMP clause: order (concurrent). */ + OMP_CLAUSE_ORDER, + /* Internally used only clause, holding SIMD uid. */ OMP_CLAUSE__SIMDUID_, --- gcc/tree.c.jj 2019-07-10 15:52:27.852038983 +0200 +++ gcc/tree.c 2019-07-11 12:24:19.316343620 +0200 @@ -342,7 +342,8 @@ unsigned const char omp_clause_num_ops[] 0, /* OMP_CLAUSE_THREADS */ 0, /* OMP_CLAUSE_SIMD */ 1, /* OMP_CLAUSE_HINT */ - 0, /* OMP_CLAUSE_DEFALTMAP */ + 0, /* OMP_CLAUSE_DEFAULTMAP */ + 0, /* OMP_CLAUSE_ORDER */ 1, /* OMP_CLAUSE__SIMDUID_ */ 0, /* OMP_CLAUSE__SIMT_ */ 0, /* OMP_CLAUSE_INDEPENDENT */ @@ -424,6 +425,7 @@ const char * const omp_clause_code_name[ "simd", "hint", "defaultmap", + "order", "_simduid_", "_simt_", "independent", @@ -12340,6 +12342,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: case OMP_CLAUSE_TILE: --- gcc/tree-pretty-print.c.jj 2019-07-04 23:39:00.809134701 +0200 +++ gcc/tree-pretty-print.c 2019-07-11 12:25:54.247881552 +0200 @@ -1040,6 +1040,10 @@ dump_omp_clause (pretty_printer *pp, tre pp_right_paren (pp); break; + case OMP_CLAUSE_ORDER: + pp_string (pp, "order(concurrent)"); + break; + case OMP_CLAUSE__SIMDUID_: pp_string (pp, "_simduid_("); dump_generic_node (pp, OMP_CLAUSE__SIMDUID__DECL (clause), --- gcc/gimplify.c.jj 2019-07-11 10:25:22.002469647 +0200 +++ gcc/gimplify.c 2019-07-11 12:29:04.711948170 +0200 @@ -9263,6 +9263,7 @@ gimplify_scan_omp_clauses (tree *list_p, case OMP_CLAUSE_NOGROUP: case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_IF_PRESENT: case OMP_CLAUSE_FINALIZE: break; @@ -10223,6 +10224,7 @@ gimplify_adjust_omp_clauses (gimple_seq case OMP_CLAUSE_SIMD: case OMP_CLAUSE_HINT: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_USE_DEVICE_PTR: case OMP_CLAUSE_IS_DEVICE_PTR: case OMP_CLAUSE_ASYNC: --- gcc/omp-low.c.jj 2019-07-10 15:52:27.864038796 +0200 +++ gcc/omp-low.c 2019-07-11 12:29:30.650548686 +0200 @@ -1402,6 +1402,7 @@ scan_sharing_clauses (tree clauses, omp_ case OMP_CLAUSE_SIMD: case OMP_CLAUSE_NOGROUP: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_CLAUSE_GANG: @@ -1595,6 +1596,7 @@ scan_sharing_clauses (tree clauses, omp_ case OMP_CLAUSE_SIMD: case OMP_CLAUSE_NOGROUP: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_USE_DEVICE_PTR: case OMP_CLAUSE_NONTEMPORAL: case OMP_CLAUSE_ASYNC: --- gcc/tree-nested.c.jj 2019-07-03 07:02:16.456989949 +0200 +++ gcc/tree-nested.c 2019-07-11 12:27:26.815455914 +0200 @@ -1343,6 +1343,7 @@ convert_nonlocal_omp_clauses (tree *pcla case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_SEQ: case OMP_CLAUSE_INDEPENDENT: case OMP_CLAUSE_AUTO: @@ -2073,6 +2074,7 @@ convert_local_omp_clauses (tree *pclause case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_SEQ: case OMP_CLAUSE_INDEPENDENT: case OMP_CLAUSE_AUTO: --- gcc/c-family/c-pragma.h.jj 2019-06-10 14:18:17.364527205 +0200 +++ gcc/c-family/c-pragma.h 2019-07-11 13:42:02.943557910 +0200 @@ -114,6 +114,7 @@ enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_NUM_TASKS, PRAGMA_OMP_CLAUSE_NUM_TEAMS, PRAGMA_OMP_CLAUSE_NUM_THREADS, + PRAGMA_OMP_CLAUSE_ORDER, PRAGMA_OMP_CLAUSE_ORDERED, PRAGMA_OMP_CLAUSE_PARALLEL, PRAGMA_OMP_CLAUSE_PRIORITY, --- gcc/c-family/c-omp.c.jj 2019-07-03 06:55:33.563493065 +0200 +++ gcc/c-family/c-omp.c 2019-07-11 13:54:09.648373658 +0200 @@ -1632,6 +1632,24 @@ c_omp_split_clauses (location_t loc, enu } s = C_OMP_CLAUSE_SPLIT_PARALLEL; break; + /* order clauses are allowed on for and simd. */ + case OMP_CLAUSE_ORDER: + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0) + { + if (code == OMP_SIMD) + { + c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses), + OMP_CLAUSE_ORDER); + OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; + cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c; + s = C_OMP_CLAUSE_SPLIT_SIMD; + } + else + s = C_OMP_CLAUSE_SPLIT_FOR; + } + else + s = C_OMP_CLAUSE_SPLIT_SIMD; + break; /* Reduction is allowed on simd, for, parallel, sections, taskloop and teams. Duplicate it on all of them, but omit on for or sections if parallel is present (unless inscan, in that case --- gcc/c/c-parser.c.jj 2019-07-10 15:52:21.252141783 +0200 +++ gcc/c/c-parser.c 2019-07-11 15:16:52.330992007 +0200 @@ -11789,6 +11789,8 @@ c_parser_omp_clause_name (c_parser *pars case 'o': if (!strcmp ("ordered", p)) result = PRAGMA_OMP_CLAUSE_ORDERED; + else if (!strcmp ("order", p)) + result = PRAGMA_OMP_CLAUSE_ORDER; break; case 'p': if (!strcmp ("parallel", p)) @@ -13467,6 +13469,44 @@ c_parser_oacc_clause_wait (c_parser *par return list; } + +/* OpenMP 5.0: + order ( concurrent ) */ + +static tree +c_parser_omp_clause_order (c_parser *parser, tree list) +{ + location_t loc = c_parser_peek_token (parser)->location; + tree c; + const char *p; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + if (!c_parser_next_token_is (parser, CPP_NAME)) + { + c_parser_error (parser, "expected %"); + goto out_err; + } + p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + if (strcmp (p, "concurrent") != 0) + { + c_parser_error (parser, "expected %"); + goto out_err; + } + c_parser_consume_token (parser); + parens.skip_until_found_close (parser); + /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */ + c = build_omp_clause (loc, OMP_CLAUSE_ORDER); + OMP_CLAUSE_CHAIN (c) = list; + return c; + + out_err: + parens.skip_until_found_close (parser); + return list; +} + + /* OpenMP 2.5: ordered @@ -15092,6 +15132,10 @@ c_parser_omp_all_clauses (c_parser *pars clauses = c_parser_omp_clause_num_threads (parser, clauses); c_name = "num_threads"; break; + case PRAGMA_OMP_CLAUSE_ORDER: + clauses = c_parser_omp_clause_order (parser, clauses); + c_name = "order"; + break; case PRAGMA_OMP_CLAUSE_ORDERED: clauses = c_parser_omp_clause_ordered (parser, clauses); c_name = "ordered"; @@ -17221,7 +17265,8 @@ omp_split_clauses (location_t loc, enum | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) static tree c_parser_omp_simd (location_t loc, c_parser *parser, @@ -17277,7 +17322,8 @@ c_parser_omp_simd (location_t loc, c_par | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) static tree c_parser_omp_for (location_t loc, c_parser *parser, --- gcc/c/c-typeck.c.jj 2019-06-25 08:57:55.722515524 +0200 +++ gcc/c/c-typeck.c 2019-07-11 14:54:17.343851089 +0200 @@ -13667,6 +13667,7 @@ c_finish_omp_clauses (tree clauses, enum tree last_iterators = NULL_TREE; bool last_iterators_remove = false; tree *nogroup_seen = NULL; + tree *order_clause = NULL; /* 1 if normal/task reduction has been seen, -1 if inscan reduction has been seen, -2 if mixed inscan/normal reduction diagnosed. */ int reduction_seen = 0; @@ -14631,6 +14632,25 @@ c_finish_omp_clauses (tree clauses, enum pc = &OMP_CLAUSE_CHAIN (c); continue; + case OMP_CLAUSE_ORDER: + if (ordered_clause) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause must not be used together " + "with %"); + remove = true; + break; + } + else if (order_clause) + { + /* Silently remove duplicates. */ + remove = true; + break; + } + order_clause = pc; + pc = &OMP_CLAUSE_CHAIN (c); + continue; + case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_NUM_TEAMS: @@ -14683,6 +14703,14 @@ c_finish_omp_clauses (tree clauses, enum case OMP_CLAUSE_ORDERED: ordered_clause = c; + if (order_clause) + { + error_at (OMP_CLAUSE_LOCATION (*order_clause), + "% clause must not be used together " + "with %"); + *order_clause = OMP_CLAUSE_CHAIN (*order_clause); + order_clause = NULL; + } pc = &OMP_CLAUSE_CHAIN (c); continue; --- gcc/cp/parser.c.jj 2019-07-01 08:12:21.036657995 +0200 +++ gcc/cp/parser.c 2019-07-11 18:03:17.564992533 +0200 @@ -32528,6 +32528,8 @@ cp_parser_omp_clause_name (cp_parser *pa case 'o': if (!strcmp ("ordered", p)) result = PRAGMA_OMP_CLAUSE_ORDERED; + else if (!strcmp ("order", p)) + result = PRAGMA_OMP_CLAUSE_ORDER; break; case 'p': if (!strcmp ("parallel", p)) @@ -33919,6 +33921,50 @@ cp_parser_omp_clause_defaultmap (cp_pars return list; } +/* OpenMP 5.0: + order ( concurrent ) */ + +static tree +cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location) +{ + tree c, id; + const char *p; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + cp_parser_error (parser, "expected %"); + goto out_err; + } + else + { + id = cp_lexer_peek_token (parser->lexer)->u.value; + p = IDENTIFIER_POINTER (id); + } + if (strcmp (p, "concurrent") != 0) + { + cp_parser_error (parser, "expected %"); + goto out_err; + } + cp_lexer_consume_token (parser->lexer); + if (!parens.require_close (parser)) + goto out_err; + + /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order", location); */ + c = build_omp_clause (location, OMP_CLAUSE_ORDER); + OMP_CLAUSE_CHAIN (c) = list; + return c; + + out_err: + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; +} + /* OpenMP 2.5: ordered @@ -35510,7 +35556,8 @@ cp_parser_omp_all_clauses (cp_parser *pa c_name = "mergeable"; break; case PRAGMA_OMP_CLAUSE_NOWAIT: - clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location); + clauses = cp_parser_omp_clause_nowait (parser, clauses, + token->location); c_name = "nowait"; break; case PRAGMA_OMP_CLAUSE_NUM_TASKS: @@ -35523,6 +35570,11 @@ cp_parser_omp_all_clauses (cp_parser *pa token->location); c_name = "num_threads"; break; + case PRAGMA_OMP_CLAUSE_ORDER: + clauses = cp_parser_omp_clause_order (parser, clauses, + token->location); + c_name = "order"; + break; case PRAGMA_OMP_CLAUSE_ORDERED: clauses = cp_parser_omp_clause_ordered (parser, clauses, token->location); @@ -37560,7 +37612,8 @@ cp_omp_split_clauses (location_t loc, en | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) static tree cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok, @@ -37620,7 +37673,8 @@ cp_parser_omp_simd (cp_parser *parser, c | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) static tree cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok, --- gcc/cp/semantics.c.jj 2019-07-10 15:52:27.884038484 +0200 +++ gcc/cp/semantics.c 2019-07-11 17:49:15.283817390 +0200 @@ -6127,6 +6127,7 @@ finish_omp_clauses (tree clauses, enum c bool branch_seen = false; bool copyprivate_seen = false; bool ordered_seen = false; + bool order_seen = false; bool schedule_seen = false; bool oacc_async = false; tree last_iterators = NULL_TREE; @@ -7600,6 +7601,13 @@ finish_omp_clauses (tree clauses, enum c ordered_seen = true; break; + case OMP_CLAUSE_ORDER: + if (order_seen) + remove = true; + else + order_seen = true; + break; + case OMP_CLAUSE_INBRANCH: case OMP_CLAUSE_NOTINBRANCH: if (branch_seen) @@ -7775,6 +7783,17 @@ finish_omp_clauses (tree clauses, enum c "% clause", "ordered"); pc = &OMP_CLAUSE_CHAIN (c); continue; + case OMP_CLAUSE_ORDER: + if (ordered_seen) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause must not be used together " + "with %"); + *pc = OMP_CLAUSE_CHAIN (c); + continue; + } + pc = &OMP_CLAUSE_CHAIN (c); + continue; case OMP_CLAUSE_NOWAIT: if (copyprivate_seen) { --- gcc/cp/pt.c.jj 2019-07-10 15:52:27.873038656 +0200 +++ gcc/cp/pt.c 2019-07-11 15:50:40.065802377 +0200 @@ -16422,6 +16422,7 @@ tsubst_omp_clauses (tree clauses, enum c case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: + case OMP_CLAUSE_ORDER: case OMP_CLAUSE_INDEPENDENT: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: --- gcc/testsuite/c-c++-common/gomp/order-1.c.jj 2019-07-11 14:03:13.660001467 +0200 +++ gcc/testsuite/c-c++-common/gomp/order-1.c 2019-07-11 15:05:04.371889727 +0200 @@ -0,0 +1,53 @@ +void +f1 (int *a) +{ + int i; + #pragma omp for order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp simd order ( concurrent ) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp for simd order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; +} + +void +f2 (int *a) +{ + int i; + #pragma omp parallel for order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp parallel for simd order (concurrent) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp teams distribute parallel for order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp teams distribute parallel for simd order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp teams + { + #pragma omp distribute parallel for order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp distribute parallel for simd order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; + } + #pragma omp taskloop simd order (concurrent) + for (i = 0; i < 128; i++) + a[i]++; +} + +void +f3 (int *a) +{ + int i; + #pragma omp for order(concurrent) order(concurrent) order(concurrent) + for (i = 0; i < 128; i++) + a[i]++; +} --- gcc/testsuite/c-c++-common/gomp/order-2.c.jj 2019-07-11 15:18:43.966273619 +0200 +++ gcc/testsuite/c-c++-common/gomp/order-2.c 2019-07-11 15:18:29.729492769 +0200 @@ -0,0 +1,57 @@ +void +f1 (int *a) +{ + int i; + #pragma omp for order /* { dg-error "expected" } */ + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp for simd order : /* { dg-error "expected" } */ + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp simd order ( foobar ) /* { dg-error "expected" } */ + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp for simd order( concurrent /* { dg-error "expected" } */ + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp for simd order( concurrent : foo )/* { dg-error "expected" } */ + for (i = 0; i < 128; i++) + a[i]++; +} + +void +f2 (int *a) +{ + int i; + #pragma omp teams + #pragma omp distribute order(concurrent) /* { dg-error "'order' is not valid for '#pragma omp distribute'" } */ + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp taskloop order (concurrent) /* { dg-error "'order' is not valid for '#pragma omp taskloop'" } */ + for (i = 0; i < 128; i++) + a[i]++; + #pragma omp for order(concurrent) ordered /* { dg-error "'order' clause must not be used together with 'ordered'" } */ + for (i = 0; i < 128; i++) + { + #pragma omp ordered + a[i]++; + } + #pragma omp for ordered order(concurrent) /* { dg-error "'order' clause must not be used together with 'ordered'" } */ + for (i = 0; i < 128; i++) + { + #pragma omp ordered + a[i]++; + } + #pragma omp for ordered (1) order(concurrent) /* { dg-error "'order' clause must not be used together with 'ordered'" } */ + for (i = 0; i < 128; i++) + { + #pragma omp ordered depend (sink: i - 1) + #pragma omp ordered depend (source) + } + #pragma omp for order(concurrent)ordered (1) /* { dg-error "'order' clause must not be used together with 'ordered'" } */ + for (i = 0; i < 128; i++) + { + #pragma omp ordered depend (sink: i - 1) + #pragma omp ordered depend (source) + } +}