From patchwork Tue Mar 26 16:57:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 231477 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 CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id F08232C04FC for ; Wed, 27 Mar 2013 03:58:34 +1100 (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=T2Hh/3EVfPfFsxuT3+6ionF0ZdGHG 2NOU7Vmf6xX1Nxr1lg8ha65wR59Fd+ub8JhR4IyZ31kVrwJSrjfYoS2E9qyZLtoC dEAUojGVSZvQTTRttI5bVX0DbsOvF7pUU50to1YhOJphARBp1Ky4/RRAABhp3mFY chiVzEtI7qDqhs= 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=AMSgN3xE4R8yLjbB5M1I4JsHR0g=; b=qUe GF6P89zbD2uQsFGsqCxaUrgkNU4AukR74f62ASfy+rHNFoDF73eS6aifEDq9BSX2 ScA8CEylTpNNJHOmscF9TiWFtUkm9xUiuG5rKj1Qizk0L63ggpTjH+lnC1gsS9gw MAXdb7vPbR/SNgPgCx4TJlzRiku1Au7dSFbMaoAc= Received: (qmail 13715 invoked by alias); 26 Mar 2013 16:57:40 -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 13385 invoked by uid 89); 26 Mar 2013 16:57:22 -0000 X-Spam-SWARE-Status: No, score=-6.7 required=5.0 tests=AWL, BAYES_05, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS, TW_TM autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Tue, 26 Mar 2013 16:57:07 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2QGv6m5028970 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 26 Mar 2013 12:57:06 -0400 Received: from zalov.cz (vpn1-6-114.ams2.redhat.com [10.36.6.114]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r2QGv4xb025341 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 26 Mar 2013 12:57:05 -0400 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.cz (8.14.5/8.14.5) with ESMTP id r2QGv304018673; Tue, 26 Mar 2013 17:57:03 +0100 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id r2QGv2V8018672; Tue, 26 Mar 2013 17:57:02 +0100 Date: Tue, 26 Mar 2013 17:57:02 +0100 From: Jakub Jelinek To: Jason Merrill , Richard Henderson Cc: gcc-patches@gcc.gnu.org Subject: [gomp4] Some progress on C++ OpenMP 4.0 parsing Message-ID: <20130326165702.GL12913@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Hi! This patch adds parsing of the 19 new OpenMP 4.0 clauses, #pragma omp simd, #pragma omp for simd, #pragma omp parallel for simd, #pragma omp cancel and #pragma omp cancellation point. The hardest parts parsing-wise are still to be done (mainly #pragma omp declare reduction and #pragma omp declare simd, #pragma omp target* and related stuff perhaps won't be that hard parsing-wise, but the trouble will start at gimplification time and especially later on to decide how to support all that stuff). Any comments? 2013-03-26 Jakub Jelinek * gimple-pretty-print.c (dump_gimple_omp_for): Handle different GIMPLE_OMP_FOR kinds. * tree.def (OMP_SIMD, OMP_FOR_SIMD, OMP_DISTRIBUTE): New tree codes. * gimple.h (enum gf_mask): Add GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_KIND_FOR, GF_OMP_FOR_KIND_SIMD, GF_OMP_FOR_KIND_FOR_SIMD and GF_OMP_FOR_KIND_DISTRIBUTE. (gimple_omp_for_kind, gimple_omp_for_set_kind): New inline functions. * gimplify.c (is_gimple_stmt, gimplify_omp_for, gimplify_expr): Handle OMP_SIMD, OMP_FOR_SIMD and OMP_DISTRIBUTE. * tree.c (omp_clause_num_ops, omp_clause_code_name, walk_tree_1): Handle new OpenMP 4.0 clauses. * tree-pretty-print.c (dump_omp_clause): Likewise. (dump_generic_node): Handle OMP_SIMD, OMP_FOR_SIMD and OMP_DISTRIBUTE. * tree.h (enum omp_clause_code): Add OMP_CLAUSE_LINEAR, OMP_CLAUSE_ALIGNED, OMP_CLAUSE_DEPEND, OMP_CLAUSE_FROM, OMP_CLAUSE_TO, OMP_CLAUSE_UNIFORM, OMP_CLAUSE_MAP, OMP_CLAUSE_DEVICE, OMP_CLAUSE_DIST_SCHEDULE, OMP_CLAUSE_INBRANCH, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_PROC_BIND, OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_FOR, OMP_CLAUSE_PARALLEL, OMP_CLAUSE_SECTIONS and OMP_CLAUSE_TASKGROUP. (OMP_LOOP_CHECK): Define. (OMP_FOR_BODY, OMP_FOR_CLAUSES, OMP_FOR_INIT, OMP_FOR_COND, OMP_FOR_INCR, OMP_FOR_PRE_BODY): Use OMP_LOOP_CHECK instead of OMP_FOR_CHECK. (OMP_CLAUSE_DECL): Extend check range up to OMP_CLAUSE_MAP. (OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_ALIGNED_ALIGNMENT, OMP_CLAUSE_NUM_TEAMS_EXPR, OMP_CLAUSE_DEVICE_ID, OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR, OMP_CLAUSE_SAFELEN_EXPR, OMP_CLAUSE_SIMDLEN_EXPR): Define. (enum omp_clause_depend_kind, enum omp_clause_map_kind, enum omp_clause_proc_bind_kind): New enums. (OMP_CLAUSE_DEPEND_KIND, OMP_CLAUSE_MAP_KIND, OMP_CLAUSE_PROC_BIND_KIND): Define. (struct tree_omp_clause): Add subcode.depend_kind, subcode.map_kind and subcode.proc_bind_kind. (find_omp_clause): New prototype. * omp-builtins.def (BUILT_IN_GOMP_CANCEL, BUILT_IN_GOMP_CANCELLATION_POINT): New built-ins. * tree-flow.h (find_omp_clause): Remove prototype. c/ * c-parser.c (c_parser_omp_all_clauses): Change mask argument type from unsigned to omp_clause_mask. (c_parser_omp_for_loop): Adjust c_finish_omp_for caller. (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1. (c_parser_omp_parallel): Use omp_clause_mask type instead of unsigned for mask, use OMP_CLAUSE_MASK_1 instead of 1 for masks. cp/ * cp-tree.h (OMP_FOR_GIMPLIFYING_P): Use OMP_LOOP_CHECK instead of OMP_FOR_CHECK. (finish_omp_for): Add enum tree_code second argument. (finish_omp_cancel, finish_omp_cancellation_point): New prototypes. * cp-gimplify.c (cp_gimplify_expr, cp_genericize_r): Handle OMP_SIMD, OMP_FOR_SIMD and OMP_DISTRIBUTE. * semantics.c (finish_omp_clauses): Handle new OpenMP 4.0 clauses. (finish_omp_for): Add code argument, pass it down to make_node or c_finish_omp_for. (finish_omp_cancel, finish_omp_cancellation_point): New functions. * parser.c (cp_parser_omp_clause_name): Add parsing of new OpenMP 4.0 clauses. (cp_parser_omp_var_list_no_open): Add COLON argument, if non-NULL, accept termination by colon instead of closing paren. (cp_parser_omp_var_list, cp_parser_omp_clause_reduction): Adjust callers. (cp_parser_omp_clause_branch, cp_parser_omp_clause_cancelkind, cp_parser_omp_clause_num_teams, cp_parser_omp_clause_aligned, cp_parser_omp_clause_linear, cp_parser_omp_clause_depend, cp_parser_omp_clause_map, cp_parser_omp_clause_device, cp_parser_omp_clause_dist_schedule, cp_parser_omp_clause_proc_bind): New functions. (cp_parser_omp_all_clauses): Change mask argument's type to omp_clause_mask from unsigned. Fix c_name for PRAGMA_OMP_CLAUSE_UNTIED. Handle new OpenMP 4.0 clauses. (cp_parser_omp_for_loop): Add code argument. Pass it down to finish_omp_for. (OMP_SIMD_CLAUSE_MASK): Define. (cp_parser_omp_simd): New function. (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK, OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK, OMP_TASK_CLAUSE_MASK): Use OMP_CLAUSE_MASK_1 instead of 1. (cp_parser_omp_for): Handle parsing of #pragma omp for simd. (cp_parser_omp_parallel): Handle parsing of #pragma omp parallel for simd. Use omp_clause_mask type instead of unsigned for mask, use OMP_CLAUSE_MASK_1 instead of 1 for masks. (OMP_CANCEL_CLAUSE_MASK, OMP_CANCELLATION_POINT_CLAUSE_MASK): Define. (cp_parser_omp_cancel, cp_parser_omp_cancellation_point): New functions. (cp_parser_omp_construct): Handle PRAGMA_OMP_SIMD, PRAGMA_OMP_CANCEL and PRAGMA_OMP_CANCELLATION_POINT. (cp_parser_pragma): Handle PRAGMA_OMP_SIMD. * pt.c (tsubst_expr): Handle OMP_SIMD, OMP_FOR_SIMD and OMP_DISTRIBUTE. Pass down TREE_CODE to finish_omp_for. fortran/ * f95-lang.c (ATTR_NULL): Define. c-family/ * c-omp.c (c_finish_omp_for): Add code argument, pass it down to make_code. (c_split_parallel_clauses): Handle OMP_CLAUSE_SAFELEN, OMP_CLAUSE_ALIGNED and OMP_CLAUSE_LINEAR. * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_CANCEL, PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_DECLARE_REDUCTION, PRAGMA_OMP_DECLARE_SIMD, PRAGMA_OMP_DECLARE_TARGET, PRAGMA_OMP_DISTRIBUTE, PRAGMA_OMP_END_DECLARE_TARGET, PRAGMA_OMP_FOR_SIMD, PRAGMA_OMP_PARALLEL_FOR_SIMD, PRAGMA_OMP_SIMD, PRAGMA_OMP_TARGET, PRAGMA_OMP_TARGET_DATA, PRAGMA_OMP_TARGET_UPDATE, PRAGMA_OMP_TASKGROUP and PRAGMA_OMP_TEAMS. (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ALIGNED, PRAGMA_OMP_CLAUSE_DEPEND, PRAGMA_OMP_CLAUSE_DEVICE, PRAGMA_OMP_CLAUSE_DIST_SCHEDULE, PRAGMA_OMP_CLAUSE_FOR, PRAGMA_OMP_CLAUSE_FROM, PRAGMA_OMP_CLAUSE_INBRANCH, PRAGMA_OMP_CLAUSE_LINEAR, PRAGMA_OMP_CLAUSE_MAP, PRAGMA_OMP_CLAUSE_NOTINBRANCH, PRAGMA_OMP_CLAUSE_NUM_TEAMS, PRAGMA_OMP_CLAUSE_PARALLEL, PRAGMA_OMP_CLAUSE_PROC_BIND, PRAGMA_OMP_CLAUSE_SAFELEN, PRAGMA_OMP_CLAUSE_SECTIONS, PRAGMA_OMP_CLAUSE_SIMDLEN, PRAGMA_OMP_CLAUSE_TASKGROUP, PRAGMA_OMP_CLAUSE_TO and PRAGMA_OMP_CLAUSE_UNIFORM. * c-pragma.c (omp_pragmas): Add new OpenMP 4.0 constructs. * c-common.h (c_finish_omp_for): Add enum tree_code as second argument. (OMP_CLAUSE_MASK_1): Define. (omp_clause_mask): For HWI >= 64 new typedef for unsigned HOST_WIDE_INT, otherwise a class with needed ctors and operators. Jakub --- gcc/gimple-pretty-print.c.jj 2013-03-20 10:08:13.000000000 +0100 +++ gcc/gimple-pretty-print.c 2013-03-26 15:39:56.247978875 +0100 @@ -1087,8 +1087,26 @@ dump_gimple_omp_for (pretty_printer *buf if (flags & TDF_RAW) { - dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs, - gimple_omp_body (gs)); + const char *kind; + switch (gimple_omp_for_kind (gs)) + { + case GF_OMP_FOR_KIND_FOR: + kind = ""; + break; + case GF_OMP_FOR_KIND_SIMD: + kind = " simd"; + break; + case GF_OMP_FOR_KIND_FOR_SIMD: + kind = " for simd"; + break; + case GF_OMP_FOR_KIND_DISTRIBUTE: + kind = " distribute"; + break; + default: + gcc_unreachable (); + } + dump_gimple_fmt (buffer, spc, flags, "%G%s <%+BODY <%S>%nCLAUSES <", gs, + kind, gimple_omp_body (gs)); dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags); dump_gimple_fmt (buffer, spc, flags, " >,"); for (i = 0; i < gimple_omp_for_collapse (gs); i++) @@ -1104,7 +1122,23 @@ dump_gimple_omp_for (pretty_printer *buf } else { - pp_string (buffer, "#pragma omp for"); + switch (gimple_omp_for_kind (gs)) + { + case GF_OMP_FOR_KIND_FOR: + pp_string (buffer, "#pragma omp for"); + break; + case GF_OMP_FOR_KIND_SIMD: + pp_string (buffer, "#pragma omp simd"); + break; + case GF_OMP_FOR_KIND_FOR_SIMD: + pp_string (buffer, "#pragma omp for simd"); + break; + case GF_OMP_FOR_KIND_DISTRIBUTE: + pp_string (buffer, "#pragma omp distribute"); + break; + default: + gcc_unreachable (); + } dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags); for (i = 0; i < gimple_omp_for_collapse (gs); i++) { --- gcc/tree.def.jj 2013-03-20 10:08:13.000000000 +0100 +++ gcc/tree.def 2013-03-26 13:16:44.774905219 +0100 @@ -1030,6 +1030,18 @@ DEFTREECODE (OMP_TASK, "omp_task", tcc_s unspecified by the standard. */ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6) +/* OpenMP - #pragma omp simd [clause1 ... clauseN] + Operands like for OMP_FOR. */ +DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6) + +/* OpenMP - #pragma omp for simd [clause1 ... clauseN] + Operands like for OMP_FOR. */ +DEFTREECODE (OMP_FOR_SIMD, "omp_for_simd", tcc_statement, 6) + +/* OpenMP - #pragma omp distribute [clause1 ... clauseN] + Operands like for OMP_FOR. */ +DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6) + /* OpenMP - #pragma omp sections [clause1 ... clauseN] Operand 0: OMP_SECTIONS_BODY: Sections body. Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */ --- gcc/c/c-parser.c.jj 2013-03-20 10:41:30.000000000 +0100 +++ gcc/c/c-parser.c 2013-03-26 14:05:22.523158908 +0100 @@ -9350,7 +9350,7 @@ c_parser_omp_clause_untied (c_parser *pa of clause default goes in *pdefault. */ static tree -c_parser_omp_all_clauses (c_parser *parser, unsigned int mask, +c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, const char *where) { tree clauses = NULL; @@ -10156,7 +10156,8 @@ c_parser_omp_for_loop (location_t loc, an error from the initialization parsing. */ if (!fail) { - stmt = c_finish_omp_for (loc, declv, initv, condv, incrv, body, NULL); + stmt = c_finish_omp_for (loc, OMP_FOR, declv, initv, condv, + incrv, body, NULL); if (stmt) { if (par_clauses != NULL) @@ -10218,15 +10219,15 @@ pop_scopes: LOC is the location of the #pragma token. */ -#define OMP_FOR_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_ORDERED) \ - | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE) \ - | (1u << PRAGMA_OMP_CLAUSE_COLLAPSE) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_FOR_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (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)) static tree c_parser_omp_for (location_t loc, c_parser *parser) @@ -10367,12 +10368,12 @@ c_parser_omp_sections_scope (location_t LOC is the location of the #pragma token. */ -#define OMP_SECTIONS_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_SECTIONS_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree c_parser_omp_sections (location_t loc, c_parser *parser) @@ -10400,15 +10401,15 @@ c_parser_omp_sections (location_t loc, c LOC is the location of the #pragma token. */ -#define OMP_PARALLEL_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_IF) \ - | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ - | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ - | (1u << PRAGMA_OMP_CLAUSE_COPYIN) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS)) +#define OMP_PARALLEL_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) static tree c_parser_omp_parallel (location_t loc, c_parser *parser) @@ -10416,7 +10417,7 @@ c_parser_omp_parallel (location_t loc, c enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL; const char *p_name = "#pragma omp parallel"; tree stmt, clauses, par_clause, ws_clause, block; - unsigned int mask = OMP_PARALLEL_CLAUSE_MASK; + omp_clause_mask mask = OMP_PARALLEL_CLAUSE_MASK; if (c_parser_next_token_is_keyword (parser, RID_FOR)) { @@ -10424,7 +10425,7 @@ c_parser_omp_parallel (location_t loc, c p_kind = PRAGMA_OMP_PARALLEL_FOR; p_name = "#pragma omp parallel for"; mask |= OMP_FOR_CLAUSE_MASK; - mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); + mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); } else if (c_parser_next_token_is (parser, CPP_NAME)) { @@ -10435,7 +10436,7 @@ c_parser_omp_parallel (location_t loc, c p_kind = PRAGMA_OMP_PARALLEL_SECTIONS; p_name = "#pragma omp parallel sections"; mask |= OMP_SECTIONS_CLAUSE_MASK; - mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); + mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); } } @@ -10481,11 +10482,11 @@ c_parser_omp_parallel (location_t loc, c LOC is the location of the #pragma. */ -#define OMP_SINGLE_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_SINGLE_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree c_parser_omp_single (location_t loc, c_parser *parser) @@ -10508,15 +10509,15 @@ c_parser_omp_single (location_t loc, c_p LOC is the location of the #pragma. */ -#define OMP_TASK_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_IF) \ - | (1u << PRAGMA_OMP_CLAUSE_UNTIED) \ - | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ - | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ - | (1u << PRAGMA_OMP_CLAUSE_FINAL) \ - | (1u << PRAGMA_OMP_CLAUSE_MERGEABLE)) +#define OMP_TASK_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)) static tree c_parser_omp_task (location_t loc, c_parser *parser) --- gcc/gimple.h.jj 2013-03-20 10:08:27.000000000 +0100 +++ gcc/gimple.h 2013-03-26 15:33:52.156043230 +0100 @@ -100,6 +100,11 @@ enum gf_mask { GF_CALL_ALLOCA_FOR_VAR = 1 << 5, GF_CALL_INTERNAL = 1 << 6, GF_OMP_PARALLEL_COMBINED = 1 << 0, + GF_OMP_FOR_KIND_MASK = 3 << 0, + GF_OMP_FOR_KIND_FOR = 0 << 0, + GF_OMP_FOR_KIND_SIMD = 1 << 0, + GF_OMP_FOR_KIND_FOR_SIMD = 2 << 0, + GF_OMP_FOR_KIND_DISTRIBUTE = 3 << 0, /* True on an GIMPLE_OMP_RETURN statement if the return does not require a thread synchronization via some sort of barrier. The exact barrier @@ -3877,6 +3882,27 @@ gimple_omp_critical_set_name (gimple gs, } +/* Return the kind of OMP for statemement. */ + +static inline int +gimple_omp_for_kind (const_gimple g) +{ + GIMPLE_CHECK (g, GIMPLE_OMP_FOR); + return (gimple_omp_subcode (g) & GF_OMP_FOR_KIND_MASK); +} + + +/* Set the OMP for kind. */ + +static inline void +gimple_omp_for_set_kind (gimple g, int kind) +{ + GIMPLE_CHECK (g, GIMPLE_OMP_FOR); + g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_FOR_KIND_MASK) + | (kind & GF_OMP_FOR_KIND_MASK); +} + + /* Return the clauses associated with OMP_FOR GS. */ static inline tree --- gcc/gimplify.c.jj 2013-03-20 10:08:13.000000000 +0100 +++ gcc/gimplify.c 2013-03-26 15:50:23.175385165 +0100 @@ -4742,6 +4742,9 @@ is_gimple_stmt (tree t) case STATEMENT_LIST: case OMP_PARALLEL: case OMP_FOR: + case OMP_SIMD: + case OMP_FOR_SIMD: + case OMP_DISTRIBUTE: case OMP_SECTIONS: case OMP_SECTION: case OMP_SINGLE: @@ -6689,6 +6692,22 @@ gimplify_omp_for (tree *expr_p, gimple_s gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt), TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)), for_pre_body); + switch (TREE_CODE (for_stmt)) + { + case OMP_FOR: + break; + case OMP_SIMD: + gimple_omp_for_set_kind (gfor, GF_OMP_FOR_KIND_SIMD); + break; + case OMP_FOR_SIMD: + gimple_omp_for_set_kind (gfor, GF_OMP_FOR_KIND_FOR_SIMD); + break; + case OMP_DISTRIBUTE: + gimple_omp_for_set_kind (gfor, GF_OMP_FOR_KIND_DISTRIBUTE); + break; + default: + gcc_unreachable (); + } for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++) { @@ -7621,6 +7640,9 @@ gimplify_expr (tree *expr_p, gimple_seq break; case OMP_FOR: + case OMP_SIMD: + case OMP_FOR_SIMD: + case OMP_DISTRIBUTE: ret = gimplify_omp_for (expr_p, pre_p); break; --- gcc/fortran/f95-lang.c.jj 2013-03-20 10:07:56.000000000 +0100 +++ gcc/fortran/f95-lang.c 2013-03-25 17:56:05.739387700 +0100 @@ -531,7 +531,8 @@ gfc_builtin_function (tree decl) return decl; } -/* So far we need just these 4 attribute types. */ +/* So far we need just these 6 attribute types. */ +#define ATTR_NULL 0 #define ATTR_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF) #define ATTR_NOTHROW_LEAF_MALLOC_LIST (ECF_NOTHROW | ECF_LEAF | ECF_MALLOC) #define ATTR_CONST_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_CONST) --- gcc/tree.c.jj 2013-03-20 10:04:59.000000000 +0100 +++ gcc/tree.c 2013-03-21 13:35:52.235322504 +0100 @@ -235,6 +235,13 @@ unsigned const char omp_clause_num_ops[] 4, /* OMP_CLAUSE_REDUCTION */ 1, /* OMP_CLAUSE_COPYIN */ 1, /* OMP_CLAUSE_COPYPRIVATE */ + 2, /* OMP_CLAUSE_LINEAR */ + 2, /* OMP_CLAUSE_ALIGNED */ + 1, /* OMP_CLAUSE_DEPEND */ + 1, /* OMP_CLAUSE_FROM */ + 1, /* OMP_CLAUSE_TO */ + 1, /* OMP_CLAUSE_UNIFORM */ + 1, /* OMP_CLAUSE_MAP */ 1, /* OMP_CLAUSE_IF */ 1, /* OMP_CLAUSE_NUM_THREADS */ 1, /* OMP_CLAUSE_SCHEDULE */ @@ -244,7 +251,19 @@ unsigned const char omp_clause_num_ops[] 3, /* OMP_CLAUSE_COLLAPSE */ 0, /* OMP_CLAUSE_UNTIED */ 1, /* OMP_CLAUSE_FINAL */ - 0 /* OMP_CLAUSE_MERGEABLE */ + 0, /* OMP_CLAUSE_MERGEABLE */ + 1, /* OMP_CLAUSE_DEVICE */ + 1, /* OMP_CLAUSE_DIST_SCHEDULE */ + 0, /* OMP_CLAUSE_INBRANCH */ + 0, /* OMP_CLAUSE_NOTINBRANCH */ + 1, /* OMP_CLAUSE_NUM_TEAMS */ + 0, /* OMP_CLAUSE_PROC_BIND */ + 1, /* OMP_CLAUSE_SAFELEN */ + 1, /* OMP_CLAUSE_SIMDLEN */ + 0, /* OMP_CLAUSE_FOR */ + 0, /* OMP_CLAUSE_PARALLEL */ + 0, /* OMP_CLAUSE_SECTIONS */ + 0 /* OMP_CLAUSE_TASKGROUP */ }; const char * const omp_clause_code_name[] = @@ -257,6 +276,13 @@ const char * const omp_clause_code_name[ "reduction", "copyin", "copyprivate", + "linear", + "aligned", + "depend", + "from", + "to", + "uniform", + "map", "if", "num_threads", "schedule", @@ -266,7 +292,19 @@ const char * const omp_clause_code_name[ "collapse", "untied", "final", - "mergeable" + "mergeable", + "device", + "dist_schedule", + "inbranch", + "notinbranch", + "num_teams", + "proc_bind", + "safelen", + "simdlen", + "for", + "parallel", + "sections", + "taskgroup" }; @@ -10761,6 +10799,16 @@ walk_tree_1 (tree *tp, walk_tree_fn func case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_SCHEDULE: + case OMP_CLAUSE_FROM: + case OMP_CLAUSE_TO: + case OMP_CLAUSE_UNIFORM: + case OMP_CLAUSE_DEPEND: + case OMP_CLAUSE_MAP: + case OMP_CLAUSE_NUM_TEAMS: + case OMP_CLAUSE_DEVICE: + case OMP_CLAUSE_DIST_SCHEDULE: + case OMP_CLAUSE_SAFELEN: + case OMP_CLAUSE_SIMDLEN: WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0)); /* FALLTHRU */ @@ -10769,6 +10817,13 @@ walk_tree_1 (tree *tp, walk_tree_fn func case OMP_CLAUSE_DEFAULT: case OMP_CLAUSE_UNTIED: case OMP_CLAUSE_MERGEABLE: + case OMP_CLAUSE_PROC_BIND: + case OMP_CLAUSE_INBRANCH: + case OMP_CLAUSE_NOTINBRANCH: + case OMP_CLAUSE_FOR: + case OMP_CLAUSE_PARALLEL: + case OMP_CLAUSE_SECTIONS: + case OMP_CLAUSE_TASKGROUP: WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); case OMP_CLAUSE_LASTPRIVATE: @@ -10784,6 +10839,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); } + case OMP_CLAUSE_ALIGNED: + case OMP_CLAUSE_LINEAR: + WALK_SUBTREE (OMP_CLAUSE_DECL (*tp)); + WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); + WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); + case OMP_CLAUSE_REDUCTION: { int i; --- gcc/cp/cp-tree.h.jj 2013-03-20 10:07:19.000000000 +0100 +++ gcc/cp/cp-tree.h 2013-03-26 14:14:46.938925937 +0100 @@ -60,7 +60,8 @@ c-common.h, not after. STMT_EXPR_NO_SCOPE (in STMT_EXPR) BIND_EXPR_TRY_BLOCK (in BIND_EXPR) TYPENAME_IS_ENUM_P (in TYPENAME_TYPE) - OMP_FOR_GIMPLIFYING_P (in OMP_FOR) + OMP_FOR_GIMPLIFYING_P (in OMP_FOR, OMP_SIMD, OMP_FOR_SIMD + and OMP_DISTRIBUTE) BASELINK_QUALIFIED_P (in BASELINK) TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX) @@ -3976,7 +3977,7 @@ more_aggr_init_expr_args_p (const aggr_i /* Used while gimplifying continue statements bound to OMP_FOR nodes. */ #define OMP_FOR_GIMPLIFYING_P(NODE) \ - (TREE_LANG_FLAG_0 (OMP_FOR_CHECK (NODE))) + (TREE_LANG_FLAG_0 (OMP_LOOP_CHECK (NODE))) /* A language-specific token attached to the OpenMP data clauses to hold code (or code fragments) related to ctors, dtors, and op=. @@ -5708,17 +5709,20 @@ extern tree begin_omp_parallel (void); extern tree finish_omp_parallel (tree, tree); extern tree begin_omp_task (void); extern tree finish_omp_task (tree, tree); -extern tree finish_omp_for (location_t, tree, tree, - tree, tree, tree, tree, tree); +extern tree finish_omp_for (location_t, enum tree_code, + tree, tree, tree, tree, tree, + tree, tree); extern void finish_omp_atomic (enum tree_code, enum tree_code, tree, tree, tree, tree, tree); 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_cancel (tree); +extern void finish_omp_cancellation_point (tree); extern tree begin_transaction_stmt (location_t, tree *, int); extern void finish_transaction_stmt (tree, tree, int, tree); extern tree build_transaction_expr (location_t, tree, int, tree); -extern void finish_omp_taskyield (void); extern bool cxx_omp_create_clause_info (tree, tree, bool, bool, bool); extern tree baselink_for_fns (tree); extern void finish_static_assert (tree, tree, location_t, --- gcc/cp/cp-gimplify.c.jj 2013-03-20 10:07:19.000000000 +0100 +++ gcc/cp/cp-gimplify.c 2013-03-26 14:10:49.672287238 +0100 @@ -669,6 +669,9 @@ cp_gimplify_expr (tree *expr_p, gimple_s gcc_unreachable (); case OMP_FOR: + case OMP_SIMD: + case OMP_FOR_SIMD: + case OMP_DISTRIBUTE: ret = cp_gimplify_omp_for (expr_p, pre_p); break; @@ -1116,7 +1119,10 @@ cp_genericize_r (tree *stmt_p, int *walk genericize_continue_stmt (stmt_p); else if (TREE_CODE (stmt) == BREAK_STMT) genericize_break_stmt (stmt_p); - else if (TREE_CODE (stmt) == OMP_FOR) + else if (TREE_CODE (stmt) == OMP_FOR + || TREE_CODE (stmt) == OMP_SIMD + || TREE_CODE (stmt) == OMP_FOR_SIMD + || TREE_CODE (stmt) == OMP_DISTRIBUTE) genericize_omp_for_stmt (stmt_p, walk_subtrees, data); else if (TREE_CODE (stmt) == SIZEOF_EXPR) { --- gcc/cp/semantics.c.jj 2013-03-20 10:36:15.000000000 +0100 +++ gcc/cp/semantics.c 2013-03-26 14:14:08.366153382 +0100 @@ -4025,6 +4025,7 @@ tree finish_omp_clauses (tree clauses) { bitmap_head generic_head, firstprivate_head, lastprivate_head; + bitmap_head aligned_head; tree c, t, *pc = &clauses; const char *name; @@ -4032,6 +4033,7 @@ finish_omp_clauses (tree clauses) bitmap_initialize (&generic_head, &bitmap_default_obstack); bitmap_initialize (&firstprivate_head, &bitmap_default_obstack); bitmap_initialize (&lastprivate_head, &bitmap_default_obstack); + bitmap_initialize (&aligned_head, &bitmap_default_obstack); for (pc = &clauses, c = clauses; c ; c = *pc) { @@ -4054,6 +4056,27 @@ finish_omp_clauses (tree clauses) case OMP_CLAUSE_COPYIN: name = "copyin"; goto check_dup_generic; + case OMP_CLAUSE_LINEAR: + name = "linear"; + t = OMP_CLAUSE_LINEAR_STEP (c); + if (t == NULL_TREE) + t = integer_one_node; + if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error ("linear step expression must be integral"); + remove = true; + } + else + { + t = mark_rvalue_use (t); + if (!processing_template_decl) + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + OMP_CLAUSE_LINEAR_STEP (c) = t; + } + goto check_dup_generic; check_dup_generic: t = OMP_CLAUSE_DECL (c); if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) @@ -4181,12 +4204,210 @@ finish_omp_clauses (tree clauses) } break; + case OMP_CLAUSE_SIMDLEN: + case OMP_CLAUSE_SAFELEN: + t = OMP_CLAUSE_OPERAND (c, 0); + if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error ("%qs length expression must be integral", + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } + else + { + t = mark_rvalue_use (t); + t = maybe_constant_value (t); + if (!processing_template_decl) + { + if (TREE_CODE (t) != INTEGER_CST + || tree_int_cst_sgn (t) == -1) + { + error ("%qs length expression must be positive constant" + " integer expression", + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } + } + OMP_CLAUSE_OPERAND (c, 0) = t; + } + break; + + case OMP_CLAUSE_NUM_TEAMS: + t = OMP_CLAUSE_NUM_TEAMS_EXPR (c); + if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error ("% expression must be integral"); + remove = true; + } + else + { + t = mark_rvalue_use (t); + if (!processing_template_decl) + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t; + } + break; + + case OMP_CLAUSE_DEVICE: + t = OMP_CLAUSE_DEVICE_ID (c); + if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error ("% id must be integral"); + remove = true; + } + else + { + t = mark_rvalue_use (t); + if (!processing_template_decl) + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + OMP_CLAUSE_DEVICE_ID (c) = t; + } + break; + + case OMP_CLAUSE_DIST_SCHEDULE: + t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c); + if (t == NULL) + ; + else if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error ("% chunk size expression must be " + "integral"); + remove = true; + } + else + { + t = mark_rvalue_use (t); + if (!processing_template_decl) + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t; + } + break; + + case OMP_CLAUSE_ALIGNED: + t = OMP_CLAUSE_DECL (c); + if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) + { + if (processing_template_decl) + break; + if (DECL_P (t)) + error ("%qD is not a variable in % clause", t); + else + error ("%qE is not a variable in % clause", t); + remove = true; + } + else if (bitmap_bit_p (&aligned_head, DECL_UID (t))) + { + error ("%qD appears more than once in % clauses", t); + remove = true; + } + else + bitmap_set_bit (&aligned_head, DECL_UID (t)); + t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c); + if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error ("% clause alignment expression must " + "be integral"); + remove = true; + } + else + { + t = mark_rvalue_use (t); + t = maybe_constant_value (t); + if (!processing_template_decl) + { + if (TREE_CODE (t) != INTEGER_CST + || tree_int_cst_sgn (t) == -1) + { + error ("% clause alignment expression must be " + "positive constant integer expression"); + remove = true; + } + } + OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t; + } + break; + + case OMP_CLAUSE_DEPEND: + t = OMP_CLAUSE_DECL (c); + /* FIXME: depend clause argument may be also array section. */ + if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) + { + if (processing_template_decl) + break; + if (DECL_P (t)) + error ("%qD is not a variable in % clause", t); + else + error ("%qE is not a variable in % clause", t); + remove = true; + } + break; + + case OMP_CLAUSE_MAP: + case OMP_CLAUSE_TO: + case OMP_CLAUSE_FROM: + t = OMP_CLAUSE_DECL (c); + /* FIXME: map clause argument may be also array section. */ + if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) + { + if (processing_template_decl) + break; + if (DECL_P (t)) + error ("%qD is not a variable in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + else + error ("%qE is not a variable in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } + else if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t)) + { + error ("%qD is threadprivate variable in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + remove = true; + } + break; + + case OMP_CLAUSE_UNIFORM: + if (TREE_CODE (t) != PARM_DECL) + { + if (processing_template_decl) + break; + if (DECL_P (t)) + error ("%qD is not an argument in % clause", t); + else + error ("%qE is not an argument in % clause", t); + remove = true; + } + break; + case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_DEFAULT: case OMP_CLAUSE_UNTIED: case OMP_CLAUSE_COLLAPSE: case OMP_CLAUSE_MERGEABLE: + case OMP_CLAUSE_INBRANCH: + case OMP_CLAUSE_NOTINBRANCH: + case OMP_CLAUSE_PARALLEL: + case OMP_CLAUSE_FOR: + case OMP_CLAUSE_SECTIONS: + case OMP_CLAUSE_TASKGROUP: + case OMP_CLAUSE_PROC_BIND: break; default: @@ -4741,8 +4962,8 @@ handle_omp_for_class_iterator (int i, lo sk_omp scope. */ tree -finish_omp_for (location_t locus, tree declv, tree initv, tree condv, - tree incrv, tree body, tree pre_body, tree clauses) +finish_omp_for (location_t locus, enum tree_code code, tree declv, tree initv, + tree condv, tree incrv, tree body, tree pre_body, tree clauses) { tree omp_for = NULL, orig_incr = NULL; tree decl, init, cond, incr; @@ -4811,7 +5032,7 @@ finish_omp_for (location_t locus, tree d { tree stmt; - stmt = make_node (OMP_FOR); + stmt = make_node (code); for (i = 0; i < TREE_VEC_LENGTH (declv); i++) { @@ -4923,7 +5144,7 @@ finish_omp_for (location_t locus, tree d if (IS_EMPTY_STMT (pre_body)) pre_body = NULL; - omp_for = c_finish_omp_for (locus, declv, initv, condv, incrv, + omp_for = c_finish_omp_for (locus, code, declv, initv, condv, incrv, body, pre_body); if (omp_for == NULL) @@ -5110,6 +5331,62 @@ finish_omp_taskyield (void) tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); release_tree_vector (vec); finish_expr_stmt (stmt); +} + +void +finish_omp_cancel (tree clauses) +{ + tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL); + int mask = 0; + if (find_omp_clause (clauses, OMP_CLAUSE_PARALLEL)) + mask = 1; + else if (find_omp_clause (clauses, OMP_CLAUSE_FOR)) + mask = 2; + else if (find_omp_clause (clauses, OMP_CLAUSE_SECTIONS)) + mask = 4; + else if (find_omp_clause (clauses, OMP_CLAUSE_TASKGROUP)) + mask = 8; + else + { + error ("%<#pragma omp cancellation point must specify one of " + "%, %, % or % clauses"); + return; + } + vec *vec + = make_tree_vector_single (build_int_cst (integer_type_node, mask)); + tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); + release_tree_vector (vec); + tree ifc = find_omp_clause (clauses, OMP_CLAUSE_IF); + if (ifc != NULL_TREE) + stmt = build3 (COND_EXPR, void_type_node, OMP_CLAUSE_IF_EXPR (ifc), + stmt, NULL_TREE); + finish_expr_stmt (stmt); +} + +void +finish_omp_cancellation_point (tree clauses) +{ + tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT); + int mask = 0; + if (find_omp_clause (clauses, OMP_CLAUSE_PARALLEL)) + mask = 1; + else if (find_omp_clause (clauses, OMP_CLAUSE_FOR)) + mask = 2; + else if (find_omp_clause (clauses, OMP_CLAUSE_SECTIONS)) + mask = 4; + else if (find_omp_clause (clauses, OMP_CLAUSE_TASKGROUP)) + mask = 8; + else + { + error ("%<#pragma omp cancellation point must specify one of " + "%, %, % or % clauses"); + return; + } + vec *vec + = make_tree_vector_single (build_int_cst (integer_type_node, mask)); + tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); + release_tree_vector (vec); + finish_expr_stmt (stmt); } /* Begin a __transaction_atomic or __transaction_relaxed statement. --- gcc/cp/parser.c.jj 2013-03-20 10:41:30.000000000 +0100 +++ gcc/cp/parser.c 2013-03-26 15:27:31.693905871 +0100 @@ -25709,7 +25709,7 @@ cp_parser_objc_at_dynamic_declaration (c } -/* OpenMP 2.5 parsing routines. */ +/* OpenMP 2.5 / 3.0 / 3.1 / 4.0 parsing routines. */ /* Returns name of the next clause. If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and @@ -25727,6 +25727,8 @@ cp_parser_omp_clause_name (cp_parser *pa result = PRAGMA_OMP_CLAUSE_DEFAULT; else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_PRIVATE)) result = PRAGMA_OMP_CLAUSE_PRIVATE; + else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) + result = PRAGMA_OMP_CLAUSE_FOR; else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { tree id = cp_lexer_peek_token (parser->lexer)->u.value; @@ -25734,6 +25736,10 @@ cp_parser_omp_clause_name (cp_parser *pa switch (p[0]) { + case 'a': + if (!strcmp ("aligned", p)) + result = PRAGMA_OMP_CLAUSE_ALIGNED; + break; case 'c': if (!strcmp ("collapse", p)) result = PRAGMA_OMP_CLAUSE_COLLAPSE; @@ -25742,23 +25748,44 @@ cp_parser_omp_clause_name (cp_parser *pa else if (!strcmp ("copyprivate", p)) result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; break; + case 'd': + if (!strcmp ("depend", p)) + result = PRAGMA_OMP_CLAUSE_DEPEND; + else if (!strcmp ("device", p)) + result = PRAGMA_OMP_CLAUSE_DEVICE; + else if (!strcmp ("dist_schedule", p)) + result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; + break; case 'f': if (!strcmp ("final", p)) result = PRAGMA_OMP_CLAUSE_FINAL; else if (!strcmp ("firstprivate", p)) result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; + else if (!strcmp ("from", p)) + result = PRAGMA_OMP_CLAUSE_FROM; break; + case 'i': + if (!strcmp ("inbranch", p)) + result = PRAGMA_OMP_CLAUSE_INBRANCH; case 'l': if (!strcmp ("lastprivate", p)) result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; + else if (!strcmp ("linear", p)) + result = PRAGMA_OMP_CLAUSE_LINEAR; break; case 'm': - if (!strcmp ("mergeable", p)) + if (!strcmp ("map", p)) + result = PRAGMA_OMP_CLAUSE_MAP; + else if (!strcmp ("mergeable", p)) result = PRAGMA_OMP_CLAUSE_MERGEABLE; break; case 'n': - if (!strcmp ("nowait", p)) + if (!strcmp ("notinbranch", p)) + result = PRAGMA_OMP_CLAUSE_NOTINBRANCH; + else if (!strcmp ("nowait", p)) result = PRAGMA_OMP_CLAUSE_NOWAIT; + else if (!strcmp ("num_teams", p)) + result = PRAGMA_OMP_CLAUSE_NUM_TEAMS; else if (!strcmp ("num_threads", p)) result = PRAGMA_OMP_CLAUSE_NUM_THREADS; break; @@ -25766,18 +25793,38 @@ cp_parser_omp_clause_name (cp_parser *pa if (!strcmp ("ordered", p)) result = PRAGMA_OMP_CLAUSE_ORDERED; break; + case 'p': + if (!strcmp ("parallel", p)) + result = PRAGMA_OMP_CLAUSE_PARALLEL; + else if (!strcmp ("proc_bind", p)) + result = PRAGMA_OMP_CLAUSE_PROC_BIND; + break; case 'r': if (!strcmp ("reduction", p)) result = PRAGMA_OMP_CLAUSE_REDUCTION; break; case 's': - if (!strcmp ("schedule", p)) + if (!strcmp ("safelen", p)) + result = PRAGMA_OMP_CLAUSE_SAFELEN; + else if (!strcmp ("schedule", p)) result = PRAGMA_OMP_CLAUSE_SCHEDULE; + else if (!strcmp ("sections", p)) + result = PRAGMA_OMP_CLAUSE_SECTIONS; else if (!strcmp ("shared", p)) result = PRAGMA_OMP_CLAUSE_SHARED; + else if (!strcmp ("simdlen", p)) + result = PRAGMA_OMP_CLAUSE_SIMDLEN; + break; + case 't': + if (!strcmp ("taskgroup", p)) + result = PRAGMA_OMP_CLAUSE_TASKGROUP; + else if (!strcmp ("to", p)) + result = PRAGMA_OMP_CLAUSE_TO; break; case 'u': - if (!strcmp ("untied", p)) + if (!strcmp ("uniform", p)) + result = PRAGMA_OMP_CLAUSE_UNIFORM; + else if (!strcmp ("untied", p)) result = PRAGMA_OMP_CLAUSE_UNTIED; break; } @@ -25810,20 +25857,26 @@ check_no_duplicate_clause (tree clauses, identifier variable-list , identifier - In addition, we match a closing parenthesis. An opening parenthesis - will have been consumed by the caller. + In addition, we match a closing parenthesis (or, if COLON is non-NULL, + colon). An opening parenthesis will have been consumed by the caller. If KIND is nonzero, create the appropriate node and install the decl in OMP_CLAUSE_DECL and add the node to the head of the list. If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE; - return the list created. */ + return the list created. + + COLON can be NULL if only closing parenthesis should end the list, + or pointer to bool which will receive false if the list is terminated + by closing parenthesis or true if the list is terminated by colon. */ static tree cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, - tree list) + tree list, bool *colon) { cp_token *token; + if (colon) + *colon = false; while (1) { tree name, decl; @@ -25857,6 +25910,13 @@ cp_parser_omp_var_list_no_open (cp_parse cp_lexer_consume_token (parser->lexer); } + if (colon != NULL && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) + { + *colon = true; + cp_parser_require (parser, CPP_COLON, RT_COLON); + return list; + } + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) { int ending; @@ -25882,7 +25942,7 @@ static tree cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list) { if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) - return cp_parser_omp_var_list_no_open (parser, kind, list); + return cp_parser_omp_var_list_no_open (parser, kind, list, NULL); return list; } @@ -26198,7 +26258,8 @@ 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, OMP_CLAUSE_REDUCTION, list, + NULL); for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) OMP_CLAUSE_REDUCTION_CODE (c) = code; @@ -26313,12 +26374,393 @@ cp_parser_omp_clause_untied (cp_parser * return c; } +/* OpenMP 4.0: + inbranch + notinbranch */ + +static tree +cp_parser_omp_clause_branch (cp_parser * /*parser*/, enum omp_clause_code code, + tree list, location_t location) +{ + check_no_duplicate_clause (list, code, omp_clause_code_name[code], location); + tree c = build_omp_clause (location, code); + OMP_CLAUSE_CHAIN (c) = list; + return c; +} + +/* OpenMP 4.0: + parallel + for + sections + taskgroup */ + +static tree +cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/, + enum omp_clause_code code, + tree list, location_t location) +{ + tree c; + + for (c = list; c; c = OMP_CLAUSE_CHAIN (c)) + switch (OMP_CLAUSE_CODE (c)) + { + case OMP_CLAUSE_PARALLEL: + case OMP_CLAUSE_FOR: + case OMP_CLAUSE_SECTIONS: + case OMP_CLAUSE_TASKGROUP: + error_at (location, "only one of %, %, % " + "and % clauses can be specified"); + break; + default: + break; + } + c = build_omp_clause (location, code); + OMP_CLAUSE_CHAIN (c) = list; + return c; +} + +/* OpenMP 4.0: + num_teams ( expression ) */ + +static tree +cp_parser_omp_clause_num_teams (cp_parser *parser, tree list, + location_t location) +{ + tree t, c; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + t = cp_parser_expression (parser, false, NULL); + + if (t == error_mark_node + || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + + check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, + "num_teams", location); + + c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS); + OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t; + OMP_CLAUSE_CHAIN (c) = list; + + return c; +} + +/* OpenMP 4.0: + aligned ( variable-list ) + aligned ( variable-list : constant-expression ) */ + +static tree +cp_parser_omp_clause_aligned (cp_parser *parser, tree list) +{ + tree nlist, c, alignment = NULL_TREE; + bool colon; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALIGNED, list, + &colon); + + if (colon) + { + alignment = cp_parser_constant_expression (parser, false, NULL); + + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + + if (alignment == error_mark_node) + alignment = NULL_TREE; + } + + for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment; + + return nlist; +} + +/* OpenMP 4.0: + linear ( variable-list ) + linear ( variable-list : expression ) */ + +static tree +cp_parser_omp_clause_linear (cp_parser *parser, tree list) +{ + tree nlist, c, step = integer_one_node; + bool colon; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list, + &colon); + + if (colon) + { + step = cp_parser_expression (parser, false, NULL); + + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + + if (step == error_mark_node) + return list; + } + + for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_LINEAR_STEP (c) = step; + + return nlist; +} + +/* OpenMP 4.0: + depend ( depend-kind : variable-list ) + + depend-kind: + in | out | inout */ + +static tree +cp_parser_omp_clause_depend (cp_parser *parser, tree list) +{ + tree nlist, c; + enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp ("in", p) == 0) + kind = OMP_CLAUSE_DEPEND_IN; + else if (strcmp ("inout", p) == 0) + kind = OMP_CLAUSE_DEPEND_INOUT; + else if (strcmp ("out", p) == 0) + kind = OMP_CLAUSE_DEPEND_OUT; + else + goto invalid_kind; + } + else + goto invalid_kind; + + cp_lexer_consume_token (parser->lexer); + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) + goto resync_fail; + + nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_DEPEND, list, + NULL); + + for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_DEPEND_KIND (c) = kind; + + return nlist; + + invalid_kind: + cp_parser_error (parser, "invalid depend kind"); + resync_fail: + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; +} + +/* OpenMP 4.0: + map ( map-kind : variable-list ) + map ( variable-list) + + map-kind: + alloc | to | from | tofrom */ + +static tree +cp_parser_omp_clause_map (cp_parser *parser, tree list) +{ + tree nlist, c; + enum omp_clause_map_kind kind = OMP_CLAUSE_MAP_TOFROM; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME) + && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp ("alloc", p) == 0) + kind = OMP_CLAUSE_MAP_ALLOC; + else if (strcmp ("to", p) == 0) + kind = OMP_CLAUSE_MAP_TO; + else if (strcmp ("from", p) == 0) + kind = OMP_CLAUSE_MAP_FROM; + else if (strcmp ("tofrom", p) == 0) + kind = OMP_CLAUSE_MAP_TOFROM; + else + { + cp_parser_error (parser, "invalid map kind"); + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + } + + nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list, + NULL); + + for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_MAP_KIND (c) = kind; + + return nlist; +} + +/* OpenMP 4.0: + device ( expression ) */ + +static tree +cp_parser_omp_clause_device (cp_parser *parser, tree list, + location_t location) +{ + tree t, c; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + t = cp_parser_expression (parser, false, NULL); + + if (t == error_mark_node + || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + + check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, + "device", location); + + c = build_omp_clause (location, OMP_CLAUSE_DEVICE); + OMP_CLAUSE_DEVICE_ID (c) = t; + OMP_CLAUSE_CHAIN (c) = list; + + return c; +} + +/* OpenMP 4.0: + dist_schedule ( static ) + dist_schedule ( static , expression ) */ + +static tree +cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list, + location_t location) +{ + tree c, t; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + c = build_omp_clause (location, OMP_CLAUSE_DIST_SCHEDULE); + + if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC)) + goto invalid_kind; + cp_lexer_consume_token (parser->lexer); + + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + { + cp_lexer_consume_token (parser->lexer); + + t = cp_parser_assignment_expression (parser, false, NULL); + + if (t == error_mark_node) + goto resync_fail; + OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t; + + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + goto resync_fail; + } + else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN)) + goto resync_fail; + + check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, "dist_schedule", + location); + OMP_CLAUSE_CHAIN (c) = list; + return c; + + invalid_kind: + cp_parser_error (parser, "invalid dist_schedule kind"); + resync_fail: + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; +} + +/* OpenMP 4.0: + proc_bind ( proc-bind-kind ) + + proc-bind-kind: + master | close | spread */ + +static tree +cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list, + location_t location) +{ + tree c; + enum omp_clause_proc_bind_kind kind; + + if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) + return list; + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp ("master", p) == 0) + kind = OMP_CLAUSE_PROC_BIND_MASTER; + else if (strcmp ("close", p) == 0) + kind = OMP_CLAUSE_PROC_BIND_CLOSE; + else if (strcmp ("spread", p) == 0) + kind = OMP_CLAUSE_PROC_BIND_SPREAD; + else + goto invalid_kind; + } + else + goto invalid_kind; + + cp_lexer_consume_token (parser->lexer); + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) + goto resync_fail; + + c = build_omp_clause (location, OMP_CLAUSE_PROC_BIND); + check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind", + location); + OMP_CLAUSE_PROC_BIND_KIND (c) = kind; + OMP_CLAUSE_CHAIN (c) = list; + return c; + + invalid_kind: + cp_parser_error (parser, "invalid depend kind"); + resync_fail: + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; +} + /* Parse all OpenMP clauses. The set clauses allowed by the directive is a bitmask in MASK. Return the list of clauses found; the result of clause default goes in *pdefault. */ static tree -cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask, +cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, const char *where, cp_token *pragma_tok) { tree clauses = NULL; @@ -26418,7 +26860,89 @@ cp_parser_omp_all_clauses (cp_parser *pa case PRAGMA_OMP_CLAUSE_UNTIED: clauses = cp_parser_omp_clause_untied (parser, clauses, token->location); - c_name = "nowait"; + c_name = "untied"; + break; + case PRAGMA_OMP_CLAUSE_INBRANCH: + clauses = cp_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH, + clauses, token->location); + c_name = "inbranch"; + break; + case PRAGMA_OMP_CLAUSE_NOTINBRANCH: + clauses = cp_parser_omp_clause_branch (parser, + OMP_CLAUSE_NOTINBRANCH, + clauses, token->location); + c_name = "notinbranch"; + break; + case PRAGMA_OMP_CLAUSE_PARALLEL: + clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL, + clauses, token->location); + c_name = "parallel"; + break; + case PRAGMA_OMP_CLAUSE_FOR: + clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR, + clauses, token->location); + c_name = "for"; + break; + case PRAGMA_OMP_CLAUSE_SECTIONS: + clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS, + clauses, token->location); + c_name = "sections"; + break; + case PRAGMA_OMP_CLAUSE_TASKGROUP: + clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP, + clauses, token->location); + c_name = "taskgroup"; + break; + case PRAGMA_OMP_CLAUSE_TO: + clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, + clauses); + c_name = "to"; + break; + case PRAGMA_OMP_CLAUSE_FROM: + clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, + clauses); + c_name = "from"; + break; + case PRAGMA_OMP_CLAUSE_UNIFORM: + clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_UNIFORM, + clauses); + c_name = "uniform"; + break; + case PRAGMA_OMP_CLAUSE_NUM_TEAMS: + clauses = cp_parser_omp_clause_num_teams (parser, clauses, + token->location); + c_name = "num_teams"; + break; + case PRAGMA_OMP_CLAUSE_ALIGNED: + clauses = cp_parser_omp_clause_aligned (parser, clauses); + c_name = "aligned"; + break; + case PRAGMA_OMP_CLAUSE_LINEAR: + clauses = cp_parser_omp_clause_linear (parser, clauses); + c_name = "linear"; + break; + case PRAGMA_OMP_CLAUSE_DEPEND: + clauses = cp_parser_omp_clause_depend (parser, clauses); + c_name = "depend"; + break; + case PRAGMA_OMP_CLAUSE_MAP: + clauses = cp_parser_omp_clause_map (parser, clauses); + c_name = "map"; + break; + case PRAGMA_OMP_CLAUSE_DEVICE: + clauses = cp_parser_omp_clause_device (parser, clauses, + token->location); + c_name = "device"; + break; + case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE: + clauses = cp_parser_omp_clause_dist_schedule (parser, clauses, + token->location); + c_name = "dist_schedule"; + break; + case PRAGMA_OMP_CLAUSE_PROC_BIND: + clauses = cp_parser_omp_clause_proc_bind (parser, clauses, + token->location); + c_name = "proc_bind"; break; default: cp_parser_error (parser, "expected %<#pragma omp%> clause"); @@ -27075,7 +27599,8 @@ cp_parser_omp_for_incr (cp_parser *parse /* Parse the restricted form of the for statement allowed by OpenMP. */ static tree -cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses) +cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, + tree *par_clauses) { tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret; tree real_decl, initv, condv, incrv, declv; @@ -27434,7 +27959,7 @@ cp_parser_omp_for_loop (cp_parser *parse if (declv == NULL_TREE) ret = NULL_TREE; else - ret = finish_omp_for (loc_first, declv, initv, condv, incrv, body, + ret = finish_omp_for (loc_first, code, declv, initv, condv, incrv, body, pre_body, clauses); while (nbraces) @@ -27467,33 +27992,86 @@ cp_parser_omp_for_loop (cp_parser *parse return ret; } +/* OpenMP 4.0: + #pragma omp simd simd-clause[optseq] new-line + for-loop */ + +#define OMP_SIMD_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) + +static tree +cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok) +{ + tree clauses, sb, ret; + unsigned int save; + + clauses = cp_parser_omp_all_clauses (parser, OMP_SIMD_CLAUSE_MASK, + "#pragma omp simd", pragma_tok); + + sb = begin_omp_structured_block (); + save = cp_parser_begin_omp_structured_block (parser); + + ret = cp_parser_omp_for_loop (parser, OMP_SIMD, clauses, NULL); + + cp_parser_end_omp_structured_block (parser, save); + add_stmt (finish_omp_structured_block (sb)); + + return ret; +} + /* OpenMP 2.5: #pragma omp for for-clause[optseq] new-line + for-loop + + OpenMP 4.0: + #pragma omp for simd for-simd-clause[optseq] new-line for-loop */ -#define OMP_FOR_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_ORDERED) \ - | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT) \ - | (1u << PRAGMA_OMP_CLAUSE_COLLAPSE)) +#define OMP_FOR_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (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)) static tree cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok) { tree clauses, sb, ret; unsigned int save; + enum tree_code code = OMP_FOR; + omp_clause_mask mask = OMP_FOR_CLAUSE_MASK; + const char *p_name = "#pragma omp for"; + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp (p, "simd") == 0) + { + cp_lexer_consume_token (parser->lexer); + code = OMP_FOR_SIMD; + mask |= OMP_SIMD_CLAUSE_MASK; + p_name = "#pragma omp for simd"; + } + } - clauses = cp_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK, - "#pragma omp for", pragma_tok); + clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok); sb = begin_omp_structured_block (); save = cp_parser_begin_omp_structured_block (parser); - ret = cp_parser_omp_for_loop (parser, clauses, NULL); + ret = cp_parser_omp_for_loop (parser, code, clauses, NULL); cp_parser_end_omp_structured_block (parser, save); add_stmt (finish_omp_structured_block (sb)); @@ -27612,12 +28190,12 @@ cp_parser_omp_sections_scope (cp_parser # pragma omp sections sections-clause[optseq] newline sections-scope */ -#define OMP_SECTIONS_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_SECTIONS_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree cp_parser_omp_sections (cp_parser *parser, cp_token *pragma_tok) @@ -27637,17 +28215,21 @@ cp_parser_omp_sections (cp_parser *parse /* OpenMP 2.5: # pragma parallel parallel-clause new-line # pragma parallel for parallel-for-clause new-line - # pragma parallel sections parallel-sections-clause new-line */ + # pragma parallel sections parallel-sections-clause new-line + + OpenMP 4.0: + # pragma parallel for simd parallel-for-simd-clause new-line */ -#define OMP_PARALLEL_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_IF) \ - | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ - | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ - | (1u << PRAGMA_OMP_CLAUSE_COPYIN) \ - | (1u << PRAGMA_OMP_CLAUSE_REDUCTION) \ - | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS)) +#define OMP_PARALLEL_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND)) static tree cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok) @@ -27655,7 +28237,7 @@ cp_parser_omp_parallel (cp_parser *parse enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL; const char *p_name = "#pragma omp parallel"; tree stmt, clauses, par_clause, ws_clause, block; - unsigned int mask = OMP_PARALLEL_CLAUSE_MASK; + omp_clause_mask mask = OMP_PARALLEL_CLAUSE_MASK; unsigned int save; location_t loc = cp_lexer_peek_token (parser->lexer)->location; @@ -27665,7 +28247,20 @@ cp_parser_omp_parallel (cp_parser *parse p_kind = PRAGMA_OMP_PARALLEL_FOR; p_name = "#pragma omp parallel for"; mask |= OMP_FOR_CLAUSE_MASK; - mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); + mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp (p, "simd") == 0) + { + cp_lexer_consume_token (parser->lexer); + p_kind = PRAGMA_OMP_PARALLEL_FOR_SIMD; + p_name = "#pragma omp parallel for simd"; + mask |= OMP_SIMD_CLAUSE_MASK; + } + } } else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { @@ -27677,7 +28271,7 @@ cp_parser_omp_parallel (cp_parser *parse p_kind = PRAGMA_OMP_PARALLEL_SECTIONS; p_name = "#pragma omp parallel sections"; mask |= OMP_SECTIONS_CLAUSE_MASK; - mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT); + mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); } } @@ -27694,7 +28288,12 @@ cp_parser_omp_parallel (cp_parser *parse case PRAGMA_OMP_PARALLEL_FOR: c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause); - cp_parser_omp_for_loop (parser, ws_clause, &par_clause); + cp_parser_omp_for_loop (parser, OMP_FOR, ws_clause, &par_clause); + break; + + case PRAGMA_OMP_PARALLEL_FOR_SIMD: + c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause); + cp_parser_omp_for_loop (parser, OMP_FOR_SIMD, ws_clause, &par_clause); break; case PRAGMA_OMP_PARALLEL_SECTIONS: @@ -27719,11 +28318,11 @@ cp_parser_omp_parallel (cp_parser *parse # pragma omp single single-clause[optseq] new-line structured-block */ -#define OMP_SINGLE_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_NOWAIT)) +#define OMP_SINGLE_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) static tree cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok) @@ -27743,15 +28342,16 @@ cp_parser_omp_single (cp_parser *parser, # pragma omp task task-clause[optseq] new-line structured-block */ -#define OMP_TASK_CLAUSE_MASK \ - ( (1u << PRAGMA_OMP_CLAUSE_IF) \ - | (1u << PRAGMA_OMP_CLAUSE_UNTIED) \ - | (1u << PRAGMA_OMP_CLAUSE_DEFAULT) \ - | (1u << PRAGMA_OMP_CLAUSE_PRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ - | (1u << PRAGMA_OMP_CLAUSE_SHARED) \ - | (1u << PRAGMA_OMP_CLAUSE_FINAL) \ - | (1u << PRAGMA_OMP_CLAUSE_MERGEABLE)) +#define OMP_TASK_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)) static tree cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok) @@ -27802,6 +28402,63 @@ cp_parser_omp_threadprivate (cp_parser * finish_omp_threadprivate (vars); } +/* OpenMP 4.0: + # pragma omp cancel cancel-clause[optseq] new-line */ + +#define OMP_CANCEL_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) + +static void +cp_parser_omp_cancel (cp_parser *parser, cp_token *pragma_tok) +{ + tree clauses = cp_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK, + "#pragma omp cancel", pragma_tok); + finish_omp_cancel (clauses); +} + +/* OpenMP 4.0: + # pragma omp cancellation point cancelpt-clause[optseq] new-line */ + +#define OMP_CANCELLATION_POINT_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)) + +static void +cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok) +{ + tree clauses; + bool point_seen = false; + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp (p, "point") == 0) + { + cp_lexer_consume_token (parser->lexer); + point_seen = true; + } + } + if (!point_seen) + { + cp_parser_require_pragma_eol (parser, pragma_tok); + return; + } + + clauses = cp_parser_omp_all_clauses (parser, + OMP_CANCELLATION_POINT_CLAUSE_MASK, + "#pragma omp cancellation point", + pragma_tok); + finish_omp_cancellation_point (clauses); +} + /* Main entry point to OpenMP statement pragmas. */ static void @@ -27832,6 +28489,9 @@ cp_parser_omp_construct (cp_parser *pars case PRAGMA_OMP_SECTIONS: stmt = cp_parser_omp_sections (parser, pragma_tok); break; + case PRAGMA_OMP_SIMD: + stmt = cp_parser_omp_simd (parser, pragma_tok); + break; case PRAGMA_OMP_SINGLE: stmt = cp_parser_omp_single (parser, pragma_tok); break; @@ -28264,6 +28924,38 @@ cp_parser_pragma (cp_parser *parser, enu } break; + case PRAGMA_OMP_CANCEL: + switch (context) + { + case pragma_compound: + cp_parser_omp_cancel (parser, pragma_tok); + return false; + case pragma_stmt: + error_at (pragma_tok->location, + "%<#pragma omp cancel%> may only be " + "used in compound statements"); + break; + default: + goto bad_stmt; + } + break; + + case PRAGMA_OMP_CANCELLATION_POINT: + switch (context) + { + case pragma_compound: + cp_parser_omp_cancellation_point (parser, pragma_tok); + return false; + case pragma_stmt: + error_at (pragma_tok->location, + "%<#pragma omp cancellation point%> may only be " + "used in compound statements"); + break; + default: + goto bad_stmt; + } + break; + case PRAGMA_OMP_THREADPRIVATE: cp_parser_omp_threadprivate (parser, pragma_tok); return false; @@ -28275,6 +28967,7 @@ cp_parser_pragma (cp_parser *parser, enu case PRAGMA_OMP_ORDERED: case PRAGMA_OMP_PARALLEL: case PRAGMA_OMP_SECTIONS: + case PRAGMA_OMP_SIMD: case PRAGMA_OMP_SINGLE: case PRAGMA_OMP_TASK: if (context == pragma_external) --- gcc/cp/pt.c.jj 2013-03-20 10:36:15.000000000 +0100 +++ gcc/cp/pt.c 2013-03-26 14:07:17.049503208 +0100 @@ -13198,6 +13198,9 @@ tsubst_expr (tree t, tree args, tsubst_f break; case OMP_FOR: + case OMP_SIMD: + case OMP_FOR_SIMD: + case OMP_DISTRIBUTE: { tree clauses, body, pre_body; tree declv, initv, condv, incrv; @@ -13225,8 +13228,8 @@ tsubst_expr (tree t, tree args, tsubst_f RECUR (OMP_FOR_BODY (t)); body = pop_stmt_list (body); - t = finish_omp_for (EXPR_LOCATION (t), declv, initv, condv, incrv, - body, pre_body, clauses); + t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv, initv, + condv, incrv, body, pre_body, clauses); add_stmt (finish_omp_structured_block (stmt)); } --- gcc/tree-pretty-print.c.jj 2013-03-20 10:04:57.000000000 +0100 +++ gcc/tree-pretty-print.c 2013-03-26 14:00:30.004838688 +0100 @@ -314,11 +314,20 @@ dump_omp_clause (pretty_printer *buffer, case OMP_CLAUSE_COPYPRIVATE: name = "copyprivate"; goto print_remap; + case OMP_CLAUSE_FROM: + name = "from"; + goto print_remap; + case OMP_CLAUSE_TO: + name = "to"; + goto print_remap; + case OMP_CLAUSE_UNIFORM: + name = "uniform"; + goto print_remap; print_remap: pp_string (buffer, name); pp_character (buffer, '('); dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), - spc, flags, false); + spc, flags, false); pp_character (buffer, ')'); break; @@ -327,21 +336,21 @@ dump_omp_clause (pretty_printer *buffer, pp_string (buffer, op_symbol_code (OMP_CLAUSE_REDUCTION_CODE (clause))); pp_character (buffer, ':'); dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), - spc, flags, false); + spc, flags, false); pp_character (buffer, ')'); break; case OMP_CLAUSE_IF: pp_string (buffer, "if("); dump_generic_node (buffer, OMP_CLAUSE_IF_EXPR (clause), - spc, flags, false); + spc, flags, false); pp_character (buffer, ')'); break; case OMP_CLAUSE_NUM_THREADS: pp_string (buffer, "num_threads("); dump_generic_node (buffer, OMP_CLAUSE_NUM_THREADS_EXPR (clause), - spc, flags, false); + spc, flags, false); pp_character (buffer, ')'); break; @@ -380,30 +389,29 @@ dump_omp_clause (pretty_printer *buffer, pp_string (buffer, "schedule("); switch (OMP_CLAUSE_SCHEDULE_KIND (clause)) { - case OMP_CLAUSE_SCHEDULE_STATIC: - pp_string (buffer, "static"); - break; - case OMP_CLAUSE_SCHEDULE_DYNAMIC: - pp_string (buffer, "dynamic"); - break; - case OMP_CLAUSE_SCHEDULE_GUIDED: - pp_string (buffer, "guided"); - break; - case OMP_CLAUSE_SCHEDULE_RUNTIME: - pp_string (buffer, "runtime"); - break; - case OMP_CLAUSE_SCHEDULE_AUTO: - pp_string (buffer, "auto"); - break; - default: - gcc_unreachable (); + case OMP_CLAUSE_SCHEDULE_STATIC: + pp_string (buffer, "static"); + break; + case OMP_CLAUSE_SCHEDULE_DYNAMIC: + pp_string (buffer, "dynamic"); + break; + case OMP_CLAUSE_SCHEDULE_GUIDED: + pp_string (buffer, "guided"); + break; + case OMP_CLAUSE_SCHEDULE_RUNTIME: + pp_string (buffer, "runtime"); + break; + case OMP_CLAUSE_SCHEDULE_AUTO: + pp_string (buffer, "auto"); + break; + default: + gcc_unreachable (); } if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause)) { pp_character (buffer, ','); - dump_generic_node (buffer, - OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause), - spc, flags, false); + dump_generic_node (buffer, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause), + spc, flags, false); } pp_character (buffer, ')'); break; @@ -414,8 +422,7 @@ dump_omp_clause (pretty_printer *buffer, case OMP_CLAUSE_COLLAPSE: pp_string (buffer, "collapse("); - dump_generic_node (buffer, - OMP_CLAUSE_COLLAPSE_EXPR (clause), + dump_generic_node (buffer, OMP_CLAUSE_COLLAPSE_EXPR (clause), spc, flags, false); pp_character (buffer, ')'); break; @@ -423,7 +430,7 @@ dump_omp_clause (pretty_printer *buffer, case OMP_CLAUSE_FINAL: pp_string (buffer, "final("); dump_generic_node (buffer, OMP_CLAUSE_FINAL_EXPR (clause), - spc, flags, false); + spc, flags, false); pp_character (buffer, ')'); break; @@ -431,6 +438,154 @@ dump_omp_clause (pretty_printer *buffer, pp_string (buffer, "mergeable"); break; + case OMP_CLAUSE_LINEAR: + pp_string (buffer, "linear("); + dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), + spc, flags, false); + pp_character (buffer, ':'); + dump_generic_node (buffer, OMP_CLAUSE_LINEAR_STEP (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_ALIGNED: + pp_string (buffer, "aligned("); + dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), + spc, flags, false); + if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause)) + { + pp_character (buffer, ':'); + dump_generic_node (buffer, OMP_CLAUSE_ALIGNED_ALIGNMENT (clause), + spc, flags, false); + } + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_DEPEND: + pp_string (buffer, "depend("); + switch (OMP_CLAUSE_DEPEND_KIND (clause)) + { + case OMP_CLAUSE_DEPEND_IN: + pp_string (buffer, "in"); + break; + case OMP_CLAUSE_DEPEND_OUT: + pp_string (buffer, "out"); + break; + case OMP_CLAUSE_DEPEND_INOUT: + pp_string (buffer, "inout"); + break; + default: + gcc_unreachable (); + } + pp_character (buffer, ':'); + dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_MAP: + pp_string (buffer, "map("); + switch (OMP_CLAUSE_MAP_KIND (clause)) + { + case OMP_CLAUSE_MAP_ALLOC: + pp_string (buffer, "alloc"); + break; + case OMP_CLAUSE_MAP_TO: + pp_string (buffer, "to"); + break; + case OMP_CLAUSE_MAP_FROM: + pp_string (buffer, "from"); + break; + case OMP_CLAUSE_MAP_TOFROM: + pp_string (buffer, "tofrom"); + break; + default: + gcc_unreachable (); + } + pp_character (buffer, ':'); + dump_generic_node (buffer, OMP_CLAUSE_DECL (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_NUM_TEAMS: + pp_string (buffer, "num_teams("); + dump_generic_node (buffer, OMP_CLAUSE_NUM_TEAMS_EXPR (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_DEVICE: + pp_string (buffer, "device("); + dump_generic_node (buffer, OMP_CLAUSE_DEVICE_ID (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_DIST_SCHEDULE: + pp_string (buffer, "dist_schedule(static"); + if (OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause)) + { + pp_character (buffer, ','); + dump_generic_node (buffer, + OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause), + spc, flags, false); + } + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_PROC_BIND: + pp_string (buffer, "proc_bind("); + switch (OMP_CLAUSE_PROC_BIND_KIND (clause)) + { + case OMP_CLAUSE_PROC_BIND_MASTER: + pp_string (buffer, "master"); + break; + case OMP_CLAUSE_PROC_BIND_CLOSE: + pp_string (buffer, "close"); + break; + case OMP_CLAUSE_PROC_BIND_SPREAD: + pp_string (buffer, "spread"); + break; + default: + gcc_unreachable (); + } + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_SAFELEN: + pp_string (buffer, "safelen("); + dump_generic_node (buffer, OMP_CLAUSE_SAFELEN_EXPR (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_SIMDLEN: + pp_string (buffer, "simdlen("); + dump_generic_node (buffer, OMP_CLAUSE_SIMDLEN_EXPR (clause), + spc, flags, false); + pp_character (buffer, ')'); + break; + + case OMP_CLAUSE_INBRANCH: + pp_string (buffer, "inbranch"); + break; + case OMP_CLAUSE_NOTINBRANCH: + pp_string (buffer, "notinbranch"); + break; + case OMP_CLAUSE_FOR: + pp_string (buffer, "for"); + break; + case OMP_CLAUSE_PARALLEL: + pp_string (buffer, "parallel"); + break; + case OMP_CLAUSE_SECTIONS: + pp_string (buffer, "sections"); + break; + case OMP_CLAUSE_TASKGROUP: + pp_string (buffer, "taskgroup"); + break; + default: /* Should never happen. */ dump_generic_node (buffer, clause, spc, flags, false); @@ -2178,6 +2333,21 @@ dump_generic_node (pretty_printer *buffe case OMP_FOR: pp_string (buffer, "#pragma omp for"); + goto dump_omp_loop; + + case OMP_SIMD: + pp_string (buffer, "#pragma omp simd"); + goto dump_omp_loop; + + case OMP_FOR_SIMD: + pp_string (buffer, "#pragma omp for simd"); + goto dump_omp_loop; + + case OMP_DISTRIBUTE: + pp_string (buffer, "#pragma omp distribute"); + goto dump_omp_loop; + + dump_omp_loop: dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags); if (!(flags & TDF_SLIM)) --- gcc/tree.h.jj 2013-03-20 10:04:59.000000000 +0100 +++ gcc/tree.h 2013-03-26 13:59:02.756337558 +0100 @@ -361,6 +361,27 @@ enum omp_clause_code /* OpenMP clause: copyprivate (variable_list). */ OMP_CLAUSE_COPYPRIVATE, + /* OpenMP clause: linear (variable-list[:linear-step]). */ + OMP_CLAUSE_LINEAR, + + /* OpenMP clause: aligned (variable-list[:alignment]). */ + OMP_CLAUSE_ALIGNED, + + /* OpenMP clause: depend ({in,out,inout}:variable-list). */ + OMP_CLAUSE_DEPEND, + + /* OpenMP clause: from (variable-list). */ + OMP_CLAUSE_FROM, + + /* OpenMP clause: to (variable-list). */ + OMP_CLAUSE_TO, + + /* OpenMP clause: uniform (argument-list). */ + OMP_CLAUSE_UNIFORM, + + /* OpenMP clause: map ({alloc:,to:,from:,tofrom:,}variable-list). */ + OMP_CLAUSE_MAP, + /* OpenMP clause: if (scalar-expression). */ OMP_CLAUSE_IF, @@ -389,7 +410,43 @@ enum omp_clause_code OMP_CLAUSE_FINAL, /* OpenMP clause: mergeable. */ - OMP_CLAUSE_MERGEABLE + OMP_CLAUSE_MERGEABLE, + + /* OpenMP clause: device (integer-expression). */ + OMP_CLAUSE_DEVICE, + + /* OpenMP clause: dist_schedule (static[:chunk-size]). */ + OMP_CLAUSE_DIST_SCHEDULE, + + /* OpenMP clause: inbranch. */ + OMP_CLAUSE_INBRANCH, + + /* OpenMP clause: notinbranch. */ + OMP_CLAUSE_NOTINBRANCH, + + /* OpenMP clause: num_teams(integer-expression). */ + OMP_CLAUSE_NUM_TEAMS, + + /* OpenMP clause: proc_bind ({master,close,spread}). */ + OMP_CLAUSE_PROC_BIND, + + /* OpenMP clause: safelen (constant-integer-expression). */ + OMP_CLAUSE_SAFELEN, + + /* OpenMP clause: simdlen (constant-integer-expression). */ + OMP_CLAUSE_SIMDLEN, + + /* OpenMP clause: for. */ + OMP_CLAUSE_FOR, + + /* OpenMP clause: parallel. */ + OMP_CLAUSE_PARALLEL, + + /* OpenMP clause: sections. */ + OMP_CLAUSE_SECTIONS, + + /* OpenMP clause: taskgroup. */ + OMP_CLAUSE_TASKGROUP }; /* The definition of tree nodes fills the next several pages. */ @@ -1766,12 +1823,13 @@ extern void protected_set_expr_location #define OMP_TASKREG_BODY(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 0) #define OMP_TASKREG_CLAUSES(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 1) -#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 0) -#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 1) -#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 2) -#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 3) -#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 4) -#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 5) +#define OMP_LOOP_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OMP_DISTRIBUTE) +#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 0) +#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 1) +#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 2) +#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 3) +#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 4) +#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 5) #define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0) #define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1) @@ -1792,7 +1850,7 @@ extern void protected_set_expr_location #define OMP_CLAUSE_DECL(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \ OMP_CLAUSE_PRIVATE, \ - OMP_CLAUSE_COPYPRIVATE), 0) + OMP_CLAUSE_MAP), 0) #define OMP_CLAUSE_HAS_LOCATION(NODE) \ (LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \ != UNKNOWN_LOCATION) @@ -1859,6 +1917,28 @@ extern void protected_set_expr_location #define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3) +#define OMP_CLAUSE_LINEAR_STEP(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1) + +#define OMP_CLAUSE_ALIGNED_ALIGNMENT(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ALIGNED), 1) + +#define OMP_CLAUSE_NUM_TEAMS_EXPR(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TEAMS), 0) + +#define OMP_CLAUSE_DEVICE_ID(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE), 0) + +#define OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, \ + OMP_CLAUSE_DIST_SCHEDULE), 0) + +#define OMP_CLAUSE_SAFELEN_EXPR(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SAFELEN), 0) + +#define OMP_CLAUSE_SIMDLEN_EXPR(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SIMDLEN), 0) + enum omp_clause_schedule_kind { OMP_CLAUSE_SCHEDULE_STATIC, @@ -1883,6 +1963,40 @@ enum omp_clause_default_kind #define OMP_CLAUSE_DEFAULT_KIND(NODE) \ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind) +enum omp_clause_depend_kind +{ + OMP_CLAUSE_DEPEND_IN, + OMP_CLAUSE_DEPEND_OUT, + OMP_CLAUSE_DEPEND_INOUT +}; + +#define OMP_CLAUSE_DEPEND_KIND(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEPEND)->omp_clause.subcode.depend_kind) + +enum omp_clause_map_kind +{ + OMP_CLAUSE_MAP_ALLOC, + OMP_CLAUSE_MAP_TO, + OMP_CLAUSE_MAP_FROM, + OMP_CLAUSE_MAP_TOFROM +}; + +#define OMP_CLAUSE_MAP_KIND(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->omp_clause.subcode.map_kind) + +enum omp_clause_proc_bind_kind +{ + /* Numbers should match omp_proc_bind_t enum in omp.h. */ + OMP_CLAUSE_PROC_BIND_FALSE = 0, + OMP_CLAUSE_PROC_BIND_TRUE = 1, + OMP_CLAUSE_PROC_BIND_MASTER = 2, + OMP_CLAUSE_PROC_BIND_CLOSE = 3, + OMP_CLAUSE_PROC_BIND_SPREAD = 4 +}; + +#define OMP_CLAUSE_PROC_BIND_KIND(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind) + struct GTY(()) tree_exp { struct tree_typed typed; location_t locus; @@ -2006,9 +2120,12 @@ struct GTY(()) tree_omp_clause { location_t locus; enum omp_clause_code code; union omp_clause_subcode { - enum omp_clause_default_kind default_kind; - enum omp_clause_schedule_kind schedule_kind; - enum tree_code reduction_code; + enum omp_clause_default_kind default_kind; + enum omp_clause_schedule_kind schedule_kind; + enum omp_clause_depend_kind depend_kind; + enum omp_clause_map_kind map_kind; + enum omp_clause_proc_bind_kind proc_bind_kind; + enum tree_code reduction_code; } GTY ((skip)) subcode; /* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's @@ -4774,6 +4891,7 @@ extern tree build_translation_unit_decl extern tree build_block (tree, tree, tree, tree); extern tree build_empty_stmt (location_t); extern tree build_omp_clause (location_t, enum omp_clause_code); +extern tree find_omp_clause (tree, enum omp_clause_code); extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL); #define build_vl_exp(c,n) build_vl_exp_stat (c,n MEM_STAT_INFO) --- gcc/omp-builtins.def.jj 2013-03-20 10:08:27.000000000 +0100 +++ gcc/omp-builtins.def 2013-03-25 16:41:27.149863893 +0100 @@ -39,6 +39,10 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKWAIT BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) DEF_GOMP_BUILTIN (BUILT_IN_GOMP_TASKYIELD, "GOMP_taskyield", BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) +DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CANCEL, "GOMP_cancel", + BT_FN_VOID_INT, ATTR_NULL) +DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CANCELLATION_POINT, "GOMP_cancellation_point", + BT_FN_VOID_INT, ATTR_NULL) DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_START, "GOMP_critical_start", BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_END, "GOMP_critical_end", --- gcc/tree-flow.h.jj 2013-03-20 10:08:27.000000000 +0100 +++ gcc/tree-flow.h 2013-03-25 17:20:24.682552721 +0100 @@ -350,7 +350,6 @@ extern struct omp_region *new_omp_region struct omp_region *); extern void free_omp_regions (void); void omp_expand_local (basic_block); -extern tree find_omp_clause (tree, enum omp_clause_code); tree copy_var_decl (tree, tree, tree); /*--------------------------------------------------------------------------- --- gcc/c-family/c-omp.c.jj 2013-03-20 10:36:15.000000000 +0100 +++ gcc/c-family/c-omp.c 2013-03-26 14:34:06.856252885 +0100 @@ -343,8 +343,8 @@ check_omp_for_incr_expr (location_t loc, the loop. */ tree -c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv, - tree incrv, tree body, tree pre_body) +c_finish_omp_for (location_t locus, enum tree_code code, tree declv, + tree initv, tree condv, tree incrv, tree body, tree pre_body) { location_t elocus; bool fail = false; @@ -569,7 +569,7 @@ c_finish_omp_for (location_t locus, tree return NULL; else { - tree t = make_node (OMP_FOR); + tree t = make_node (code); TREE_TYPE (t) = void_type_node; OMP_FOR_INIT (t) = initv; @@ -621,6 +621,9 @@ c_split_parallel_clauses (location_t loc case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_COLLAPSE: + case OMP_CLAUSE_SAFELEN: + case OMP_CLAUSE_ALIGNED: + case OMP_CLAUSE_LINEAR: OMP_CLAUSE_CHAIN (clauses) = *ws_clauses; *ws_clauses = clauses; break; --- gcc/c-family/c-pragma.h.jj 2013-03-20 10:04:57.499336349 +0100 +++ gcc/c-family/c-pragma.h 2013-03-25 13:43:27.399526027 +0100 @@ -29,21 +29,36 @@ typedef enum pragma_kind { PRAGMA_OMP_ATOMIC, PRAGMA_OMP_BARRIER, + PRAGMA_OMP_CANCEL, + PRAGMA_OMP_CANCELLATION_POINT, PRAGMA_OMP_CRITICAL, + PRAGMA_OMP_DECLARE_REDUCTION, + PRAGMA_OMP_DECLARE_SIMD, + PRAGMA_OMP_DECLARE_TARGET, + PRAGMA_OMP_DISTRIBUTE, + PRAGMA_OMP_END_DECLARE_TARGET, PRAGMA_OMP_FLUSH, PRAGMA_OMP_FOR, + PRAGMA_OMP_FOR_SIMD, PRAGMA_OMP_MASTER, PRAGMA_OMP_ORDERED, PRAGMA_OMP_PARALLEL, PRAGMA_OMP_PARALLEL_FOR, + PRAGMA_OMP_PARALLEL_FOR_SIMD, PRAGMA_OMP_PARALLEL_SECTIONS, PRAGMA_OMP_SECTION, PRAGMA_OMP_SECTIONS, + PRAGMA_OMP_SIMD, PRAGMA_OMP_SINGLE, + PRAGMA_OMP_TARGET, + PRAGMA_OMP_TARGET_DATA, + PRAGMA_OMP_TARGET_UPDATE, PRAGMA_OMP_TASK, + PRAGMA_OMP_TASKGROUP, PRAGMA_OMP_TASKWAIT, PRAGMA_OMP_TASKYIELD, PRAGMA_OMP_THREADPRIVATE, + PRAGMA_OMP_TEAMS, PRAGMA_GCC_PCH_PREPROCESS, @@ -51,28 +66,47 @@ typedef enum pragma_kind { } pragma_kind; -/* All clauses defined by OpenMP 2.5 and 3.0. +/* All clauses defined by OpenMP 2.5, 3.0, 3.1 and 4.0. Used internally by both C and C++ parsers. */ typedef enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_NONE = 0, + PRAGMA_OMP_CLAUSE_ALIGNED, PRAGMA_OMP_CLAUSE_COLLAPSE, PRAGMA_OMP_CLAUSE_COPYIN, PRAGMA_OMP_CLAUSE_COPYPRIVATE, PRAGMA_OMP_CLAUSE_DEFAULT, + PRAGMA_OMP_CLAUSE_DEPEND, + PRAGMA_OMP_CLAUSE_DEVICE, + PRAGMA_OMP_CLAUSE_DIST_SCHEDULE, + PRAGMA_OMP_CLAUSE_FINAL, PRAGMA_OMP_CLAUSE_FIRSTPRIVATE, + PRAGMA_OMP_CLAUSE_FOR, + PRAGMA_OMP_CLAUSE_FROM, PRAGMA_OMP_CLAUSE_IF, + PRAGMA_OMP_CLAUSE_INBRANCH, PRAGMA_OMP_CLAUSE_LASTPRIVATE, + PRAGMA_OMP_CLAUSE_LINEAR, + PRAGMA_OMP_CLAUSE_MAP, + PRAGMA_OMP_CLAUSE_MERGEABLE, + PRAGMA_OMP_CLAUSE_NOTINBRANCH, PRAGMA_OMP_CLAUSE_NOWAIT, + PRAGMA_OMP_CLAUSE_NUM_TEAMS, PRAGMA_OMP_CLAUSE_NUM_THREADS, PRAGMA_OMP_CLAUSE_ORDERED, + PRAGMA_OMP_CLAUSE_PARALLEL, PRAGMA_OMP_CLAUSE_PRIVATE, + PRAGMA_OMP_CLAUSE_PROC_BIND, PRAGMA_OMP_CLAUSE_REDUCTION, + PRAGMA_OMP_CLAUSE_SAFELEN, PRAGMA_OMP_CLAUSE_SCHEDULE, + PRAGMA_OMP_CLAUSE_SECTIONS, PRAGMA_OMP_CLAUSE_SHARED, - PRAGMA_OMP_CLAUSE_UNTIED, - PRAGMA_OMP_CLAUSE_FINAL, - PRAGMA_OMP_CLAUSE_MERGEABLE + PRAGMA_OMP_CLAUSE_SIMDLEN, + PRAGMA_OMP_CLAUSE_TASKGROUP, + PRAGMA_OMP_CLAUSE_TO, + PRAGMA_OMP_CLAUSE_UNIFORM, + PRAGMA_OMP_CLAUSE_UNTIED } pragma_omp_clause; extern struct cpp_reader* parse_in; --- gcc/c-family/c-pragma.c.jj 2013-03-20 10:04:57.498336355 +0100 +++ gcc/c-family/c-pragma.c 2013-03-25 13:43:52.670382258 +0100 @@ -1162,7 +1162,11 @@ struct omp_pragma_def { const char *name static const struct omp_pragma_def omp_pragmas[] = { { "atomic", PRAGMA_OMP_ATOMIC }, { "barrier", PRAGMA_OMP_BARRIER }, + { "cancel", PRAGMA_OMP_CANCEL }, + { "cancellation", PRAGMA_OMP_CANCELLATION_POINT }, { "critical", PRAGMA_OMP_CRITICAL }, + { "declare", PRAGMA_OMP_DECLARE_REDUCTION }, + { "end", PRAGMA_OMP_END_DECLARE_TARGET }, { "flush", PRAGMA_OMP_FLUSH }, { "for", PRAGMA_OMP_FOR }, { "master", PRAGMA_OMP_MASTER }, @@ -1170,10 +1174,14 @@ static const struct omp_pragma_def omp_p { "parallel", PRAGMA_OMP_PARALLEL }, { "section", PRAGMA_OMP_SECTION }, { "sections", PRAGMA_OMP_SECTIONS }, + { "simd", PRAGMA_OMP_SIMD }, { "single", PRAGMA_OMP_SINGLE }, + { "target", PRAGMA_OMP_TARGET }, { "task", PRAGMA_OMP_TASK }, + { "taskgroup", PRAGMA_OMP_TASKGROUP }, { "taskwait", PRAGMA_OMP_TASKWAIT }, { "taskyield", PRAGMA_OMP_TASKYIELD }, + { "teams", PRAGMA_OMP_TEAMS }, { "threadprivate", PRAGMA_OMP_THREADPRIVATE } }; --- gcc/c-family/c-common.h.jj 2013-03-20 10:36:15.130435868 +0100 +++ gcc/c-family/c-common.h 2013-03-26 14:01:23.458525474 +0100 @@ -1039,7 +1039,8 @@ extern tree c_finish_omp_atomic (locatio extern void c_finish_omp_flush (location_t); extern void c_finish_omp_taskwait (location_t); extern void c_finish_omp_taskyield (location_t); -extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree); +extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree, + tree, tree, tree); extern void c_split_parallel_clauses (location_t, tree, tree *, tree *); extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree); @@ -1133,4 +1134,129 @@ enum stv_conv { extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1, bool); +#if HOST_BITS_PER_WIDE_INT >= 64 +typedef unsigned HOST_WIDE_INT omp_clause_mask; +# define OMP_CLAUSE_MASK_1 ((omp_clause_mask) 1) +#else +struct omp_clause_mask +{ + inline omp_clause_mask (); + inline omp_clause_mask (unsigned HOST_WIDE_INT l); + inline omp_clause_mask (unsigned HOST_WIDE_INT l, + unsigned HOST_WIDE_INT h); + inline omp_clause_mask &operator &= (omp_clause_mask); + inline omp_clause_mask &operator |= (omp_clause_mask); + inline omp_clause_mask operator ~ () const; + inline omp_clause_mask operator & (omp_clause_mask) const; + inline omp_clause_mask operator | (omp_clause_mask) const; + inline omp_clause_mask operator >> (int); + inline omp_clause_mask operator << (int); + inline bool operator == (omp_clause_mask) const; + unsigned HOST_WIDE_INT low, high; +}; + +inline +omp_clause_mask::omp_clause_mask () +{ +} + +inline +omp_clause_mask::omp_clause_mask (unsigned HOST_WIDE_INT l) +: low (l), high (0) +{ +} + +inline +omp_clause_mask::omp_clause_mask (unsigned HOST_WIDE_INT l, + unsigned HOST_WIDE_INT h) +: low (l), high (h) +{ +} + +inline omp_clause_mask & +omp_clause_mask::operator &= (omp_clause_mask b) +{ + low &= b.low; + high &= b.high; + return *this; +} + +inline omp_clause_mask & +omp_clause_mask::operator |= (omp_clause_mask b) +{ + low |= b.low; + high |= b.high; + return *this; +} + +inline omp_clause_mask +omp_clause_mask::operator ~ () const +{ + omp_clause_mask ret (~low, ~high); + return ret; +} + +inline omp_clause_mask +omp_clause_mask::operator | (omp_clause_mask b) const +{ + omp_clause_mask ret (low | b.low, high | b.high); + return ret; +} + +inline omp_clause_mask +omp_clause_mask::operator & (omp_clause_mask b) const +{ + omp_clause_mask ret (low & b.low, high & b.high); + return ret; +} + +inline omp_clause_mask +omp_clause_mask::operator << (int amount) +{ + omp_clause_mask ret; + if (amount >= HOST_BITS_PER_WIDE_INT) + { + ret.low = 0; + ret.high = low << (amount - HOST_BITS_PER_WIDE_INT); + } + else if (amount == 0) + ret = *this; + else + { + ret.low = low << amount; + ret.high = (low >> (HOST_BITS_PER_WIDE_INT - amount)) + | (high << amount); + } + return ret; +} + +inline omp_clause_mask +omp_clause_mask::operator >> (int amount) +{ + omp_clause_mask ret; + if (amount >= HOST_BITS_PER_WIDE_INT) + { + ret.low = high >> (amount - HOST_BITS_PER_WIDE_INT); + ret.high = 0; + } + else if (amount == 0) + ret = *this; + else + { + ret.low = (high << (HOST_BITS_PER_WIDE_INT - amount)) + | (low >> amount); + ret.high = high >> amount; + } + return ret; +} + +inline bool +omp_clause_mask::operator == (omp_clause_mask b) const +{ + return low == b.low && high == b.high; +} + +# define OMP_CLAUSE_MASK_1 omp_clause_mask (1) +#endif + #endif /* ! GCC_C_COMMON_H */