From patchwork Thu Dec 7 15:52:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1873281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SmJjH2XVsz1ySY for ; Fri, 8 Dec 2023 02:53:55 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5FF223861844 for ; Thu, 7 Dec 2023 15:53:53 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) by sourceware.org (Postfix) with ESMTPS id 6A810385C40F for ; Thu, 7 Dec 2023 15:53:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6A810385C40F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6A810385C40F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.129.153 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964392; cv=none; b=GS+et902mTz0iWmSjVb82TTkbYbu2uk0PNqAfxcH9/CrQgdg7IxEYlOgPvkp0XGE0v1wp8crlKC4k2+k/3a3MeVtmFHOjrX/Vf3qlrG34rlNOtBL2FaGGGwKtxDkgjJetXVrzW/KUCnI3/HS6sKiIkSHvVTirFb1ROjuGIvgrQU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964392; c=relaxed/simple; bh=U2TLZZTC+T82oe9DuTxyTKkP2Shs1hhlAq8W8wE253c=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=I+c//kCyCgWDVGlpNYnlUA/qUXUNgcLIJ1R8cxH8S7nDNKtFZ0L1dYHts8ytdE7njZUX4/fZbFfrtNpNJhC2k204ykNp2tv1xNfTbbfflrMYklA0n1umFPijBft9LDo0FXa1DhGjItkoCY0A0kOJu00q/pOc5/gIzxtdhmaB7VE= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: ajZajqR9SzuinXLC0TvilA== X-CSE-MsgGUID: 28KtLtaPTlG/qEJCb8t3zQ== X-IronPort-AV: E=Sophos;i="6.04,256,1695715200"; d="scan'208";a="27954247" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 07 Dec 2023 07:53:06 -0800 IronPort-SDR: yEkZtC4H2kExFgnXJc4VKN4kcu43SMu42wZjFzBVcbHwIhWTUeLoS4/0xdni/y1dDVvdzngYfx Y1MNKw+ZoTJCX9r0S7zxvEIKOsMD+UHiruqNRw253RXqI4UKpMJkpMKOYo5ib6aYL8v2PPjzrR Q4o7DDXFn+pzOhkcKTfblLk/ijQaewMtDnEkbRgT4krfTo1G3CO+p3eyKQNLheF4979w9jUAcq C8x9ICqxMFjFxyPldbv8QYgUIdBCHAlp7NvTbx4CDVgzjK0PJE3uU7MhLXYzQYrDj6Xg52VQ1m dgA= From: Sandra Loosemore To: CC: , , Subject: [PATCH V3 1/4] OpenMP: Introduce accessor macros and constructors for context selectors. Date: Thu, 7 Dec 2023 08:52:44 -0700 Message-ID: <20231207155247.372718-2-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207155247.372718-1-sandra@codesourcery.com> References: <20231207155247.372718-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: svr-orw-mbx-14.mgc.mentorg.com (147.34.90.214) To svr-orw-mbx-13.mgc.mentorg.com (147.34.90.213) X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org This patch hides the underlying nested TREE_LIST structure of context selectors behind accessor macros that have more meaningful names than the generic TREE_PURPOSE/TREE_VALUE accessors. There is a slight change to the representation in that the score expression in trait-selectors has a distinguished tag and is separated from the ordinary properties, although internally it is still represented as the first item in the TREE_VALUE of the selector. This patch also renames some local variables with slightly more descriptive names so it is easier to track whether something is a selector-set, selector, or property. gcc/ChangeLog * omp-general.h (OMP_TS_SCORE_NODE): New. (OMP_TSS_ID, OMP_TSS_TRAIT_SELECTORS): New. (OMP_TS_ID, OMP_TS_SCORE, OMP_TS_PROPERTIES): New. (OMP_TP_NAME, OMP_TP_VALUE): New. (make_trait_set_selector): Declare. (make_trait_selector): Declare. (make_trait_property): Declare. (omp_constructor_traits_to_codes): Rename to omp_construct_traits_to_codes. * omp-general.cc (omp_constructor_traits_to_codes): Rename to omp_construct_traits_to_codes. Use new accessors. (omp_check_context_selector): Use new accessors. (make_trait_set_selector): New. (make_trait_selector): New. (make_trait_property): New. (omp_context_name_list_prop): Use new accessors. (omp_context_selector_matches): Use new accessors. (omp_context_selector_props_compare): Use new accessors. (omp_context_selector_set_compare): Use new accessors. (omp_get_context_selector): Use new accessors. (omp_context_compute_score): Use new accessors. * gimplify.cc (omp_construct_selector_matches): Adjust for renaming of omp_constructor_traits_to_codes. gcc/c/ChangeLog * c-parser.cc (c_parser_omp_context_selector): Use new constructors. gcc/cp/ChangeLog * parser.cc (cp_parser_omp_context_selector): Use new constructors. * pt.cc: Include omp-general.h. (tsubst_attribute): Use new context selector accessors and constructors. gcc/fortran/ChangeLog * trans-openmp.cc (gfc_trans_omp_declare_variant): Use new constructors. --- gcc/c/c-parser.cc | 27 ++-- gcc/cp/parser.cc | 30 ++-- gcc/cp/pt.cc | 82 ++++++---- gcc/fortran/trans-openmp.cc | 27 ++-- gcc/gimplify.cc | 4 +- gcc/omp-general.cc | 293 ++++++++++++++++++------------------ gcc/omp-general.h | 48 +++++- 7 files changed, 297 insertions(+), 214 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index df9a07928b5..9a17a8c5760 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24353,7 +24353,10 @@ static const char *const omp_user_selectors[] = { trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])] trait-score: - score(score-expression) */ + score(score-expression) + + Note that this function returns a list of trait selectors for the + trait-selector-set SET. */ static tree c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) @@ -24372,6 +24375,7 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) } tree properties = NULL_TREE; + tree scoreval = NULL_TREE; const char *const *selectors = NULL; bool allow_score = true; bool allow_user = false; @@ -24478,8 +24482,7 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) error_at (token->location, "score argument must be " "non-negative"); else - properties = tree_cons (get_identifier (" score"), - score, properties); + scoreval = score; } token = c_parser_peek_token (parser); } @@ -24492,7 +24495,8 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) { t = c_parser_expr_no_commas (parser, NULL).value; if (TREE_CODE (t) == STRING_CST) - properties = tree_cons (NULL_TREE, t, properties); + properties = make_trait_property (NULL_TREE, t, + properties); else if (t != error_mark_node) { mark_exp_read (t); @@ -24503,7 +24507,8 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) "constant integer expression or string " "literal"); else - properties = tree_cons (NULL_TREE, t, properties); + properties = make_trait_property (NULL_TREE, t, + properties); } else return error_mark_node; @@ -24521,7 +24526,8 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) { tree prop = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); - properties = tree_cons (prop, NULL_TREE, properties); + properties = make_trait_property (prop, NULL_TREE, + properties); } else { @@ -24549,7 +24555,7 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) return error_mark_node; } - properties = tree_cons (prop, value, properties); + properties = make_trait_property (prop, value, properties); if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); @@ -24569,7 +24575,8 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) error_at (token->location, "property must be " "constant integer expression"); else - properties = tree_cons (NULL_TREE, t, properties); + properties = make_trait_property (NULL_TREE, t, + properties); } else return error_mark_node; @@ -24607,7 +24614,7 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) return error_mark_node; } - ret = tree_cons (selector, properties, ret); + ret = make_trait_selector (selector, scoreval, properties, ret); if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); @@ -24683,7 +24690,7 @@ c_parser_omp_context_selector_specification (c_parser *parser, tree parms) if (selectors == error_mark_node) ret = error_mark_node; else if (ret != error_mark_node) - ret = tree_cons (set, selectors, ret); + ret = make_trait_set_selector (set, selectors, ret); braces.skip_until_found_close (parser); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 732d2a919eb..9d4ae9726e5 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47341,7 +47341,10 @@ static const char *const omp_user_selectors[] = { trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])] trait-score: - score(score-expression) */ + score(score-expression) + + Note that this function returns a list of trait selectors for the + trait-selector-set SET. */ static tree cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) @@ -47360,6 +47363,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) } tree properties = NULL_TREE; + tree scoreval = NULL_TREE; const char *const *selectors = NULL; bool allow_score = true; bool allow_user = false; @@ -47466,8 +47470,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) { score = fold_non_dependent_expr (score); if (value_dependent_expression_p (score)) - properties = tree_cons (get_identifier (" score"), - score, properties); + scoreval = score; else if (!INTEGRAL_TYPE_P (TREE_TYPE (score)) || TREE_CODE (score) != INTEGER_CST) error_at (token->location, "score argument must be " @@ -47476,8 +47479,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) error_at (token->location, "score argument must be " "non-negative"); else - properties = tree_cons (get_identifier (" score"), - score, properties); + scoreval = score; } } else @@ -47497,7 +47499,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) { t = fold_non_dependent_expr (t); if (TREE_CODE (t) == STRING_CST) - properties = tree_cons (NULL_TREE, t, properties); + properties = make_trait_property (NULL_TREE, t, + properties); else if (!value_dependent_expression_p (t) && (!INTEGRAL_TYPE_P (TREE_TYPE (t)) || !tree_fits_shwi_p (t))) @@ -47505,7 +47508,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) "constant integer expression or string " "literal"); else - properties = tree_cons (NULL_TREE, t, properties); + properties = make_trait_property (NULL_TREE, t, + properties); } else return error_mark_node; @@ -47523,7 +47527,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) { tree prop = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); - properties = tree_cons (prop, NULL_TREE, properties); + properties = make_trait_property (prop, NULL_TREE, + properties); } else { @@ -47552,7 +47557,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) return error_mark_node; } - properties = tree_cons (prop, value, properties); + properties = make_trait_property (prop, value, properties); if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) cp_lexer_consume_token (parser->lexer); @@ -47572,7 +47577,8 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) error_at (token->location, "property must be " "constant integer expression"); else - properties = tree_cons (NULL_TREE, t, properties); + properties = make_trait_property (NULL_TREE, t, + properties); } else return error_mark_node; @@ -47607,7 +47613,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) return error_mark_node; } - ret = tree_cons (selector, properties, ret); + ret = make_trait_selector (selector, scoreval, properties, ret); if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) cp_lexer_consume_token (parser->lexer); @@ -47689,7 +47695,7 @@ cp_parser_omp_context_selector_specification (cp_parser *parser, ret = error_mark_node; } else if (ret != error_mark_node) - ret = tree_cons (set, selectors, ret); + ret = make_trait_set_selector (set, selectors, ret); braces.require_close (parser); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 669d2ad65c3..2541ad95cc1 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "selftest.h" #include "target.h" #include "builtins.h" +#include "omp-general.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -11818,50 +11819,72 @@ tsubst_attribute (tree t, tree *decl_p, tree args, location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain)); tree ctx = copy_list (TREE_VALUE (val)); tree simd = get_identifier ("simd"); - tree score = get_identifier (" score"); tree condition = get_identifier ("condition"); - for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) + for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) { - const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1)); - TREE_VALUE (t1) = copy_list (TREE_VALUE (t1)); - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + const char *set = IDENTIFIER_POINTER (OMP_TSS_ID (tss)); + tree selectors = NULL_TREE; + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; + ts = TREE_CHAIN (ts)) { - if (TREE_PURPOSE (t2) == simd && set[0] == 'c') + tree properties = NULL_TREE; + tree scoreval = NULL_TREE; + if (OMP_TS_ID (ts) == simd && set[0] == 'c') { - tree clauses = TREE_VALUE (t2); + tree clauses = OMP_TS_PROPERTIES (ts); clauses = tsubst_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD, args, complain, in_decl); c_omp_declare_simd_clauses_to_decls (*decl_p, clauses); clauses = finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD); - TREE_VALUE (t2) = clauses; + properties = clauses; } else { - TREE_VALUE (t2) = copy_list (TREE_VALUE (t2)); - for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3)) - if (TREE_VALUE (t3)) + tree v = OMP_TS_SCORE (ts); + if (v) + { + v = tsubst_expr (v, args, complain, in_decl); + v = fold_non_dependent_expr (v); + if (!INTEGRAL_TYPE_P (TREE_TYPE (v)) + || TREE_CODE (v) != INTEGER_CST) + { + location_t loc + = cp_expr_loc_or_loc (OMP_TS_SCORE (ts), + match_loc); + error_at (loc, "score argument must be " + "constant integer expression"); + return NULL_TREE; + } + else if (tree_int_cst_sgn (v) < 0) + { + location_t loc + = cp_expr_loc_or_loc (OMP_TS_SCORE (ts), + match_loc); + error_at (loc, "score argument must be " + "non-negative"); + return NULL_TREE; + } + scoreval = v; + } + properties = copy_list (OMP_TS_PROPERTIES (ts)); + for (tree p = properties; p; p = TREE_CHAIN (p)) + if (OMP_TP_VALUE (p)) { bool allow_string - = ((TREE_PURPOSE (t2) != condition || set[0] != 'u') - && TREE_PURPOSE (t3) != score); - tree v = TREE_VALUE (t3); + = (OMP_TS_ID (ts) != condition || set[0] != 'u'); + tree v = OMP_TP_VALUE (p); if (TREE_CODE (v) == STRING_CST && allow_string) continue; v = tsubst_expr (v, args, complain, in_decl); v = fold_non_dependent_expr (v); if (!INTEGRAL_TYPE_P (TREE_TYPE (v)) - || (TREE_PURPOSE (t3) == score - ? TREE_CODE (v) != INTEGER_CST - : !tree_fits_shwi_p (v))) + || !tree_fits_shwi_p (v)) { location_t loc - = cp_expr_loc_or_loc (TREE_VALUE (t3), + = cp_expr_loc_or_loc (OMP_TP_VALUE (p), match_loc); - if (TREE_PURPOSE (t3) == score) - error_at (loc, "score argument must be " - "constant integer expression"); - else if (allow_string) + if (allow_string) error_at (loc, "property must be constant " "integer expression or string " "literal"); @@ -11870,20 +11893,13 @@ tsubst_attribute (tree t, tree *decl_p, tree args, "integer expression"); return NULL_TREE; } - else if (TREE_PURPOSE (t3) == score - && tree_int_cst_sgn (v) < 0) - { - location_t loc - = cp_expr_loc_or_loc (TREE_VALUE (t3), - match_loc); - error_at (loc, "score argument must be " - "non-negative"); - return NULL_TREE; - } - TREE_VALUE (t3) = v; + OMP_TP_VALUE (p) = v; } } + selectors = make_trait_selector (OMP_TS_ID (ts), scoreval, + properties, selectors); } + OMP_TSS_TRAIT_SELECTORS (tss) = nreverse (selectors); } val = tree_cons (varid, ctx, chain); } diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 82bbc41b388..fe8044a57cd 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -8210,6 +8210,7 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) gfc_omp_selector *os; for (os = oss->trait_selectors; os; os = os->next) { + tree scoreval = NULL_TREE; tree properties = NULL_TREE; gfc_omp_trait_property *otp; @@ -8223,13 +8224,14 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) gfc_se se; gfc_init_se (&se, NULL); gfc_conv_expr (&se, otp->expr); - properties = tree_cons (NULL_TREE, se.expr, - properties); + properties = make_trait_property (NULL_TREE, se.expr, + properties); } break; case CTX_PROPERTY_ID: - properties = tree_cons (get_identifier (otp->name), - NULL_TREE, properties); + properties + = make_trait_property (get_identifier (otp->name), + NULL_TREE, properties); break; case CTX_PROPERTY_NAME_LIST: { @@ -8239,7 +8241,8 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) else value = gfc_conv_constant_to_tree (otp->expr); - properties = tree_cons (prop, value, properties); + properties = make_trait_property (prop, value, + properties); } break; case CTX_PROPERTY_SIMD: @@ -8256,17 +8259,17 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) gfc_se se; gfc_init_se (&se, NULL); gfc_conv_expr (&se, os->score); - properties = tree_cons (get_identifier (" score"), - se.expr, properties); + scoreval = se.expr; } - selectors = tree_cons (get_identifier (os->trait_selector_name), - properties, selectors); + tree ts_name = get_identifier (os->trait_selector_name); + selectors = make_trait_selector (ts_name, scoreval, + properties, selectors); } - set_selectors - = tree_cons (get_identifier (oss->trait_set_selector_name), - selectors, set_selectors); + tree tss_name = get_identifier (oss->trait_set_selector_name); + set_selectors = make_trait_set_selector (tss_name, selectors, + set_selectors); } const char *variant_proc_name = odv->variant_proc_symtree->name; diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 342e43a7f25..a71ef23c37b 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -13564,8 +13564,8 @@ omp_construct_selector_matches (enum tree_code *constructs, int nconstructs, int variant_nconstructs = 0; if (!target_seen) variant_nconstructs - = omp_constructor_traits_to_codes (TREE_VALUE (attr), - variant_constructs); + = omp_construct_traits_to_codes (TREE_VALUE (attr), + variant_constructs); for (int i = 0; i < variant_nconstructs; i++) { ++cnt; diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index 8241574651d..75980fcf4da 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1017,13 +1017,13 @@ omp_max_simt_vf (void) return their number. */ int -omp_constructor_traits_to_codes (tree ctx, enum tree_code *constructs) +omp_construct_traits_to_codes (tree ctx, enum tree_code *constructs) { int nconstructs = list_length (ctx); int i = nconstructs - 1; - for (tree t2 = ctx; t2; t2 = TREE_CHAIN (t2), i--) + for (tree ts = ctx; ts; ts = TREE_CHAIN (ts), i--) { - const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t2)); + const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts)); if (!strcmp (sel, "target")) constructs[i] = OMP_TARGET; else if (!strcmp (sel, "teams")) @@ -1125,38 +1125,40 @@ omp_check_context_selector (location_t loc, tree ctx) There are just 4 set names. */ for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + if (OMP_TSS_ID (t1) == OMP_TSS_ID (t2)) { error_at (loc, "selector set %qs specified more than once", - IDENTIFIER_POINTER (TREE_PURPOSE (t1))); + IDENTIFIER_POINTER (OMP_TSS_ID (t1))); return error_mark_node; } - for (tree t = ctx; t; t = TREE_CHAIN (t)) + for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) { /* Each trait-selector-name can only be specified once. */ - if (list_length (TREE_VALUE (t)) < 5) + if (list_length (OMP_TSS_TRAIT_SELECTORS (tss)) < 5) { - for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) - for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + for (tree ts1 = OMP_TSS_TRAIT_SELECTORS (tss); ts1; + ts1 = TREE_CHAIN (ts1)) + for (tree ts2 = TREE_CHAIN (ts1); ts2; ts2 = TREE_CHAIN (ts2)) + if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2)) { error_at (loc, "selector %qs specified more than once in set %qs", - IDENTIFIER_POINTER (TREE_PURPOSE (t1)), - IDENTIFIER_POINTER (TREE_PURPOSE (t))); + IDENTIFIER_POINTER (OMP_TS_ID (ts1)), + IDENTIFIER_POINTER (OMP_TSS_ID (tss))); return error_mark_node; } } else { hash_set pset; - for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) - if (pset.add (TREE_PURPOSE (t1))) + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; + ts = TREE_CHAIN (ts)) + if (pset.add (OMP_TS_ID (ts))) { error_at (loc, "selector %qs specified more than once in set %qs", - IDENTIFIER_POINTER (TREE_PURPOSE (t1)), - IDENTIFIER_POINTER (TREE_PURPOSE (t))); + IDENTIFIER_POINTER (OMP_TS_ID (ts)), + IDENTIFIER_POINTER (OMP_TSS_ID (tss))); return error_mark_node; } } @@ -1177,49 +1179,45 @@ omp_check_context_selector (location_t loc, tree ctx) { "implementation", "extension", extension }, { "implementation", "atomic_default_mem_order", atomic_default_mem_order } }; - for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) for (unsigned i = 0; i < ARRAY_SIZE (props); i++) - if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)), + if (!strcmp (IDENTIFIER_POINTER (OMP_TS_ID (ts)), props[i].selector) - && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)), + && !strcmp (IDENTIFIER_POINTER (OMP_TSS_ID (tss)), props[i].set)) - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) for (unsigned j = 0; ; j++) { if (props[i].props[j] == NULL) { - if (TREE_PURPOSE (t2) - && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), - " score")) - break; if (props[i].props == atomic_default_mem_order) { error_at (loc, "incorrect property %qs of %qs selector", - IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + IDENTIFIER_POINTER (TREE_PURPOSE (p)), "atomic_default_mem_order"); return error_mark_node; } - else if (TREE_PURPOSE (t2)) + else if (OMP_TP_NAME (p)) warning_at (loc, OPT_Wopenmp, "unknown property %qs of %qs selector", - IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].selector); else warning_at (loc, OPT_Wopenmp, "unknown property %qE of %qs selector", - TREE_VALUE (t2), props[i].selector); + OMP_TP_VALUE (p), props[i].selector); break; } - else if (TREE_PURPOSE (t2) == NULL_TREE) + else if (OMP_TP_NAME (p) == NULL_TREE) { - const char *str = TREE_STRING_POINTER (TREE_VALUE (t2)); + const char *str = TREE_STRING_POINTER (OMP_TP_VALUE (p)); if (!strcmp (str, props[i].props[j]) - && ((size_t) TREE_STRING_LENGTH (TREE_VALUE (t2)) + && ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (p)) == strlen (str) + (lang_GNU_Fortran () ? 0 : 1))) break; } - else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + else if (!strcmp (IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].props[j])) break; } @@ -1254,18 +1252,43 @@ omp_mark_declare_variant (location_t loc, tree variant, tree construct) } +/* Constructors for context selectors. */ + +tree +make_trait_set_selector (tree name, tree selectors, tree chain) +{ + return tree_cons (name, selectors, chain); +} + +tree +make_trait_selector (tree name, tree score, tree properties, tree chain) +{ + if (score == NULL_TREE) + return tree_cons (name, properties, chain); + else + return tree_cons (name, + tree_cons (OMP_TS_SCORE_NODE, score, properties), + chain); +} + +tree +make_trait_property (tree name, tree value, tree chain) +{ + return tree_cons (name, value, chain); +} + /* Return a name from PROP, a property in selectors accepting name lists. */ static const char * omp_context_name_list_prop (tree prop) { - if (TREE_PURPOSE (prop)) - return IDENTIFIER_POINTER (TREE_PURPOSE (prop)); + if (OMP_TP_NAME (prop)) + return IDENTIFIER_POINTER (OMP_TP_NAME (prop)); else { - const char *ret = TREE_STRING_POINTER (TREE_VALUE (prop)); - if ((size_t) TREE_STRING_LENGTH (TREE_VALUE (prop)) + const char *ret = TREE_STRING_POINTER (OMP_TP_VALUE (prop)); + if ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (prop)) == strlen (ret) + (lang_GNU_Fortran () ? 0 : 1)) return ret; return NULL; @@ -1282,9 +1305,9 @@ int omp_context_selector_matches (tree ctx) { int ret = 1; - for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) + for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) { - char set = IDENTIFIER_POINTER (TREE_PURPOSE (t1))[0]; + char set = IDENTIFIER_POINTER (OMP_TSS_ID (tss))[0]; if (set == 'c') { /* For now, ignore the construct set. While something can be @@ -1302,7 +1325,8 @@ omp_context_selector_matches (tree ctx) enum tree_code constructs[5]; int nconstructs - = omp_constructor_traits_to_codes (TREE_VALUE (t1), constructs); + = omp_construct_traits_to_codes (OMP_TSS_TRAIT_SELECTORS (tss), + constructs); if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) { @@ -1333,20 +1357,19 @@ omp_context_selector_matches (tree ctx) ret = -1; continue; } - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) { - const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t2)); + const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts)); switch (*sel) { case 'v': if (set == 'i' && !strcmp (sel, "vendor")) - for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3)) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { - const char *prop = omp_context_name_list_prop (t3); + const char *prop = omp_context_name_list_prop (p); if (prop == NULL) return 0; - if ((!strcmp (prop, " score") && TREE_PURPOSE (t3)) - || !strcmp (prop, "gnu")) + if (!strcmp (prop, "gnu")) continue; return 0; } @@ -1377,13 +1400,8 @@ omp_context_selector_matches (tree ctx) else omo = OMP_MEMORY_ORDER_RELAXED; } - tree t3 = TREE_VALUE (t2); - const char *prop = IDENTIFIER_POINTER (TREE_PURPOSE (t3)); - if (!strcmp (prop, " score")) - { - t3 = TREE_CHAIN (t3); - prop = IDENTIFIER_POINTER (TREE_PURPOSE (t3)); - } + tree p = OMP_TS_PROPERTIES (ts); + const char *prop = IDENTIFIER_POINTER (OMP_TP_NAME (p)); if (!strcmp (prop, "relaxed") && omo != OMP_MEMORY_ORDER_RELAXED) return 0; @@ -1395,9 +1413,9 @@ omp_context_selector_matches (tree ctx) return 0; } if (set == 'd' && !strcmp (sel, "arch")) - for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3)) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { - const char *arch = omp_context_name_list_prop (t3); + const char *arch = omp_context_name_list_prop (p); if (arch == NULL) return 0; int r = 0; @@ -1497,9 +1515,9 @@ omp_context_selector_matches (tree ctx) break; case 'k': if (set == 'd' && !strcmp (sel, "kind")) - for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3)) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { - const char *prop = omp_context_name_list_prop (t3); + const char *prop = omp_context_name_list_prop (p); if (prop == NULL) return 0; if (!strcmp (prop, "any")) @@ -1558,9 +1576,9 @@ omp_context_selector_matches (tree ctx) break; case 'i': if (set == 'd' && !strcmp (sel, "isa")) - for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3)) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { - const char *isa = omp_context_name_list_prop (t3); + const char *isa = omp_context_name_list_prop (p); if (isa == NULL) return 0; int r = 0; @@ -1611,12 +1629,12 @@ omp_context_selector_matches (tree ctx) break; case 'c': if (set == 'u' && !strcmp (sel, "condition")) - for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3)) - if (TREE_PURPOSE (t3) == NULL_TREE) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) + if (OMP_TP_NAME (p) == NULL_TREE) { - if (integer_zerop (TREE_VALUE (t3))) + if (integer_zerop (OMP_TP_VALUE (p))) return 0; - if (integer_nonzerop (TREE_VALUE (t3))) + if (integer_nonzerop (OMP_TP_VALUE (p))) break; ret = -1; } @@ -1747,6 +1765,7 @@ omp_construct_simd_compare (tree clauses1, tree clauses2) } /* Compare properties of selectors SEL from SET other than construct. + CTX1 and CTX2 are the lists of properties to compare. Return 0/-1/1/2 as in omp_context_selector_set_compare. Unlike set names or selector names, properties can have duplicates. */ @@ -1756,57 +1775,37 @@ omp_context_selector_props_compare (const char *set, const char *sel, { int ret = 0; for (int pass = 0; pass < 2; pass++) - for (tree t1 = pass ? ctx2 : ctx1; t1; t1 = TREE_CHAIN (t1)) + for (tree p1 = pass ? ctx2 : ctx1; p1; p1 = TREE_CHAIN (p1)) { - tree t2; - for (t2 = pass ? ctx1 : ctx2; t2; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + tree p2; + for (p2 = pass ? ctx1 : ctx2; p2; p2 = TREE_CHAIN (p2)) + if (OMP_TP_NAME (p1) == OMP_TP_NAME (p2)) { - if (TREE_PURPOSE (t1) == NULL_TREE) + if (OMP_TP_NAME (p1) == NULL_TREE) { if (set[0] == 'u' && strcmp (sel, "condition") == 0) { - if (integer_zerop (TREE_VALUE (t1)) - != integer_zerop (TREE_VALUE (t2))) + if (integer_zerop (OMP_TP_VALUE (p1)) + != integer_zerop (OMP_TP_VALUE (p2))) return 2; break; } - if (simple_cst_equal (TREE_VALUE (t1), TREE_VALUE (t2))) + if (simple_cst_equal (OMP_TP_VALUE (p1), OMP_TP_VALUE (p2))) break; } - else if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)), - " score") == 0) - { - if (!simple_cst_equal (TREE_VALUE (t1), TREE_VALUE (t2))) - return 2; - break; - } else break; } - else if (TREE_PURPOSE (t1) - && TREE_PURPOSE (t2) == NULL_TREE - && TREE_CODE (TREE_VALUE (t2)) == STRING_CST) - { - const char *p1 = omp_context_name_list_prop (t1); - const char *p2 = omp_context_name_list_prop (t2); - if (p2 - && strcmp (p1, p2) == 0 - && strcmp (p1, " score")) - break; - } - else if (TREE_PURPOSE (t1) == NULL_TREE - && TREE_PURPOSE (t2) - && TREE_CODE (TREE_VALUE (t1)) == STRING_CST) + else { - const char *p1 = omp_context_name_list_prop (t1); - const char *p2 = omp_context_name_list_prop (t2); - if (p1 - && strcmp (p1, p2) == 0 - && strcmp (p1, " score")) + /* Handle string constant vs identifier comparison for + name-list properties. */ + const char *n1 = omp_context_name_list_prop (p1); + const char *n2 = omp_context_name_list_prop (p2); + if (n1 && n2 && !strcmp (n1, n2)) break; } - if (t2 == NULL_TREE) + if (p2 == NULL_TREE) { int r = pass ? -1 : 1; if (ret && ret != r) @@ -1824,6 +1823,7 @@ omp_context_selector_props_compare (const char *set, const char *sel, } /* Compare single context selector sets CTX1 and CTX2 with SET name. + CTX1 and CTX2 are lists of trait-selectors. Return 0 if CTX1 is equal to CTX2, -1 if CTX1 is a strict subset of CTX2, 1 if CTX2 is a strict subset of CTX1, or @@ -1845,26 +1845,26 @@ omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) } if (set[0] == 'c') { - tree t1; - tree t2 = ctx2; + tree ts1; + tree ts2 = ctx2; tree simd = get_identifier ("simd"); /* Handle construct set specially. In this case the order of the selector matters too. */ - for (t1 = ctx1; t1; t1 = TREE_CHAIN (t1)) - if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + for (ts1 = ctx1; ts1; ts1 = TREE_CHAIN (ts1)) + if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2)) { int r = 0; - if (TREE_PURPOSE (t1) == simd) - r = omp_construct_simd_compare (TREE_VALUE (t1), - TREE_VALUE (t2)); + if (OMP_TS_ID (ts1) == simd) + r = omp_construct_simd_compare (OMP_TS_PROPERTIES (ts1), + OMP_TS_PROPERTIES (ts2)); if (r == 2 || (ret && r && (ret < 0) != (r < 0))) return 2; if (ret == 0) ret = r; - t2 = TREE_CHAIN (t2); - if (t2 == NULL_TREE) + ts2 = TREE_CHAIN (ts2); + if (ts2 == NULL_TREE) { - t1 = TREE_CHAIN (t1); + ts1 = TREE_CHAIN (ts1); break; } } @@ -1872,9 +1872,9 @@ omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) return 2; else ret = 1; - if (t2 != NULL_TREE) + if (ts2 != NULL_TREE) return 2; - if (t1 != NULL_TREE) + if (ts1 != NULL_TREE) { if (ret < 0) return 2; @@ -1884,16 +1884,21 @@ omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) return 0; return swapped ? -ret : ret; } - for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1)) + for (tree ts1 = ctx1; ts1; ts1 = TREE_CHAIN (ts1)) { - tree t2; - for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + tree ts2; + for (ts2 = ctx2; ts2; ts2 = TREE_CHAIN (ts2)) + if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2)) { - const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t1)); + tree score1 = OMP_TS_SCORE (ts1); + tree score2 = OMP_TS_SCORE (ts2); + if (score1 && score2 && !simple_cst_equal (score1, score2)) + return 2; + + const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts1)); int r = omp_context_selector_props_compare (set, sel, - TREE_VALUE (t1), - TREE_VALUE (t2)); + OMP_TS_PROPERTIES (ts1), + OMP_TS_PROPERTIES (ts2)); if (r == 2 || (ret && r && (ret < 0) != (r < 0))) return 2; if (ret == 0) @@ -1901,7 +1906,7 @@ omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) cnt++; break; } - if (t2 == NULL_TREE) + if (ts2 == NULL_TREE) { if (ret == -1) return 2; @@ -1935,15 +1940,17 @@ omp_context_selector_compare (tree ctx1, tree ctx2) std::swap (ctx1, ctx2); std::swap (len1, len2); } - for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1)) + for (tree tss1 = ctx1; tss1; tss1 = TREE_CHAIN (tss1)) { - tree t2; - for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + tree tss2; + for (tss2 = ctx2; tss2; tss2 = TREE_CHAIN (tss2)) + if (OMP_TSS_ID (tss1) == OMP_TSS_ID (tss2)) { - const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1)); - int r = omp_context_selector_set_compare (set, TREE_VALUE (t1), - TREE_VALUE (t2)); + const char *set = IDENTIFIER_POINTER (OMP_TSS_ID (tss1)); + int r + = omp_context_selector_set_compare + (set, OMP_TSS_TRAIT_SELECTORS (tss1), + OMP_TSS_TRAIT_SELECTORS (tss2)); if (r == 2 || (ret && r && (ret < 0) != (r < 0))) return 2; if (ret == 0) @@ -1951,7 +1958,7 @@ omp_context_selector_compare (tree ctx1, tree ctx2) cnt++; break; } - if (t2 == NULL_TREE) + if (tss2 == NULL_TREE) { if (ret == -1) return 2; @@ -1974,14 +1981,14 @@ omp_get_context_selector (tree ctx, const char *set, const char *sel) { tree setid = get_identifier (set); tree selid = sel ? get_identifier (sel) : NULL_TREE; - for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) - if (TREE_PURPOSE (t1) == setid) + for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) + if (OMP_TSS_ID (tss) == setid) { if (sel == NULL) - return TREE_VALUE (t1); - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) - if (TREE_PURPOSE (t2) == selid) - return t2; + return OMP_TSS_TRAIT_SELECTORS (tss); + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) + if (OMP_TS_ID (ts) == selid) + return ts; } return NULL_TREE; } @@ -2004,25 +2011,23 @@ omp_context_compute_score (tree ctx, score_wide_int *score, bool declare_simd) bool has_isa = omp_get_context_selector (ctx, "device", "isa"); bool ret = false; *score = 1; - for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) - if (TREE_VALUE (t1) != construct) - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) - if (tree t3 = TREE_VALUE (t2)) - if (TREE_PURPOSE (t3) - && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3)), " score") == 0 - && TREE_CODE (TREE_VALUE (t3)) == INTEGER_CST) - { - tree t4 = TREE_VALUE (t3); - *score += score_wide_int::from (wi::to_wide (t4), - TYPE_SIGN (TREE_TYPE (t4))); - } + for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) + if (OMP_TSS_TRAIT_SELECTORS (tss) != construct) + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) + { + tree s = OMP_TS_SCORE (ts); + if (s && TREE_CODE (s) == INTEGER_CST) + *score += score_wide_int::from (wi::to_wide (s), + TYPE_SIGN (TREE_TYPE (s))); + } + if (construct || has_kind || has_arch || has_isa) { int scores[12]; enum tree_code constructs[5]; int nconstructs = 0; if (construct) - nconstructs = omp_constructor_traits_to_codes (construct, constructs); + nconstructs = omp_construct_traits_to_codes (construct, constructs); if (omp_construct_selector_matches (constructs, nconstructs, scores) == 2) ret = true; diff --git a/gcc/omp-general.h b/gcc/omp-general.h index 1a52bfdb56b..28a9c0e6e17 100644 --- a/gcc/omp-general.h +++ b/gcc/omp-general.h @@ -92,6 +92,52 @@ struct omp_for_data #define OACC_FN_ATTRIB "oacc function" +/* Accessors for OMP context selectors, used by variant directives. + These are represented internally by a multilevel TREE_LIST structure, but + these accessors should be used to avoid confusion. The grammar is: + + context-set-selector-specification: + trait-set-selector [, trait-set-selector [, ...]] + trait-set-selector: + trait-set-selector-name = { trait-selector [, trait-selector [, ... ]] } + trait-selector: + trait-selector-name [ ( [trait-score: ] + trait-property [, trait-property [, ...]] ) ] + + trait-properties can variously be identifiers, strings, clauses, or + expressions. + + All the lists are chained via TREE_CHAIN. If a score is present, it is + internally tacked on to the properties with a TREE_PURPOSE of + OMP_TS_SCORE_NODE. */ + +#define OMP_TS_SCORE_NODE integer_minus_one_node + +#define OMP_TSS_ID(NODE) \ + TREE_PURPOSE (NODE) +#define OMP_TSS_TRAIT_SELECTORS(NODE) \ + TREE_VALUE (NODE) +#define OMP_TS_ID(NODE) \ + TREE_PURPOSE (NODE) +#define OMP_TS_SCORE(NODE) \ + ((TREE_VALUE (NODE) \ + && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST \ + && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \ + ? TREE_VALUE (TREE_VALUE (NODE)) : NULL_TREE) +#define OMP_TS_PROPERTIES(NODE) \ + ((TREE_VALUE (NODE) \ + && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST \ + && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \ + ? TREE_CHAIN (TREE_VALUE (NODE)) : TREE_VALUE (NODE)) +#define OMP_TP_NAME(NODE) \ + TREE_PURPOSE (NODE) +#define OMP_TP_VALUE(NODE) \ + TREE_VALUE (NODE) + +extern tree make_trait_set_selector (tree, tree, tree); +extern tree make_trait_selector (tree, tree, tree, tree); +extern tree make_trait_property (tree, tree, tree); + extern tree omp_find_clause (tree clauses, enum omp_clause_code kind); extern bool omp_is_allocatable_or_ptr (tree decl); extern tree omp_check_optional_argument (tree decl, bool for_present_check); @@ -106,7 +152,7 @@ extern gimple *omp_build_barrier (tree lhs); extern tree find_combined_omp_for (tree *, int *, void *); extern poly_uint64 omp_max_vf (void); extern int omp_max_simt_vf (void); -extern int omp_constructor_traits_to_codes (tree, enum tree_code *); +extern int omp_construct_traits_to_codes (tree, enum tree_code *); extern tree omp_check_context_selector (location_t loc, tree ctx); extern void omp_mark_declare_variant (location_t loc, tree variant, tree construct); From patchwork Thu Dec 7 15:52:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1873280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SmJhj1gCkz1ySY for ; Fri, 8 Dec 2023 02:53:25 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 47C51385B51F for ; Thu, 7 Dec 2023 15:53:23 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa1.mentor.iphmx.com (esa1.mentor.iphmx.com [68.232.129.153]) by sourceware.org (Postfix) with ESMTPS id 49A53385E01F for ; Thu, 7 Dec 2023 15:53:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 49A53385E01F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 49A53385E01F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.129.153 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964392; cv=none; b=CQlMCldE6NZAmr7XRBp6kJntwgEMeQ9vaU+sji3Tlz891kQV6YlKczZYjjurYUcCl5+1yBjQgt81Ogd8UdEghLXj0dKwjkOuzhpfshPVBl7XXBIVyOAghl5vn2iCtfvqvrPj/GYUENqSPzijWIl9XRU+L4detXVSHYvcNb9aUKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964392; c=relaxed/simple; bh=F56Xm8H/fqyBIQ2XkVkx1qYEP3nU/bgGRuHGP4AZcfw=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=br2RKaIolx9E2zT51AVxIIpV50cl5jvI7xB4GYxG6Q9v5L1mYeMJaWBKo3s9Ccv5hWtynV6mmJWJBe+HvkAFzhVWBkXvs3OkaE6nubjYL/YUFi2p0d12ngT6VMLa/0gxj376J8DGX8D2bXMKvWEkKhfYeIJ8We+Wqx0GkhRpCfo= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: ajZajqR9SzuinXLC0TvilA== X-CSE-MsgGUID: w+K2wjudSbG1K9HuPXqzbw== X-IronPort-AV: E=Sophos;i="6.04,256,1695715200"; d="scan'208";a="27954260" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa1.mentor.iphmx.com with ESMTP; 07 Dec 2023 07:53:09 -0800 IronPort-SDR: PFj9t3WRGYUuB/EXy625cdbQXhKUvL+svaXzuG5GJL1YsIlPF/7+/2peagNDYDUTXmXleX7eMO xfTbf7oLQCi9ine4a8loAFvlcXucTiUbRqJzZptvOSugSQ7uSSUT0VFFfL42dOjURRt8wev8Dp h0EeUslI9Oef1PhJNKa1RP43pNIbN1FS+IN2oGLB+gC3bQgrFiByKzbe/5egSEruhx+sU7N327 jSopNwufbQOtImNHv25dxfJsH20kgOSaFy4iR9fWV4lE3Fy9PT4tjWg7Ymyv0kB0LLRjGN6Npu b+8= From: Sandra Loosemore To: CC: , , Subject: [PATCH V3 2/4] OpenMP: Unify representation of name-list properties. Date: Thu, 7 Dec 2023 08:52:45 -0700 Message-ID: <20231207155247.372718-3-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207155247.372718-1-sandra@codesourcery.com> References: <20231207155247.372718-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: svr-orw-mbx-14.mgc.mentorg.com (147.34.90.214) To svr-orw-mbx-13.mgc.mentorg.com (147.34.90.213) X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Previously, name-list properties specified as identifiers were stored in the TREE_PURPOSE/OMP_TP_NAME slot, while those specified as strings were stored in the TREE_VALUE/OMP_TP_VALUE slot. This patch puts both representations in OMP_TP_VALUE with a magic cookie in OMP_TP_NAME. gcc/ChangeLog * omp-general.h (OMP_TP_NAMELIST_NODE): New. * omp-general.cc (omp_context_name_list_prop): Move earlier in the file, and adjust for new representation. (omp_check_context_selector): Adjust this too. (omp_context_selector_props_compare): Likewise. gcc/c/ChangeLog * c-parser.cc (c_parser_omp_context_selector): Adjust for new namelist property representation. gcc/cp/ChangeLog * parser.cc (cp_parser_omp_context_selector): Adjust for new namelist property representation. * pt.cc (tsubst_attribute): Likewise. gcc/fortran/ChangeLog * trans-openmp.cc (gfc_trans_omp_declare_varaint): Adjust for new namelist property representation. --- gcc/c/c-parser.cc | 5 ++- gcc/cp/parser.cc | 5 ++- gcc/cp/pt.cc | 4 +- gcc/fortran/trans-openmp.cc | 5 ++- gcc/omp-general.cc | 84 +++++++++++++++++++++---------------- gcc/omp-general.h | 1 + 6 files changed, 61 insertions(+), 43 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 9a17a8c5760..7fe449dc54a 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24538,11 +24538,12 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) case CTX_PROPERTY_NAME_LIST: do { - tree prop = NULL_TREE, value = NULL_TREE; + tree prop = OMP_TP_NAMELIST_NODE; + tree value = NULL_TREE; if (c_parser_next_token_is (parser, CPP_KEYWORD) || c_parser_next_token_is (parser, CPP_NAME)) { - prop = c_parser_peek_token (parser)->value; + value = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); } else if (c_parser_next_token_is (parser, CPP_STRING)) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9d4ae9726e5..eb1b0f26003 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47539,11 +47539,12 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) case CTX_PROPERTY_NAME_LIST: do { - tree prop = NULL_TREE, value = NULL_TREE; + tree prop = OMP_TP_NAMELIST_NODE; + tree value = NULL_TREE; if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD) || cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { - prop = cp_lexer_peek_token (parser->lexer)->u.value; + value = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); } else if (cp_lexer_next_token_is (parser->lexer, CPP_STRING)) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2541ad95cc1..ca4975dcd6f 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11869,7 +11869,9 @@ tsubst_attribute (tree t, tree *decl_p, tree args, } properties = copy_list (OMP_TS_PROPERTIES (ts)); for (tree p = properties; p; p = TREE_CHAIN (p)) - if (OMP_TP_VALUE (p)) + if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) + continue; + else if (OMP_TP_VALUE (p)) { bool allow_string = (OMP_TS_ID (ts) != condition || set[0] != 'u'); diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index fe8044a57cd..60154ff3751 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -8235,9 +8235,10 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) break; case CTX_PROPERTY_NAME_LIST: { - tree prop = NULL_TREE, value = NULL_TREE; + tree prop = OMP_TP_NAMELIST_NODE; + tree value = NULL_TREE; if (otp->is_name) - prop = get_identifier (otp->name); + value = get_identifier (otp->name); else value = gfc_conv_constant_to_tree (otp->expr); diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index 75980fcf4da..156508eabb5 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1114,6 +1114,30 @@ omp_maybe_offloaded (void) return false; } +/* Return a name from PROP, a property in selectors accepting + name lists. */ + +static const char * +omp_context_name_list_prop (tree prop) +{ + gcc_assert (OMP_TP_NAME (prop) == OMP_TP_NAMELIST_NODE); + tree val = OMP_TP_VALUE (prop); + switch (TREE_CODE (val)) + { + case IDENTIFIER_NODE: + return IDENTIFIER_POINTER (val); + case STRING_CST: + { + const char *ret = TREE_STRING_POINTER (val); + if ((size_t) TREE_STRING_LENGTH (val) + == strlen (ret) + (lang_GNU_Fortran () ? 0 : 1)) + return ret; + return NULL; + } + default: + return NULL; + } +} /* Diagnose errors in an OpenMP context selector, return CTX if it is correct or error_mark_node otherwise. */ @@ -1198,23 +1222,29 @@ omp_check_context_selector (location_t loc, tree ctx) "atomic_default_mem_order"); return error_mark_node; } + else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE + && (TREE_CODE (OMP_TP_VALUE (p)) == STRING_CST)) + warning_at (loc, 0, + "unknown property %qE of %qs selector", + OMP_TP_VALUE (p), + props[i].selector); + else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) + warning_at (loc, 0, + "unknown property %qs of %qs selector", + omp_context_name_list_prop (p), + props[i].selector); else if (OMP_TP_NAME (p)) warning_at (loc, OPT_Wopenmp, "unknown property %qs of %qs selector", IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].selector); - else - warning_at (loc, OPT_Wopenmp, - "unknown property %qE of %qs selector", - OMP_TP_VALUE (p), props[i].selector); break; } - else if (OMP_TP_NAME (p) == NULL_TREE) + else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) + /* Property-list traits. */ { - const char *str = TREE_STRING_POINTER (OMP_TP_VALUE (p)); - if (!strcmp (str, props[i].props[j]) - && ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (p)) - == strlen (str) + (lang_GNU_Fortran () ? 0 : 1))) + const char *str = omp_context_name_list_prop (p); + if (str && !strcmp (str, props[i].props[j])) break; } else if (!strcmp (IDENTIFIER_POINTER (OMP_TP_NAME (p)), @@ -1277,24 +1307,6 @@ make_trait_property (tree name, tree value, tree chain) return tree_cons (name, value, chain); } -/* Return a name from PROP, a property in selectors accepting - name lists. */ - -static const char * -omp_context_name_list_prop (tree prop) -{ - if (OMP_TP_NAME (prop)) - return IDENTIFIER_POINTER (OMP_TP_NAME (prop)); - else - { - const char *ret = TREE_STRING_POINTER (OMP_TP_VALUE (prop)); - if ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (prop)) - == strlen (ret) + (lang_GNU_Fortran () ? 0 : 1)) - return ret; - return NULL; - } -} - /* Return 1 if context selector matches the current OpenMP context, 0 if it does not and -1 if it is unknown and need to be determined later. Some properties can be checked right away during parsing (this routine), @@ -1793,18 +1805,18 @@ omp_context_selector_props_compare (const char *set, const char *sel, if (simple_cst_equal (OMP_TP_VALUE (p1), OMP_TP_VALUE (p2))) break; } + else if (OMP_TP_NAME (p1) == OMP_TP_NAMELIST_NODE) + { + /* Handle string constant vs identifier comparison for + name-list properties. */ + const char *n1 = omp_context_name_list_prop (p1); + const char *n2 = omp_context_name_list_prop (p2); + if (n1 && n2 && !strcmp (n1, n2)) + break; + } else break; } - else - { - /* Handle string constant vs identifier comparison for - name-list properties. */ - const char *n1 = omp_context_name_list_prop (p1); - const char *n2 = omp_context_name_list_prop (p2); - if (n1 && n2 && !strcmp (n1, n2)) - break; - } if (p2 == NULL_TREE) { int r = pass ? -1 : 1; diff --git a/gcc/omp-general.h b/gcc/omp-general.h index 28a9c0e6e17..dc5e5f6ba1f 100644 --- a/gcc/omp-general.h +++ b/gcc/omp-general.h @@ -112,6 +112,7 @@ struct omp_for_data OMP_TS_SCORE_NODE. */ #define OMP_TS_SCORE_NODE integer_minus_one_node +#define OMP_TP_NAMELIST_NODE integer_one_node #define OMP_TSS_ID(NODE) \ TREE_PURPOSE (NODE) From patchwork Thu Dec 7 15:52:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1873283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SmJkX4rVyz1ySY for ; Fri, 8 Dec 2023 02:55:00 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9FAB7385F028 for ; Thu, 7 Dec 2023 15:54:58 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) by sourceware.org (Postfix) with ESMTPS id BDA0C3861010 for ; Thu, 7 Dec 2023 15:53:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BDA0C3861010 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BDA0C3861010 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.137.180 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964433; cv=none; b=taRVsWX6zKG3YeJGzhnHuYrzCZ6eJzebpFVE0zvBdt1jTT6s25x0ZTqARc1Qxy5KQciUOJjb4Xr1oTkZhw2IJmEbOBm4z3GWqgVZ87FzSem/aE/LPayXKWGa60svLKK/8mDIX1bQ6ZEr8x7MCuVSQ/hdqv1loMpg/nqSQd86NDo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964433; c=relaxed/simple; bh=tqzJL07mf9sR202A27t7SxqQbHFJ5hvYU9WjF5BiwxE=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=kewQGMk/QUA4Fw7bYOe3A/mEHBZAgOwM7Ff4uSNK8RTi8RmBJEQ/xcFzQOK58ss2kwV4OHSWzon7uyaJn+gy6hfuQXgZaPjhIdZZcJFLiS1dEPZdu1Zo/bxfwTIG2UnbHBEcShWXd4j2wh/MfEwC8+11V91rV2DZ4NNvhbHayv4= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: YUWxDdx7QcOciOeh9n+6Xw== X-CSE-MsgGUID: vKmx+227QXKNvs1qgZuF5g== X-IronPort-AV: E=Sophos;i="6.04,256,1695715200"; d="scan'208";a="24734409" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 07 Dec 2023 07:53:44 -0800 IronPort-SDR: TsvORx9VyFTnGWLDRD6Qt8DdGaBZVSjZBq1aPte0EOoEqADaMttHW5Pekhpcg6VfXlBJ3YPof3 w/W0S7NeucaqrrJIkrfXLxHuu1dLcz2771QMTzutctZnGZagPMdAzh5Gf0KunprV8SW7P9KdDd 71CW22FQdCwODr82iAo0nUT8C7b+sOnvowme64xalIONX6UWlt7TBtFiGSEDWd4XFGM3hLt+4B H/4EaiEgC8Gu23GLY6DXIHe1ZhK46EhWYUfKfext3ar1jtMsEK/Qe6RL2TMEy9JU/PbC6Ybzts aYU= From: Sandra Loosemore To: CC: , , Subject: [PATCH V3 3/4] OpenMP: Use enumerators for names of trait-sets and traits Date: Thu, 7 Dec 2023 08:52:46 -0700 Message-ID: <20231207155247.372718-4-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207155247.372718-1-sandra@codesourcery.com> References: <20231207155247.372718-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: svr-orw-mbx-11.mgc.mentorg.com (147.34.90.211) To svr-orw-mbx-13.mgc.mentorg.com (147.34.90.213) X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org This patch introduces enumerators to represent trait-set names and trait names, which makes it easier to use tables to control other behavior and for switch statements to dispatch on the tags. The tags are stored in the same place in the TREE_LIST structure (OMP_TSS_ID or OMP_TS_ID) and are encoded there as integer constants. gcc/ChangeLog * omp-selectors.h: New file. * omp-general.h: Include omp-selectors.h. (OMP_TSS_CODE, OMP_TSS_NAME): New. (OMP_TS_CODE, OMP_TS_NAME): New. (make_trait_set_selector, make_trait_selector): Adjust declarations. (omp_construct_traits_to_codes): Likewise. (omp_context_selector_set_compare): Likewise. (omp_get_context_selector): Likewise. (omp_get_context_selector_list): New. * omp-general.cc (omp_construct_traits_to_codes): Pass length in as argument instead of returning it. Make it table-driven. (omp_tss_map): New. (kind_properties, vendor_properties, extension_properties): New. (atomic_default_mem_order_properties): New. (omp_ts_map): New. (omp_check_context_selector): Simplify lookup and dispatch logic. (omp_mark_declare_variant): Ignore variants with unknown construct selectors. Adjust for new representation. (make_trait_set_selector, make_trait_selector): Adjust for new representations. (omp_context_selector_matches): Simplify dispatch logic. Avoid fixed-sized buffers and adjust call to omp_construct_traits_to_codes. (omp_context_selector_props_compare): Adjust for new representations and simplify dispatch logic. (omp_context_selector_set_compare): Likewise. (omp_context_selector_compare): Likewise. (omp_get_context_selector): Adjust for new representations, and split out... (omp_get_context_selector_list): New function. (omp_lookup_tss_code): New. (omp_lookup_ts_code): New. (omp_context_compute_score): Adjust for new representations. Avoid fixed-sized buffers and magic numbers. Adjust call to omp_construct_traits_to_codes. * gimplify.cc (omp_construct_selector_matches): Avoid use of fixed-size buffer. Adjust call to omp_construct_traits_to_codes. gcc/c/ChangeLog * c-parser.cc (omp_construct_selectors): Delete. (omp_device_selectors): Delete. (omp_implementation_selectors): Delete. (omp_user_selectors): Delete. (c_parser_omp_context_selector): Adjust for new representations and simplify dispatch logic. Uniformly warn instead of sometimes error when an unknown selector is found. (c_parser_omp_context_selector_specification): Likewise. (c_finish_omp_declare_variant): Adjust for new representations. gcc/cp/ChangeLog * decl.cc (omp_declare_variant_finalize_one): Adjust for new representations. * parser.cc (omp_construct_selectors): Delete. (omp_device_selectors): Delete. (omp_implementation_selectors): Delete. (omp_user_selectors): Delete. (cp_parser_omp_context_selector): Adjust for new representations and simplify dispatch logic. Uniformly warn instead of sometimes error when an unknown selector is found. (cp_parser_omp_context_selector_specification): Likewise. * pt.cc (tsubst_attribute): Adjust for new representations. gcc/fortran/ChangeLog * gfortran.h: Include omp-selectors.h. (enum gfc_omp_trait_property_kind): Delete, and replace all references with equivalent omp_tp_type enumerators. (struct gfc_omp_trait_property): Update for omp_tp_type. (struct gfc_omp_selector): Replace string name with new enumerator. (struct gfc_omp_set_selector): Likewise. * openmp.cc (gfc_free_omp_trait_property_list): Update for omp_tp_type. (omp_construct_selectors): Delete. (omp_device_selectors): Delete. (omp_implementation_selectors): Delete. (omp_user_selectors): Delete. (gfc_ignore_trait_property_extension): New. (gfc_ignore_trait_property_extension_list): New. (gfc_match_omp_selector): Adjust for new representations and simplify dispatch logic. Uniformly warn instead of sometimes error when an unknown selector is found. (gfc_match_omp_context_selector): Adjust for new representations. (gfc_match_omp_context_selector_specification): Likewise. * trans-openmp.cc (gfc_trans_omp_declare_variant): Adjust for new representations. gcc/testsuite/ * c-c++-common/gomp/declare-variant-1.c: Expect warning on unknown selectors. * c-c++-common/gomp/declare-variant-2.c: Likewise. * gfortran.dg/gomp/declare-variant-1.f90: Likewise. * gfortran.dg/gomp/declare-variant-2.f90: Likewise. --- gcc/c/c-parser.cc | 185 ++---- gcc/cp/decl.cc | 8 +- gcc/cp/parser.cc | 182 ++---- gcc/cp/pt.cc | 15 +- gcc/fortran/gfortran.h | 20 +- gcc/fortran/openmp.cc | 189 +++--- gcc/fortran/trans-openmp.cc | 42 +- gcc/gimplify.cc | 17 +- gcc/omp-general.cc | 561 ++++++++++++------ gcc/omp-general.h | 23 +- gcc/omp-selectors.h | 93 +++ .../c-c++-common/gomp/declare-variant-1.c | 1 + .../c-c++-common/gomp/declare-variant-2.c | 40 +- .../gfortran.dg/gomp/declare-variant-1.f90 | 1 + .../gfortran.dg/gomp/declare-variant-2.f90 | 34 +- 15 files changed, 755 insertions(+), 656 deletions(-) create mode 100644 gcc/omp-selectors.h diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 7fe449dc54a..9059a9747db 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24337,16 +24337,6 @@ c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context) } } -static const char *const omp_construct_selectors[] = { - "simd", "target", "teams", "parallel", "for", NULL }; -static const char *const omp_device_selectors[] = { - "kind", "isa", "arch", NULL }; -static const char *const omp_implementation_selectors[] = { - "vendor", "extension", "atomic_default_mem_order", "unified_address", - "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL }; -static const char *const omp_user_selectors[] = { - "condition", NULL }; - /* OpenMP 5.0: trait-selector: @@ -24359,7 +24349,8 @@ static const char *const omp_user_selectors[] = { trait-selector-set SET. */ static tree -c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) +c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set, + tree parms) { tree ret = NULL_TREE; do @@ -24373,80 +24364,41 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) c_parser_error (parser, "expected trait selector name"); return error_mark_node; } + enum omp_ts_code sel + = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector)); - tree properties = NULL_TREE; - tree scoreval = NULL_TREE; - const char *const *selectors = NULL; - bool allow_score = true; - bool allow_user = false; - int property_limit = 0; - enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST, - CTX_PROPERTY_ID, CTX_PROPERTY_EXPR, - CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE; - switch (IDENTIFIER_POINTER (set)[0]) - { - case 'c': /* construct */ - selectors = omp_construct_selectors; - allow_score = false; - property_limit = 1; - property_kind = CTX_PROPERTY_SIMD; - break; - case 'd': /* device */ - selectors = omp_device_selectors; - allow_score = false; - allow_user = true; - property_limit = 3; - property_kind = CTX_PROPERTY_NAME_LIST; - break; - case 'i': /* implementation */ - selectors = omp_implementation_selectors; - allow_user = true; - property_limit = 3; - property_kind = CTX_PROPERTY_NAME_LIST; - break; - case 'u': /* user */ - selectors = omp_user_selectors; - property_limit = 1; - property_kind = CTX_PROPERTY_EXPR; - break; - default: - gcc_unreachable (); - } - for (int i = 0; ; i++) + if (sel == OMP_TRAIT_INVALID) { - if (selectors[i] == NULL) + /* Per the spec, "Implementations can ignore specified selectors + that are not those described in this section"; however, we + must record such selectors because they cause match failures. */ + warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp, + "unknown selector %qs for context selector set %qs", + IDENTIFIER_POINTER (selector), omp_tss_map[set]); + c_parser_consume_token (parser); + ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret); + if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) + c_parser_balanced_token_sequence (parser); + if (c_parser_next_token_is (parser, CPP_COMMA)) { - if (allow_user) - { - property_kind = CTX_PROPERTY_USER; - break; - } - else - { - error_at (c_parser_peek_token (parser)->location, - "selector %qs not allowed for context selector " - "set %qs", IDENTIFIER_POINTER (selector), - IDENTIFIER_POINTER (set)); - c_parser_consume_token (parser); - return error_mark_node; - } + c_parser_consume_token (parser); + continue; } - if (i == property_limit) - property_kind = CTX_PROPERTY_NONE; - if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0) + else break; } - if (property_kind == CTX_PROPERTY_NAME_LIST - && IDENTIFIER_POINTER (set)[0] == 'i' - && strcmp (IDENTIFIER_POINTER (selector), - "atomic_default_mem_order") == 0) - property_kind = CTX_PROPERTY_ID; c_parser_consume_token (parser); + tree properties = NULL_TREE; + tree scoreval = NULL_TREE; + enum omp_tp_type property_kind = omp_ts_map[sel].tp_type; + bool allow_score = omp_ts_map[sel].allow_score; + tree t; + if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) { - if (property_kind == CTX_PROPERTY_NONE) + if (property_kind == OMP_TRAIT_PROPERTY_NONE) { error_at (c_parser_peek_token (parser)->location, "selector %qs does not accept any properties", @@ -24489,38 +24441,7 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) switch (property_kind) { - tree t; - case CTX_PROPERTY_USER: - do - { - t = c_parser_expr_no_commas (parser, NULL).value; - if (TREE_CODE (t) == STRING_CST) - properties = make_trait_property (NULL_TREE, t, - properties); - else if (t != error_mark_node) - { - mark_exp_read (t); - t = c_fully_fold (t, false, NULL); - if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - || !tree_fits_shwi_p (t)) - error_at (token->location, "property must be " - "constant integer expression or string " - "literal"); - else - properties = make_trait_property (NULL_TREE, t, - properties); - } - else - return error_mark_node; - - if (c_parser_next_token_is (parser, CPP_COMMA)) - c_parser_consume_token (parser); - else - break; - } - while (1); - break; - case CTX_PROPERTY_ID: + case OMP_TRAIT_PROPERTY_ID: if (c_parser_next_token_is (parser, CPP_KEYWORD) || c_parser_next_token_is (parser, CPP_NAME)) { @@ -24535,7 +24456,7 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) return error_mark_node; } break; - case CTX_PROPERTY_NAME_LIST: + case OMP_TRAIT_PROPERTY_NAME_LIST: do { tree prop = OMP_TP_NAMELIST_NODE; @@ -24565,12 +24486,14 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) } while (1); break; - case CTX_PROPERTY_EXPR: + case OMP_TRAIT_PROPERTY_EXPR: t = c_parser_expr_no_commas (parser, NULL).value; if (t != error_mark_node) { mark_exp_read (t); t = c_fully_fold (t, false, NULL); + /* FIXME: this is bogus, both device_num and + condition selectors allow arbitrary expressions. */ if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) || !tree_fits_shwi_p (t)) error_at (token->location, "property must be " @@ -24582,7 +24505,9 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) else return error_mark_node; break; - case CTX_PROPERTY_SIMD: + case OMP_TRAIT_PROPERTY_CLAUSE_LIST: + gcc_assert (sel == OMP_TRAIT_CONSTRUCT_SIMD); + if (parms == NULL_TREE) { error_at (token->location, "properties for % " @@ -24607,15 +24532,15 @@ c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) parens.skip_until_found_close (parser); properties = nreverse (properties); } - else if (property_kind == CTX_PROPERTY_NAME_LIST - || property_kind == CTX_PROPERTY_ID - || property_kind == CTX_PROPERTY_EXPR) + else if (property_kind != OMP_TRAIT_PROPERTY_NONE + && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST + && property_kind != OMP_TRAIT_PROPERTY_EXTENSION) { c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"); return error_mark_node; } - ret = make_trait_selector (selector, scoreval, properties, ret); + ret = make_trait_selector (sel, scoreval, properties, ret); if (c_parser_next_token_is (parser, CPP_COMMA)) c_parser_consume_token (parser); @@ -24649,35 +24574,17 @@ c_parser_omp_context_selector_specification (c_parser *parser, tree parms) const char *setp = ""; if (c_parser_next_token_is (parser, CPP_NAME)) setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - switch (setp[0]) - { - case 'c': - if (strcmp (setp, "construct") == 0) - setp = NULL; - break; - case 'd': - if (strcmp (setp, "device") == 0) - setp = NULL; - break; - case 'i': - if (strcmp (setp, "implementation") == 0) - setp = NULL; - break; - case 'u': - if (strcmp (setp, "user") == 0) - setp = NULL; - break; - default: - break; - } - if (setp) + enum omp_tss_code set = omp_lookup_tss_code (setp); + + if (set == OMP_TRAIT_SET_INVALID) { + /* FIXME: hardwired list of names here is incomplete and + liable to bit-rot. */ c_parser_error (parser, "expected %, %, " "% or %"); return error_mark_node; } - tree set = c_parser_peek_token (parser)->value; c_parser_consume_token (parser); if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) @@ -24774,7 +24681,8 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms) error_at (token->location, "variant %qD is not a function", variant); variant = error_mark_node; } - else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE + else if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT, + OMP_TRAIT_CONSTRUCT_SIMD) && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant))) { error_at (token->location, "variant %qD and base %qD have " @@ -24795,7 +24703,8 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms) if (variant != error_mark_node) { C_DECL_USED (variant) = 1; - tree construct = omp_get_context_selector (ctx, "construct", NULL); + tree construct + = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT); omp_mark_declare_variant (match_loc, variant, construct); if (omp_context_selector_matches (ctx)) { diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 4b685270097..1844c923b7f 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8097,12 +8097,13 @@ omp_declare_variant_finalize_one (tree decl, tree attr) } tree ctx = TREE_VALUE (TREE_VALUE (attr)); - tree simd = omp_get_context_selector (ctx, "construct", "simd"); + tree simd = omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT, + OMP_TRAIT_CONSTRUCT_SIMD); if (simd) { TREE_VALUE (simd) = c_omp_declare_simd_clauses_to_numbers (DECL_ARGUMENTS (decl), - TREE_VALUE (simd)); + OMP_TS_PROPERTIES (simd)); /* FIXME, adjusting simd args unimplemented. */ return true; } @@ -8195,7 +8196,8 @@ omp_declare_variant_finalize_one (tree decl, tree attr) } else { - tree construct = omp_get_context_selector (ctx, "construct", NULL); + tree construct + = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT); omp_mark_declare_variant (match_loc, variant, construct); if (!omp_context_selector_matches (ctx)) return true; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index eb1b0f26003..6cde6159cf1 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47325,16 +47325,6 @@ cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok, } } -static const char *const omp_construct_selectors[] = { - "simd", "target", "teams", "parallel", "for", NULL }; -static const char *const omp_device_selectors[] = { - "kind", "isa", "arch", NULL }; -static const char *const omp_implementation_selectors[] = { - "vendor", "extension", "atomic_default_mem_order", "unified_address", - "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL }; -static const char *const omp_user_selectors[] = { - "condition", NULL }; - /* OpenMP 5.0: trait-selector: @@ -47347,7 +47337,8 @@ static const char *const omp_user_selectors[] = { trait-selector-set SET. */ static tree -cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) +cp_parser_omp_context_selector (cp_parser *parser, enum omp_tss_code set, + bool has_parms_p) { tree ret = NULL_TREE; do @@ -47362,78 +47353,44 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) return error_mark_node; } - tree properties = NULL_TREE; - tree scoreval = NULL_TREE; - const char *const *selectors = NULL; - bool allow_score = true; - bool allow_user = false; - int property_limit = 0; - enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST, - CTX_PROPERTY_ID, CTX_PROPERTY_EXPR, - CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE; - switch (IDENTIFIER_POINTER (set)[0]) - { - case 'c': /* construct */ - selectors = omp_construct_selectors; - allow_score = false; - property_limit = 1; - property_kind = CTX_PROPERTY_SIMD; - break; - case 'd': /* device */ - selectors = omp_device_selectors; - allow_score = false; - allow_user = true; - property_limit = 3; - property_kind = CTX_PROPERTY_NAME_LIST; - break; - case 'i': /* implementation */ - selectors = omp_implementation_selectors; - allow_user = true; - property_limit = 3; - property_kind = CTX_PROPERTY_NAME_LIST; - break; - case 'u': /* user */ - selectors = omp_user_selectors; - property_limit = 1; - property_kind = CTX_PROPERTY_EXPR; - break; - default: - gcc_unreachable (); - } - for (int i = 0; ; i++) + enum omp_ts_code sel + = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector)); + + if (sel == OMP_TRAIT_INVALID) { - if (selectors[i] == NULL) + /* Per the spec, "Implementations can ignore specified selectors + that are not those described in this section"; however, we + must record such selectors because they cause match failures. */ + warning_at (cp_lexer_peek_token (parser->lexer)->location, + OPT_Wopenmp, + "unknown selector %qs for context selector set %qs", + IDENTIFIER_POINTER (selector), omp_tss_map[set]); + cp_lexer_consume_token (parser->lexer); + ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret); + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; + n; --n) + cp_lexer_consume_token (parser->lexer); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) { - if (allow_user) - { - property_kind = CTX_PROPERTY_USER; - break; - } - else - { - error ("selector %qs not allowed for context selector " - "set %qs", IDENTIFIER_POINTER (selector), - IDENTIFIER_POINTER (set)); - cp_lexer_consume_token (parser->lexer); - return error_mark_node; - } + cp_lexer_consume_token (parser->lexer); + continue; } - if (i == property_limit) - property_kind = CTX_PROPERTY_NONE; - if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0) + else break; } - if (property_kind == CTX_PROPERTY_NAME_LIST - && IDENTIFIER_POINTER (set)[0] == 'i' - && strcmp (IDENTIFIER_POINTER (selector), - "atomic_default_mem_order") == 0) - property_kind = CTX_PROPERTY_ID; cp_lexer_consume_token (parser->lexer); + tree properties = NULL_TREE; + tree scoreval = NULL_TREE; + enum omp_tp_type property_kind = omp_ts_map[sel].tp_type; + bool allow_score = omp_ts_map[sel].allow_score; + tree t; + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { - if (property_kind == CTX_PROPERTY_NONE) + if (property_kind == OMP_TRAIT_PROPERTY_NONE) { error ("selector %qs does not accept any properties", IDENTIFIER_POINTER (selector)); @@ -47490,38 +47447,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) switch (property_kind) { - tree t; - case CTX_PROPERTY_USER: - do - { - t = cp_parser_constant_expression (parser); - if (t != error_mark_node) - { - t = fold_non_dependent_expr (t); - if (TREE_CODE (t) == STRING_CST) - properties = make_trait_property (NULL_TREE, t, - properties); - else if (!value_dependent_expression_p (t) - && (!INTEGRAL_TYPE_P (TREE_TYPE (t)) - || !tree_fits_shwi_p (t))) - error_at (token->location, "property must be " - "constant integer expression or string " - "literal"); - else - properties = make_trait_property (NULL_TREE, t, - properties); - } - else - return error_mark_node; - - if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) - cp_lexer_consume_token (parser->lexer); - else - break; - } - while (1); - break; - case CTX_PROPERTY_ID: + case OMP_TRAIT_PROPERTY_ID: if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD) || cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { @@ -47536,7 +47462,7 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) return error_mark_node; } break; - case CTX_PROPERTY_NAME_LIST: + case OMP_TRAIT_PROPERTY_NAME_LIST: do { tree prop = OMP_TP_NAMELIST_NODE; @@ -47567,7 +47493,9 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) } while (1); break; - case CTX_PROPERTY_EXPR: + case OMP_TRAIT_PROPERTY_EXPR: + /* FIXME: this is bogus, the expression need + not be constant. */ t = cp_parser_constant_expression (parser); if (t != error_mark_node) { @@ -47584,7 +47512,9 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) else return error_mark_node; break; - case CTX_PROPERTY_SIMD: + case OMP_TRAIT_PROPERTY_CLAUSE_LIST: + gcc_assert (sel == OMP_TRAIT_CONSTRUCT_SIMD); + if (!has_parms_p) { error_at (token->location, "properties for % " @@ -47606,15 +47536,15 @@ cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p) properties = nreverse (properties); } - else if (property_kind == CTX_PROPERTY_NAME_LIST - || property_kind == CTX_PROPERTY_ID - || property_kind == CTX_PROPERTY_EXPR) + else if (property_kind != OMP_TRAIT_PROPERTY_NONE + && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST + && property_kind != OMP_TRAIT_PROPERTY_EXTENSION) { cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); return error_mark_node; } - ret = make_trait_selector (selector, scoreval, properties, ret); + ret = make_trait_selector (sel, scoreval, properties, ret); if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) cp_lexer_consume_token (parser->lexer); @@ -47650,35 +47580,17 @@ cp_parser_omp_context_selector_specification (cp_parser *parser, if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) setp = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value); - switch (setp[0]) - { - case 'c': - if (strcmp (setp, "construct") == 0) - setp = NULL; - break; - case 'd': - if (strcmp (setp, "device") == 0) - setp = NULL; - break; - case 'i': - if (strcmp (setp, "implementation") == 0) - setp = NULL; - break; - case 'u': - if (strcmp (setp, "user") == 0) - setp = NULL; - break; - default: - break; - } - if (setp) + enum omp_tss_code set = omp_lookup_tss_code (setp); + + if (set == OMP_TRAIT_SET_INVALID) { + /* FIXME: hardwired list of names here is incomplete and + liable to bit-rot. */ cp_parser_error (parser, "expected %, %, " "% or %"); return error_mark_node; } - tree set = cp_lexer_peek_token (parser->lexer)->u.value; cp_lexer_consume_token (parser->lexer); if (!cp_parser_require (parser, CPP_EQ, RT_EQ)) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index ca4975dcd6f..42d020b105d 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11818,18 +11818,20 @@ tsubst_attribute (tree t, tree *decl_p, tree args, tree chain = TREE_CHAIN (val); location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain)); tree ctx = copy_list (TREE_VALUE (val)); - tree simd = get_identifier ("simd"); - tree condition = get_identifier ("condition"); for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) { - const char *set = IDENTIFIER_POINTER (OMP_TSS_ID (tss)); + enum omp_tss_code set = OMP_TSS_CODE (tss); tree selectors = NULL_TREE; for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) { tree properties = NULL_TREE; tree scoreval = NULL_TREE; - if (OMP_TS_ID (ts) == simd && set[0] == 'c') + /* FIXME: The body of this loop should really be dispatching + according to omp_ts_map[OMP_TS_CODE (TS)].tp_type instead + of having hard-wired knowledge of specific selectors. */ + if (OMP_TS_CODE (ts) == OMP_TRAIT_CONSTRUCT_SIMD + && set == OMP_TRAIT_SET_CONSTRUCT) { tree clauses = OMP_TS_PROPERTIES (ts); clauses = tsubst_omp_clauses (clauses, @@ -11874,7 +11876,8 @@ tsubst_attribute (tree t, tree *decl_p, tree args, else if (OMP_TP_VALUE (p)) { bool allow_string - = (OMP_TS_ID (ts) != condition || set[0] != 'u'); + = (OMP_TS_CODE (ts) != OMP_TRAIT_USER_CONDITION + || set != OMP_TRAIT_SET_USER); tree v = OMP_TP_VALUE (p); if (TREE_CODE (v) == STRING_CST && allow_string) continue; @@ -11898,7 +11901,7 @@ tsubst_attribute (tree t, tree *decl_p, tree args, OMP_TP_VALUE (p) = v; } } - selectors = make_trait_selector (OMP_TS_ID (ts), scoreval, + selectors = make_trait_selector (OMP_TS_CODE (ts), scoreval, properties, selectors); } OMP_TSS_TRAIT_SELECTORS (tss) = nreverse (selectors); diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index a77441f38e7..df423f3b4ba 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1641,21 +1641,13 @@ typedef struct gfc_omp_declare_simd gfc_omp_declare_simd; #define gfc_get_omp_declare_simd() XCNEW (gfc_omp_declare_simd) - -enum gfc_omp_trait_property_kind -{ - CTX_PROPERTY_NONE, - CTX_PROPERTY_USER, - CTX_PROPERTY_NAME_LIST, - CTX_PROPERTY_ID, - CTX_PROPERTY_EXPR, - CTX_PROPERTY_SIMD -}; +/* For OpenMP trait selector enum types and tables. */ +#include "omp-selectors.h" typedef struct gfc_omp_trait_property { struct gfc_omp_trait_property *next; - enum gfc_omp_trait_property_kind property_kind; + enum omp_tp_type property_kind; bool is_name : 1; union @@ -1671,8 +1663,7 @@ typedef struct gfc_omp_trait_property typedef struct gfc_omp_selector { struct gfc_omp_selector *next; - - char *trait_selector_name; + enum omp_ts_code code; gfc_expr *score; struct gfc_omp_trait_property *properties; } gfc_omp_selector; @@ -1681,8 +1672,7 @@ typedef struct gfc_omp_selector typedef struct gfc_omp_set_selector { struct gfc_omp_set_selector *next; - - const char *trait_set_selector_name; + enum omp_tss_code code; struct gfc_omp_selector *trait_selectors; } gfc_omp_set_selector; #define gfc_get_omp_set_selector() XCNEW (gfc_omp_set_selector) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 794df19a4d1..1cf04722d00 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -269,14 +269,14 @@ gfc_free_omp_trait_property_list (gfc_omp_trait_property *list) list = list->next; switch (current->property_kind) { - case CTX_PROPERTY_ID: + case OMP_TRAIT_PROPERTY_ID: free (current->name); break; - case CTX_PROPERTY_NAME_LIST: + case OMP_TRAIT_PROPERTY_NAME_LIST: if (current->is_name) free (current->name); break; - case CTX_PROPERTY_SIMD: + case OMP_TRAIT_PROPERTY_CLAUSE_LIST: gfc_free_omp_clauses (current->clauses); break; default: @@ -5584,17 +5584,55 @@ cleanup: return MATCH_ERROR; } +/* Skip over and ignore trait-property-extensions. -static const char *const omp_construct_selectors[] = { - "simd", "target", "teams", "parallel", "do", NULL }; -static const char *const omp_device_selectors[] = { - "kind", "isa", "arch", NULL }; -static const char *const omp_implementation_selectors[] = { - "vendor", "extension", "atomic_default_mem_order", "unified_address", - "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL }; -static const char *const omp_user_selectors[] = { - "condition", NULL }; + trait-property-extension : + trait-property-name + identifier (trait-property-extension[, trait-property-extension[, ...]]) + constant integer expression + */ +static match gfc_ignore_trait_property_extension_list (void); + +static match +gfc_ignore_trait_property_extension (void) +{ + char buf[GFC_MAX_SYMBOL_LEN + 1]; + gfc_expr *expr; + + /* Identifier form of trait-property name, possibly followed by + a list of (recursive) trait-property-extensions. */ + if (gfc_match_name (buf) == MATCH_YES) + { + if (gfc_match (" (") == MATCH_YES) + return gfc_ignore_trait_property_extension_list (); + return MATCH_YES; + } + + /* Literal constant. */ + if (gfc_match_literal_constant (&expr, 0) == MATCH_YES) + return MATCH_YES; + + /* FIXME: constant integer expressions. */ + gfc_error ("Expected trait-property-extension at %C"); + return MATCH_ERROR; +} + +static match +gfc_ignore_trait_property_extension_list (void) +{ + while (1) + { + if (gfc_ignore_trait_property_extension () != MATCH_YES) + return MATCH_ERROR; + if (gfc_match (" ,") == MATCH_YES) + continue; + if (gfc_match (" )") == MATCH_YES) + return MATCH_YES; + gfc_error ("expected %<)%> at %C"); + return MATCH_ERROR; + } +} /* OpenMP 5.0: @@ -5618,75 +5656,37 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss) } gfc_omp_selector *os = gfc_get_omp_selector (); - os->trait_selector_name = XNEWVEC (char, strlen (selector) + 1); - strcpy (os->trait_selector_name, selector); + if (oss->code == OMP_TRAIT_SET_CONSTRUCT + && !strcmp (selector, "do")) + os->code = OMP_TRAIT_CONSTRUCT_FOR; + else if (oss->code == OMP_TRAIT_SET_CONSTRUCT + && !strcmp (selector, "for")) + os->code = OMP_TRAIT_INVALID; + else + os->code = omp_lookup_ts_code (oss->code, selector); os->next = oss->trait_selectors; oss->trait_selectors = os; - const char *const *selectors = NULL; - bool allow_score = true; - bool allow_user = false; - int property_limit = 0; - enum gfc_omp_trait_property_kind property_kind = CTX_PROPERTY_NONE; - switch (oss->trait_set_selector_name[0]) - { - case 'c': /* construct */ - selectors = omp_construct_selectors; - allow_score = false; - property_limit = 1; - property_kind = CTX_PROPERTY_SIMD; - break; - case 'd': /* device */ - selectors = omp_device_selectors; - allow_score = false; - allow_user = true; - property_limit = 3; - property_kind = CTX_PROPERTY_NAME_LIST; - break; - case 'i': /* implementation */ - selectors = omp_implementation_selectors; - allow_user = true; - property_limit = 3; - property_kind = CTX_PROPERTY_NAME_LIST; - break; - case 'u': /* user */ - selectors = omp_user_selectors; - property_limit = 1; - property_kind = CTX_PROPERTY_EXPR; - break; - default: - gcc_unreachable (); - } - for (int i = 0; ; i++) + if (os->code == OMP_TRAIT_INVALID) { - if (selectors[i] == NULL) - { - if (allow_user) - { - property_kind = CTX_PROPERTY_USER; - break; - } - else - { - gfc_error ("selector %qs not allowed for context selector " - "set %qs at %C", - selector, oss->trait_set_selector_name); - return MATCH_ERROR; - } - } - if (i == property_limit) - property_kind = CTX_PROPERTY_NONE; - if (strcmp (selectors[i], selector) == 0) - break; + gfc_warning (OPT_Wopenmp, + "unknown selector %qs for context selector set %qs " + "at %C", + selector, omp_tss_map[oss->code]); + if (gfc_match (" (") == MATCH_YES + && gfc_ignore_trait_property_extension_list () != MATCH_YES) + return MATCH_ERROR; + if (gfc_match (" ,") == MATCH_YES) + continue; + break; } - if (property_kind == CTX_PROPERTY_NAME_LIST - && oss->trait_set_selector_name[0] == 'i' - && strcmp (selector, "atomic_default_mem_order") == 0) - property_kind = CTX_PROPERTY_ID; + + enum omp_tp_type property_kind = omp_ts_map[os->code].tp_type; + bool allow_score = omp_ts_map[os->code].allow_score; if (gfc_match (" (") == MATCH_YES) { - if (property_kind == CTX_PROPERTY_NONE) + if (property_kind == OMP_TRAIT_PROPERTY_NONE) { gfc_error ("selector %qs does not accept any properties at %C", selector); @@ -5737,22 +5737,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss) switch (property_kind) { - case CTX_PROPERTY_USER: - do - { - if (gfc_match_expr (&otp->expr) != MATCH_YES) - { - gfc_error ("property must be constant integer " - "expression or string literal at %C"); - return MATCH_ERROR; - } - - if (gfc_match (" ,") != MATCH_YES) - break; - } - while (1); - break; - case CTX_PROPERTY_ID: + case OMP_TRAIT_PROPERTY_ID: { char buf[GFC_MAX_SYMBOL_LEN + 1]; if (gfc_match_name (buf) == MATCH_YES) @@ -5767,7 +5752,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss) } } break; - case CTX_PROPERTY_NAME_LIST: + case OMP_TRAIT_PROPERTY_NAME_LIST: do { char buf[GFC_MAX_SYMBOL_LEN + 1]; @@ -5798,7 +5783,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss) } while (1); break; - case CTX_PROPERTY_EXPR: + case OMP_TRAIT_PROPERTY_EXPR: if (gfc_match_expr (&otp->expr) != MATCH_YES) { gfc_error ("expected expression at %C"); @@ -5814,7 +5799,7 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss) return MATCH_ERROR; } break; - case CTX_PROPERTY_SIMD: + case OMP_TRAIT_PROPERTY_CLAUSE_LIST: { if (gfc_match_omp_clauses (&otp->clauses, OMP_DECLARE_SIMD_CLAUSES, @@ -5836,9 +5821,9 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss) return MATCH_ERROR; } } - else if (property_kind == CTX_PROPERTY_NAME_LIST - || property_kind == CTX_PROPERTY_ID - || property_kind == CTX_PROPERTY_EXPR) + else if (property_kind != OMP_TRAIT_PROPERTY_NONE + && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST + && property_kind != OMP_TRAIT_PROPERTY_EXTENSION) { if (gfc_match (" (") != MATCH_YES) { @@ -5874,20 +5859,16 @@ gfc_match_omp_context_selector_specification (gfc_omp_declare_variant *odv) do { match m; - const char *selector_sets[] = { "construct", "device", - "implementation", "user" }; - const int selector_set_count = ARRAY_SIZE (selector_sets); - int i; char buf[GFC_MAX_SYMBOL_LEN + 1]; + enum omp_tss_code set = OMP_TRAIT_SET_INVALID; m = gfc_match_name (buf); if (m == MATCH_YES) - for (i = 0; i < selector_set_count; i++) - if (strcmp (buf, selector_sets[i]) == 0) - break; + set = omp_lookup_tss_code (buf); - if (m != MATCH_YES || i == selector_set_count) + if (set == OMP_TRAIT_SET_INVALID) { + /* FIXME: hard-coded list of set names is prone to bit-rot. */ gfc_error ("expected %, %, % " "or % at %C"); return MATCH_ERROR; @@ -5909,7 +5890,7 @@ gfc_match_omp_context_selector_specification (gfc_omp_declare_variant *odv) gfc_omp_set_selector *oss = gfc_get_omp_set_selector (); oss->next = odv->set_selectors; - oss->trait_set_selector_name = selector_sets[i]; + oss->code = set; odv->set_selectors = oss; if (gfc_match_omp_context_selector (oss) != MATCH_YES) diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 60154ff3751..ea7ae0fa0c0 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -8208,18 +8208,32 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) { tree selectors = NULL_TREE; gfc_omp_selector *os; + enum omp_tss_code set = oss->code; + gcc_assert (set != OMP_TRAIT_SET_INVALID); + for (os = oss->trait_selectors; os; os = os->next) { tree scoreval = NULL_TREE; tree properties = NULL_TREE; gfc_omp_trait_property *otp; + enum omp_ts_code sel = os->code; + + /* Per the spec, "Implementations can ignore specified + selectors that are not those described in this section"; + however, we must record such selectors because they + cause match failures. */ + if (sel == OMP_TRAIT_INVALID) + { + selectors = make_trait_selector (sel, NULL_TREE, NULL_TREE, + selectors); + continue; + } for (otp = os->properties; otp; otp = otp->next) { switch (otp->property_kind) { - case CTX_PROPERTY_USER: - case CTX_PROPERTY_EXPR: + case OMP_TRAIT_PROPERTY_EXPR: { gfc_se se; gfc_init_se (&se, NULL); @@ -8228,12 +8242,12 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) properties); } break; - case CTX_PROPERTY_ID: + case OMP_TRAIT_PROPERTY_ID: properties = make_trait_property (get_identifier (otp->name), NULL_TREE, properties); break; - case CTX_PROPERTY_NAME_LIST: + case OMP_TRAIT_PROPERTY_NAME_LIST: { tree prop = OMP_TP_NAMELIST_NODE; tree value = NULL_TREE; @@ -8246,7 +8260,7 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) properties); } break; - case CTX_PROPERTY_SIMD: + case OMP_TRAIT_PROPERTY_CLAUSE_LIST: properties = gfc_trans_omp_clauses (NULL, otp->clauses, odv->where, true); break; @@ -8263,13 +8277,10 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) scoreval = se.expr; } - tree ts_name = get_identifier (os->trait_selector_name); - selectors = make_trait_selector (ts_name, scoreval, + selectors = make_trait_selector (sel, scoreval, properties, selectors); } - - tree tss_name = get_identifier (oss->trait_set_selector_name); - set_selectors = make_trait_set_selector (tss_name, selectors, + set_selectors = make_trait_set_selector (set, selectors, set_selectors); } @@ -8298,8 +8309,10 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) variant_proc_name, &odv->where); variant_proc_sym = NULL; } - else if (omp_get_context_selector (set_selectors, "construct", - "simd") == NULL_TREE) + else if (omp_get_context_selector (set_selectors, + OMP_TRAIT_SET_CONSTRUCT, + OMP_TRAIT_CONSTRUCT_SIMD) + == NULL_TREE) { char err[256]; if (!gfc_compare_interfaces (ns->proc_name, variant_proc_sym, @@ -8316,8 +8329,9 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) if (variant_proc_sym != NULL) { gfc_set_sym_referenced (variant_proc_sym); - tree construct = omp_get_context_selector (set_selectors, - "construct", NULL); + tree construct + = omp_get_context_selector_list (set_selectors, + OMP_TRAIT_SET_CONSTRUCT); omp_mark_declare_variant (gfc_get_location (&odv->where), gfc_get_symbol_decl (variant_proc_sym), construct); diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index a71ef23c37b..ee4b0f70b86 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -13560,12 +13560,17 @@ omp_construct_selector_matches (enum tree_code *constructs, int nconstructs, if (tree attr = lookup_attribute ("omp declare variant variant", DECL_ATTRIBUTES (current_function_decl))) { - enum tree_code variant_constructs[5]; - int variant_nconstructs = 0; - if (!target_seen) - variant_nconstructs - = omp_construct_traits_to_codes (TREE_VALUE (attr), - variant_constructs); + tree selectors = TREE_VALUE (attr); + int variant_nconstructs = list_length (selectors); + enum tree_code *variant_constructs = NULL; + if (!target_seen && variant_nconstructs) + { + variant_constructs + = (enum tree_code *) alloca (variant_nconstructs + * sizeof (enum tree_code)); + omp_construct_traits_to_codes (selectors, variant_nconstructs, + variant_constructs); + } for (int i = 0; i < variant_nconstructs; i++) { ++cnt; diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index 156508eabb5..5f0cb041ffa 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1013,32 +1013,29 @@ omp_max_simt_vf (void) return 0; } -/* Store the construct selectors as tree codes from last to first, - return their number. */ +/* Store the construct selectors as tree codes from last to first. + CTX is a list of trait selectors, nconstructs must be equal to its + length, and the array CONSTRUCTS holds the output. */ -int -omp_construct_traits_to_codes (tree ctx, enum tree_code *constructs) +void +omp_construct_traits_to_codes (tree ctx, int nconstructs, + enum tree_code *constructs) { - int nconstructs = list_length (ctx); int i = nconstructs - 1; + + /* Order must match the OMP_TRAIT_CONSTRUCT_* enumerators in + enum omp_ts_code. */ + static enum tree_code code_map[] + = { OMP_TARGET, OMP_TEAMS, OMP_PARALLEL, OMP_FOR, OMP_SIMD }; + for (tree ts = ctx; ts; ts = TREE_CHAIN (ts), i--) { - const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts)); - if (!strcmp (sel, "target")) - constructs[i] = OMP_TARGET; - else if (!strcmp (sel, "teams")) - constructs[i] = OMP_TEAMS; - else if (!strcmp (sel, "parallel")) - constructs[i] = OMP_PARALLEL; - else if (!strcmp (sel, "for") || !strcmp (sel, "do")) - constructs[i] = OMP_FOR; - else if (!strcmp (sel, "simd")) - constructs[i] = OMP_SIMD; - else - gcc_unreachable (); + enum omp_ts_code sel = OMP_TS_CODE (ts); + int j = (int)sel - (int)OMP_TRAIT_CONSTRUCT_TARGET; + gcc_assert (j >= 0 && (unsigned int) j < ARRAY_SIZE (code_map)); + constructs[i] = code_map[j]; } gcc_assert (i == -1); - return nconstructs; } /* Return true if PROP is possibly present in one of the offloading target's @@ -1114,6 +1111,124 @@ omp_maybe_offloaded (void) return false; } +/* Lookup tables for context selectors. */ +const char *omp_tss_map[] = + { + "construct", + "device", + "target_device", + "implementation", + "user", + NULL +}; + +/* Arrays of property candidates must be null-terminated. */ +static const char *const kind_properties[] = + { "host", "nohost", "cpu", "gpu", "fpga", "any", NULL }; +static const char *const vendor_properties[] = + { "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel", + "llvm", "nvidia", "pgi", "ti", "unknown", NULL }; +static const char *const extension_properties[] = + { NULL }; +static const char *const atomic_default_mem_order_properties[] = + { "seq_cst", "relaxed", "acq_rel", NULL }; + +struct omp_ts_info omp_ts_map[] = + { + { "kind", + (1 << OMP_TRAIT_SET_DEVICE) | (1 << OMP_TRAIT_SET_TARGET_DEVICE), + OMP_TRAIT_PROPERTY_NAME_LIST, false, + kind_properties + }, + { "isa", + (1 << OMP_TRAIT_SET_DEVICE) | (1 << OMP_TRAIT_SET_TARGET_DEVICE), + OMP_TRAIT_PROPERTY_NAME_LIST, false, + NULL + }, + { "arch", + (1 << OMP_TRAIT_SET_DEVICE) | (1 << OMP_TRAIT_SET_TARGET_DEVICE), + OMP_TRAIT_PROPERTY_NAME_LIST, false, + NULL + }, + { "device_num", + (1 << OMP_TRAIT_SET_TARGET_DEVICE), + OMP_TRAIT_PROPERTY_EXPR, false, + NULL + }, + { "vendor", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_NAME_LIST, true, + vendor_properties, + }, + { "extension", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_NAME_LIST, true, + extension_properties, + }, + { "atomic_default_mem_order", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_ID, true, + atomic_default_mem_order_properties, + }, + { "requires", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_CLAUSE_LIST, true, + NULL + }, + { "unified_address", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_NONE, true, + NULL + }, + { "unified_shared_memory", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_NONE, true, + NULL + }, + { "dynamic_allocators", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_NONE, true, + NULL + }, + { "reverse_offload", + (1 << OMP_TRAIT_SET_IMPLEMENTATION), + OMP_TRAIT_PROPERTY_NONE, true, + NULL + }, + { "condition", + (1 << OMP_TRAIT_SET_USER), + OMP_TRAIT_PROPERTY_EXPR, true, + NULL + }, + { "target", + (1 << OMP_TRAIT_SET_CONSTRUCT), + OMP_TRAIT_PROPERTY_NONE, false, + NULL + }, + { "teams", + (1 << OMP_TRAIT_SET_CONSTRUCT), + OMP_TRAIT_PROPERTY_NONE, false, + NULL + }, + { "parallel", + (1 << OMP_TRAIT_SET_CONSTRUCT), + OMP_TRAIT_PROPERTY_NONE, false, + NULL + }, + { "for", + (1 << OMP_TRAIT_SET_CONSTRUCT), + OMP_TRAIT_PROPERTY_NONE, false, + NULL + }, + { "simd", + (1 << OMP_TRAIT_SET_CONSTRUCT), + OMP_TRAIT_PROPERTY_CLAUSE_LIST, false, + NULL + }, + { NULL, 0, OMP_TRAIT_PROPERTY_NONE, false, NULL } /* OMP_TRAIT_LAST */ + }; + + /* Return a name from PROP, a property in selectors accepting name lists. */ @@ -1145,124 +1260,115 @@ omp_context_name_list_prop (tree prop) tree omp_check_context_selector (location_t loc, tree ctx) { - /* Each trait-set-selector-name can only be specified once. - There are just 4 set names. */ - for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)) - for (tree t2 = TREE_CHAIN (t1); t2; t2 = TREE_CHAIN (t2)) - if (OMP_TSS_ID (t1) == OMP_TSS_ID (t2)) - { - error_at (loc, "selector set %qs specified more than once", - IDENTIFIER_POINTER (OMP_TSS_ID (t1))); - return error_mark_node; - } + bool tss_seen[OMP_TRAIT_SET_LAST], ts_seen[OMP_TRAIT_LAST]; + + memset (tss_seen, 0, sizeof (tss_seen)); for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) { - /* Each trait-selector-name can only be specified once. */ - if (list_length (OMP_TSS_TRAIT_SELECTORS (tss)) < 5) + enum omp_tss_code tss_code = OMP_TSS_CODE (tss); + + /* Each trait-set-selector-name can only be specified once. */ + if (tss_seen[tss_code]) { - for (tree ts1 = OMP_TSS_TRAIT_SELECTORS (tss); ts1; - ts1 = TREE_CHAIN (ts1)) - for (tree ts2 = TREE_CHAIN (ts1); ts2; ts2 = TREE_CHAIN (ts2)) - if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2)) - { - error_at (loc, - "selector %qs specified more than once in set %qs", - IDENTIFIER_POINTER (OMP_TS_ID (ts1)), - IDENTIFIER_POINTER (OMP_TSS_ID (tss))); - return error_mark_node; - } + error_at (loc, "selector set %qs specified more than once", + OMP_TSS_NAME (tss)); + return error_mark_node; } else + tss_seen[tss_code] = true; + + memset (ts_seen, 0, sizeof (ts_seen)); + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) { - hash_set pset; - for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; - ts = TREE_CHAIN (ts)) - if (pset.add (OMP_TS_ID (ts))) + enum omp_ts_code ts_code = OMP_TS_CODE (ts); + + /* Ignore unknown traits. */ + if (ts_code == OMP_TRAIT_INVALID) + continue; + + /* Each trait-selector-name can only be specified once. */ + if (ts_seen[ts_code]) + { + error_at (loc, + "selector %qs specified more than once in set %qs", + OMP_TS_NAME (ts), + OMP_TSS_NAME (tss)); + return error_mark_node; + } + else + ts_seen[ts_code] = true; + + if (omp_ts_map[ts_code].valid_properties == NULL) + continue; + + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) + for (unsigned j = 0; ; j++) { - error_at (loc, - "selector %qs specified more than once in set %qs", - IDENTIFIER_POINTER (OMP_TS_ID (ts)), - IDENTIFIER_POINTER (OMP_TSS_ID (tss))); - return error_mark_node; + const char *candidate + = omp_ts_map[ts_code].valid_properties[j]; + if (candidate == NULL) + { + /* We've reached the end of the candidate array. */ + if (ts_code == OMP_TRAIT_IMPLEMENTATION_ADMO) + /* FIXME: not sure why this is an error vs warnings + for the others, + incorrect/unknown wording? */ + { + error_at (loc, + "incorrect property %qs of %qs selector", + IDENTIFIER_POINTER (OMP_TP_NAME (p)), + "atomic_default_mem_order"); + return error_mark_node; + } + if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE + && (TREE_CODE (OMP_TP_VALUE (p)) == STRING_CST)) + warning_at (loc, OPT_Wopenmp, + "unknown property %qE of %qs selector", + OMP_TP_VALUE (p), + OMP_TS_NAME (ts)); + else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) + warning_at (loc, OPT_Wopenmp, + "unknown property %qs of %qs selector", + omp_context_name_list_prop (p), + OMP_TS_NAME (ts)); + else if (OMP_TP_NAME (p)) + warning_at (loc, OPT_Wopenmp, + "unknown property %qs of %qs selector", + IDENTIFIER_POINTER (OMP_TP_NAME (p)), + OMP_TS_NAME (ts)); + break; + } + else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) + /* Property-list traits. */ + { + const char *str = omp_context_name_list_prop (p); + if (str && !strcmp (str, candidate)) + break; + } + else if (!strcmp (IDENTIFIER_POINTER (OMP_TP_NAME (p)), + candidate)) + /* Identifier traits. */ + break; } } - - static const char *const kind[] = { - "host", "nohost", "cpu", "gpu", "fpga", "any", NULL }; - static const char *const vendor[] = { - "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel", - "llvm", "nvidia", "pgi", "ti", "unknown", NULL }; - static const char *const extension[] = { NULL }; - static const char *const atomic_default_mem_order[] = { - "seq_cst", "relaxed", "acq_rel", NULL }; - struct known_properties { const char *set; const char *selector; - const char *const *props; }; - known_properties props[] = { - { "device", "kind", kind }, - { "implementation", "vendor", vendor }, - { "implementation", "extension", extension }, - { "implementation", "atomic_default_mem_order", - atomic_default_mem_order } }; - for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) - for (unsigned i = 0; i < ARRAY_SIZE (props); i++) - if (!strcmp (IDENTIFIER_POINTER (OMP_TS_ID (ts)), - props[i].selector) - && !strcmp (IDENTIFIER_POINTER (OMP_TSS_ID (tss)), - props[i].set)) - for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) - for (unsigned j = 0; ; j++) - { - if (props[i].props[j] == NULL) - { - if (props[i].props == atomic_default_mem_order) - { - error_at (loc, - "incorrect property %qs of %qs selector", - IDENTIFIER_POINTER (TREE_PURPOSE (p)), - "atomic_default_mem_order"); - return error_mark_node; - } - else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE - && (TREE_CODE (OMP_TP_VALUE (p)) == STRING_CST)) - warning_at (loc, 0, - "unknown property %qE of %qs selector", - OMP_TP_VALUE (p), - props[i].selector); - else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) - warning_at (loc, 0, - "unknown property %qs of %qs selector", - omp_context_name_list_prop (p), - props[i].selector); - else if (OMP_TP_NAME (p)) - warning_at (loc, OPT_Wopenmp, - "unknown property %qs of %qs selector", - IDENTIFIER_POINTER (OMP_TP_NAME (p)), - props[i].selector); - break; - } - else if (OMP_TP_NAME (p) == OMP_TP_NAMELIST_NODE) - /* Property-list traits. */ - { - const char *str = omp_context_name_list_prop (p); - if (str && !strcmp (str, props[i].props[j])) - break; - } - else if (!strcmp (IDENTIFIER_POINTER (OMP_TP_NAME (p)), - props[i].props[j])) - break; - } } return ctx; } /* Register VARIANT as variant of some base function marked with - #pragma omp declare variant. CONSTRUCT is corresponding construct - selector set. */ - + #pragma omp declare variant. CONSTRUCT is corresponding list of + trait-selectors for the construct selector set. This is stashed as the + value of the "omp declare variant variant" attribute on VARIANT. */ void omp_mark_declare_variant (location_t loc, tree variant, tree construct) { + /* Ignore this variant if it contains unknown construct selectors. + It will never match, and the front ends have already issued a warning + about it. */ + for (tree c = construct; c; c = TREE_CHAIN (c)) + if (OMP_TS_CODE (c) == OMP_TRAIT_INVALID) + return; + tree attr = lookup_attribute ("omp declare variant variant", DECL_ATTRIBUTES (variant)); if (attr == NULL_TREE) @@ -1275,7 +1381,8 @@ omp_mark_declare_variant (location_t loc, tree variant, tree construct) } if ((TREE_VALUE (attr) != NULL_TREE) != (construct != NULL_TREE) || (construct != NULL_TREE - && omp_context_selector_set_compare ("construct", TREE_VALUE (attr), + && omp_context_selector_set_compare (OMP_TRAIT_SET_CONSTRUCT, + TREE_VALUE (attr), construct))) error_at (loc, "%qD used as a variant with incompatible % " "selector sets", variant); @@ -1285,18 +1392,21 @@ omp_mark_declare_variant (location_t loc, tree variant, tree construct) /* Constructors for context selectors. */ tree -make_trait_set_selector (tree name, tree selectors, tree chain) +make_trait_set_selector (enum omp_tss_code code, tree selectors, tree chain) { - return tree_cons (name, selectors, chain); + return tree_cons (build_int_cst (integer_type_node, code), + selectors, chain); } tree -make_trait_selector (tree name, tree score, tree properties, tree chain) +make_trait_selector (enum omp_ts_code code, tree score, tree properties, + tree chain) { if (score == NULL_TREE) - return tree_cons (name, properties, chain); + return tree_cons (build_int_cst (integer_type_node, code), + properties, chain); else - return tree_cons (name, + return tree_cons (build_int_cst (integer_type_node, code), tree_cons (OMP_TS_SCORE_NODE, score, properties), chain); } @@ -1319,8 +1429,16 @@ omp_context_selector_matches (tree ctx) int ret = 1; for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) { - char set = IDENTIFIER_POINTER (OMP_TSS_ID (tss))[0]; - if (set == 'c') + enum omp_tss_code set = OMP_TSS_CODE (tss); + tree selectors = OMP_TSS_TRAIT_SELECTORS (tss); + + /* Immediately reject the match if there are any ignored + selectors present. */ + for (tree ts = selectors; ts; ts = TREE_CHAIN (ts)) + if (OMP_TS_CODE (ts) == OMP_TRAIT_INVALID) + return 0; + + if (set == OMP_TRAIT_SET_CONSTRUCT) { /* For now, ignore the construct set. While something can be determined already during parsing, we don't know until end of TU @@ -1335,10 +1453,20 @@ omp_context_selector_matches (tree ctx) continue; } - enum tree_code constructs[5]; - int nconstructs - = omp_construct_traits_to_codes (OMP_TSS_TRAIT_SELECTORS (tss), + int nconstructs = list_length (selectors); + enum tree_code *constructs = NULL; + if (nconstructs) + { + /* Even though this alloca appears in a loop over selector + sets, it does not repeatedly grow the stack, because + there can be only one construct selector set specified. + This is enforced by omp_check_context_selector. */ + constructs + = (enum tree_code *) alloca (nconstructs + * sizeof (enum tree_code)); + omp_construct_traits_to_codes (selectors, nconstructs, constructs); + } if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) { @@ -1369,13 +1497,13 @@ omp_context_selector_matches (tree ctx) ret = -1; continue; } - for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) + for (tree ts = selectors; ts; ts = TREE_CHAIN (ts)) { - const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts)); - switch (*sel) + enum omp_ts_code sel = OMP_TS_CODE (ts); + switch (sel) { - case 'v': - if (set == 'i' && !strcmp (sel, "vendor")) + case OMP_TRAIT_IMPLEMENTATION_VENDOR: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { const char *prop = omp_context_name_list_prop (p); @@ -1386,13 +1514,13 @@ omp_context_selector_matches (tree ctx) return 0; } break; - case 'e': - if (set == 'i' && !strcmp (sel, "extension")) + case OMP_TRAIT_IMPLEMENTATION_EXTENSION: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) /* We don't support any extensions right now. */ return 0; break; - case 'a': - if (set == 'i' && !strcmp (sel, "atomic_default_mem_order")) + case OMP_TRAIT_IMPLEMENTATION_ADMO: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) { if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) break; @@ -1424,7 +1552,9 @@ omp_context_selector_matches (tree ctx) && omo != OMP_MEMORY_ORDER_ACQ_REL) return 0; } - if (set == 'd' && !strcmp (sel, "arch")) + break; + case OMP_TRAIT_DEVICE_ARCH: + if (set == OMP_TRAIT_SET_DEVICE) for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { const char *arch = omp_context_name_list_prop (p); @@ -1461,8 +1591,8 @@ omp_context_selector_matches (tree ctx) ret = -1; } break; - case 'u': - if (set == 'i' && !strcmp (sel, "unified_address")) + case OMP_TRAIT_IMPLEMENTATION_UNIFIED_ADDRESS: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) { if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) break; @@ -1474,9 +1604,10 @@ omp_context_selector_matches (tree ctx) else return 0; } - break; } - if (set == 'i' && !strcmp (sel, "unified_shared_memory")) + break; + case OMP_TRAIT_IMPLEMENTATION_UNIFIED_SHARED_MEMORY: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) { if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) break; @@ -1489,11 +1620,10 @@ omp_context_selector_matches (tree ctx) else return 0; } - break; } break; - case 'd': - if (set == 'i' && !strcmp (sel, "dynamic_allocators")) + case OMP_TRAIT_IMPLEMENTATION_DYNAMIC_ALLOCATORS: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) { if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) break; @@ -1506,11 +1636,10 @@ omp_context_selector_matches (tree ctx) else return 0; } - break; } break; - case 'r': - if (set == 'i' && !strcmp (sel, "reverse_offload")) + case OMP_TRAIT_IMPLEMENTATION_REVERSE_OFFLOAD: + if (set == OMP_TRAIT_SET_IMPLEMENTATION) { if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) break; @@ -1522,11 +1651,10 @@ omp_context_selector_matches (tree ctx) else return 0; } - break; } break; - case 'k': - if (set == 'd' && !strcmp (sel, "kind")) + case OMP_TRAIT_DEVICE_KIND: + if (set == OMP_TRAIT_SET_DEVICE) for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { const char *prop = omp_context_name_list_prop (p); @@ -1586,8 +1714,8 @@ omp_context_selector_matches (tree ctx) ret = -1; } break; - case 'i': - if (set == 'd' && !strcmp (sel, "isa")) + case OMP_TRAIT_DEVICE_ISA: + if (set == OMP_TRAIT_SET_DEVICE) for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) { const char *isa = omp_context_name_list_prop (p); @@ -1639,8 +1767,8 @@ omp_context_selector_matches (tree ctx) ret = -1; } break; - case 'c': - if (set == 'u' && !strcmp (sel, "condition")) + case OMP_TRAIT_USER_CONDITION: + if (set == OMP_TRAIT_SET_USER) for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) if (OMP_TP_NAME (p) == NULL_TREE) { @@ -1782,7 +1910,8 @@ omp_construct_simd_compare (tree clauses1, tree clauses2) Unlike set names or selector names, properties can have duplicates. */ static int -omp_context_selector_props_compare (const char *set, const char *sel, +omp_context_selector_props_compare (enum omp_tss_code set, + enum omp_ts_code sel, tree ctx1, tree ctx2) { int ret = 0; @@ -1795,7 +1924,8 @@ omp_context_selector_props_compare (const char *set, const char *sel, { if (OMP_TP_NAME (p1) == NULL_TREE) { - if (set[0] == 'u' && strcmp (sel, "condition") == 0) + if (set == OMP_TRAIT_SET_USER + && sel == OMP_TRAIT_USER_CONDITION) { if (integer_zerop (OMP_TP_VALUE (p1)) != integer_zerop (OMP_TP_VALUE (p2))) @@ -1842,8 +1972,18 @@ omp_context_selector_props_compare (const char *set, const char *sel, 2 if neither context is a subset of another one. */ int -omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) +omp_context_selector_set_compare (enum omp_tss_code set, tree ctx1, tree ctx2) { + + /* If either list includes an ignored selector trait, neither can + be a subset of the other. */ + for (tree ts = ctx1; ts; ts = TREE_CHAIN (ts)) + if (OMP_TS_CODE (ts) == OMP_TRAIT_INVALID) + return 2; + for (tree ts = ctx2; ts; ts = TREE_CHAIN (ts)) + if (OMP_TS_CODE (ts) == OMP_TRAIT_INVALID) + return 2; + bool swapped = false; int ret = 0; int len1 = list_length (ctx1); @@ -1855,18 +1995,18 @@ omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) std::swap (ctx1, ctx2); std::swap (len1, len2); } - if (set[0] == 'c') + + if (set == OMP_TRAIT_SET_CONSTRUCT) { tree ts1; tree ts2 = ctx2; - tree simd = get_identifier ("simd"); /* Handle construct set specially. In this case the order of the selector matters too. */ for (ts1 = ctx1; ts1; ts1 = TREE_CHAIN (ts1)) - if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2)) + if (OMP_TS_CODE (ts1) == OMP_TS_CODE (ts2)) { int r = 0; - if (OMP_TS_ID (ts1) == simd) + if (OMP_TS_CODE (ts1) == OMP_TRAIT_CONSTRUCT_SIMD) r = omp_construct_simd_compare (OMP_TS_PROPERTIES (ts1), OMP_TS_PROPERTIES (ts2)); if (r == 2 || (ret && r && (ret < 0) != (r < 0))) @@ -1898,17 +2038,17 @@ omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) } for (tree ts1 = ctx1; ts1; ts1 = TREE_CHAIN (ts1)) { + enum omp_ts_code sel = OMP_TS_CODE (ts1); tree ts2; for (ts2 = ctx2; ts2; ts2 = TREE_CHAIN (ts2)) - if (OMP_TS_ID (ts1) == OMP_TS_ID (ts2)) + if (sel == OMP_TS_CODE (ts2)) { tree score1 = OMP_TS_SCORE (ts1); tree score2 = OMP_TS_SCORE (ts2); if (score1 && score2 && !simple_cst_equal (score1, score2)) return 2; - const char *sel = IDENTIFIER_POINTER (OMP_TS_ID (ts1)); - int r = omp_context_selector_props_compare (set, sel, + int r = omp_context_selector_props_compare (set, OMP_TS_CODE (ts1), OMP_TS_PROPERTIES (ts1), OMP_TS_PROPERTIES (ts2)); if (r == 2 || (ret && r && (ret < 0) != (r < 0))) @@ -1954,11 +2094,11 @@ omp_context_selector_compare (tree ctx1, tree ctx2) } for (tree tss1 = ctx1; tss1; tss1 = TREE_CHAIN (tss1)) { + enum omp_tss_code set = OMP_TSS_CODE (tss1); tree tss2; for (tss2 = ctx2; tss2; tss2 = TREE_CHAIN (tss2)) - if (OMP_TSS_ID (tss1) == OMP_TSS_ID (tss2)) + if (set == OMP_TSS_CODE (tss2)) { - const char *set = IDENTIFIER_POINTER (OMP_TSS_ID (tss1)); int r = omp_context_selector_set_compare (set, OMP_TSS_TRAIT_SELECTORS (tss1), @@ -1985,26 +2125,51 @@ omp_context_selector_compare (tree ctx1, tree ctx2) } /* From context selector CTX, return trait-selector with name SEL in - trait-selector-set with name SET if any, or NULL_TREE if not found. - If SEL is NULL, return the list of trait-selectors in SET. */ + trait-selector-set with name SET if any, or NULL_TREE if not found. */ +tree +omp_get_context_selector (tree ctx, enum omp_tss_code set, + enum omp_ts_code sel) +{ + for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) + if (OMP_TSS_CODE (tss) == set) + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) + if (OMP_TS_CODE (ts) == sel) + return ts; + return NULL_TREE; +} +/* Similar, but returns the whole trait-selector list for SET in CTX. */ tree -omp_get_context_selector (tree ctx, const char *set, const char *sel) +omp_get_context_selector_list (tree ctx, enum omp_tss_code set) { - tree setid = get_identifier (set); - tree selid = sel ? get_identifier (sel) : NULL_TREE; for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) - if (OMP_TSS_ID (tss) == setid) - { - if (sel == NULL) - return OMP_TSS_TRAIT_SELECTORS (tss); - for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) - if (OMP_TS_ID (ts) == selid) - return ts; - } + if (OMP_TSS_CODE (tss) == set) + return OMP_TSS_TRAIT_SELECTORS (tss); return NULL_TREE; } +/* Map string S onto a trait selector set code. */ +enum omp_tss_code +omp_lookup_tss_code (const char * s) +{ + for (int i = 0; i < OMP_TRAIT_SET_LAST; i++) + if (strcmp (s, omp_tss_map[i]) == 0) + return (enum omp_tss_code) i; + return OMP_TRAIT_SET_INVALID; +} + +/* Map string S onto a trait selector code for set SET. */ +enum omp_ts_code +omp_lookup_ts_code (enum omp_tss_code set, const char *s) +{ + unsigned int mask = 1 << set; + for (int i = 0; i < OMP_TRAIT_LAST; i++) + if ((mask & omp_ts_map[i].tss_mask) != 0 + && strcmp (s, omp_ts_map[i].name) == 0) + return (enum omp_ts_code) i; + return OMP_TRAIT_INVALID; +} + /* Needs to be a GC-friendly widest_int variant, but precision is desirable to be the same on all targets. */ typedef generic_wide_int > score_wide_int; @@ -2017,14 +2182,18 @@ typedef generic_wide_int > score_wide_int; static bool omp_context_compute_score (tree ctx, score_wide_int *score, bool declare_simd) { - tree construct = omp_get_context_selector (ctx, "construct", NULL); - bool has_kind = omp_get_context_selector (ctx, "device", "kind"); - bool has_arch = omp_get_context_selector (ctx, "device", "arch"); - bool has_isa = omp_get_context_selector (ctx, "device", "isa"); + tree selectors + = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT); + bool has_kind = omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE, + OMP_TRAIT_DEVICE_KIND); + bool has_arch = omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE, + OMP_TRAIT_DEVICE_ARCH); + bool has_isa = omp_get_context_selector (ctx, OMP_TRAIT_SET_DEVICE, + OMP_TRAIT_DEVICE_ISA); bool ret = false; *score = 1; for (tree tss = ctx; tss; tss = TREE_CHAIN (tss)) - if (OMP_TSS_TRAIT_SELECTORS (tss) != construct) + if (OMP_TSS_TRAIT_SELECTORS (tss) != selectors) for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) { tree s = OMP_TS_SCORE (ts); @@ -2033,13 +2202,19 @@ omp_context_compute_score (tree ctx, score_wide_int *score, bool declare_simd) TYPE_SIGN (TREE_TYPE (s))); } - if (construct || has_kind || has_arch || has_isa) + if (selectors || has_kind || has_arch || has_isa) { - int scores[12]; - enum tree_code constructs[5]; - int nconstructs = 0; - if (construct) - nconstructs = omp_construct_traits_to_codes (construct, constructs); + int nconstructs = list_length (selectors); + enum tree_code *constructs = NULL; + if (nconstructs) + { + constructs + = (enum tree_code *) alloca (nconstructs + * sizeof (enum tree_code)); + omp_construct_traits_to_codes (selectors, nconstructs, constructs); + } + int *scores + = (int *) alloca ((2 * nconstructs + 2) * sizeof (int)); if (omp_construct_selector_matches (constructs, nconstructs, scores) == 2) ret = true; diff --git a/gcc/omp-general.h b/gcc/omp-general.h index dc5e5f6ba1f..8a0338b9942 100644 --- a/gcc/omp-general.h +++ b/gcc/omp-general.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "gomp-constants.h" #include "omp-api.h" +#include "omp-selectors.h" /* Flags for an OpenACC loop. */ @@ -135,8 +136,18 @@ struct omp_for_data #define OMP_TP_VALUE(NODE) \ TREE_VALUE (NODE) -extern tree make_trait_set_selector (tree, tree, tree); -extern tree make_trait_selector (tree, tree, tree, tree); +#define OMP_TSS_CODE(t) \ + ((enum omp_tss_code) TREE_INT_CST_LOW (OMP_TSS_ID (t))) +#define OMP_TSS_NAME(t) \ + (omp_tss_map[OMP_TSS_CODE (t)]) + +#define OMP_TS_CODE(t) \ + ((enum omp_ts_code) TREE_INT_CST_LOW (OMP_TS_ID (t))) +#define OMP_TS_NAME(t) \ + (omp_ts_map[OMP_TS_CODE (t)].name) + +extern tree make_trait_set_selector (enum omp_tss_code, tree, tree); +extern tree make_trait_selector (enum omp_ts_code, tree, tree, tree); extern tree make_trait_property (tree, tree, tree); extern tree omp_find_clause (tree clauses, enum omp_clause_code kind); @@ -153,13 +164,15 @@ extern gimple *omp_build_barrier (tree lhs); extern tree find_combined_omp_for (tree *, int *, void *); extern poly_uint64 omp_max_vf (void); extern int omp_max_simt_vf (void); -extern int omp_construct_traits_to_codes (tree, enum tree_code *); +extern void omp_construct_traits_to_codes (tree, int, enum tree_code *); extern tree omp_check_context_selector (location_t loc, tree ctx); extern void omp_mark_declare_variant (location_t loc, tree variant, tree construct); extern int omp_context_selector_matches (tree); -extern int omp_context_selector_set_compare (const char *, tree, tree); -extern tree omp_get_context_selector (tree, const char *, const char *); +extern int omp_context_selector_set_compare (enum omp_tss_code, tree, tree); +extern tree omp_get_context_selector (tree, enum omp_tss_code, + enum omp_ts_code); +extern tree omp_get_context_selector_list (tree, enum omp_tss_code); extern tree omp_resolve_declare_variant (tree); extern tree oacc_launch_pack (unsigned code, tree device, unsigned op); extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims); diff --git a/gcc/omp-selectors.h b/gcc/omp-selectors.h new file mode 100644 index 00000000000..825a082c939 --- /dev/null +++ b/gcc/omp-selectors.h @@ -0,0 +1,93 @@ +/* Data structures for OpenMP context selectors. This is in a separate file + from omp-general.h so that it may also be used in the Fortran parser + without reference to tree data structures. + + Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +#ifndef GCC_OMP_SELECTORS_H +#define GCC_OMP_SELECTORS_H + +/* Trait set selector keywords. */ +enum omp_tss_code { + OMP_TRAIT_SET_CONSTRUCT, + OMP_TRAIT_SET_DEVICE, + OMP_TRAIT_SET_TARGET_DEVICE, + OMP_TRAIT_SET_IMPLEMENTATION, + OMP_TRAIT_SET_USER, + OMP_TRAIT_SET_LAST, + OMP_TRAIT_SET_INVALID = -1 +}; + +/* Trait selector keywords. */ +enum omp_ts_code { + OMP_TRAIT_DEVICE_KIND, + OMP_TRAIT_DEVICE_ISA, + OMP_TRAIT_DEVICE_ARCH, + OMP_TRAIT_DEVICE_NUM, + OMP_TRAIT_IMPLEMENTATION_VENDOR, + OMP_TRAIT_IMPLEMENTATION_EXTENSION, + OMP_TRAIT_IMPLEMENTATION_ADMO, + OMP_TRAIT_IMPLEMENTATION_REQUIRES, + OMP_TRAIT_IMPLEMENTATION_UNIFIED_ADDRESS, + OMP_TRAIT_IMPLEMENTATION_UNIFIED_SHARED_MEMORY, + OMP_TRAIT_IMPLEMENTATION_DYNAMIC_ALLOCATORS, + OMP_TRAIT_IMPLEMENTATION_REVERSE_OFFLOAD, + OMP_TRAIT_USER_CONDITION, + OMP_TRAIT_CONSTRUCT_TARGET, + OMP_TRAIT_CONSTRUCT_TEAMS, + OMP_TRAIT_CONSTRUCT_PARALLEL, + OMP_TRAIT_CONSTRUCT_FOR, + OMP_TRAIT_CONSTRUCT_SIMD, + OMP_TRAIT_LAST, + OMP_TRAIT_INVALID = -1 +}; + +/* All trait property forms. */ +enum omp_tp_type { + OMP_TRAIT_PROPERTY_NONE, + OMP_TRAIT_PROPERTY_ID, + OMP_TRAIT_PROPERTY_NAME_LIST, + OMP_TRAIT_PROPERTY_EXPR, + OMP_TRAIT_PROPERTY_CLAUSE_LIST, + OMP_TRAIT_PROPERTY_EXTENSION +}; + +/* Map trait set selector name keywords onto strings. */ +extern const char *omp_tss_map []; + +/* Map trait selector keywords onto strings, allowed contexts, and + allowed property names for OMP_TRAIT_PROPERTY_NAME_LIST and + OMP_TRAIT_PROPERTY_ID properties. If valid_properties is null, + it means that any required checking has to be done explicitly + somewhere instead of being driven by the table. Otherwise it's a + null-terminated array of strings. */ +struct omp_ts_info { + const char *name; + unsigned int tss_mask; + enum omp_tp_type tp_type; + bool allow_score; + const char * const *valid_properties; +}; +extern struct omp_ts_info omp_ts_map[]; + +extern enum omp_tss_code omp_lookup_tss_code (const char *); +extern enum omp_ts_code omp_lookup_ts_code (enum omp_tss_code, const char *); + +#endif /* GCC_OMP_SELECTORS_H */ diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-1.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-1.c index 8b3cd7fed9f..75fcb7bf0e7 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-variant-1.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-1.c @@ -9,6 +9,7 @@ int bar (int, int, int *); match (device={arch(x86_64,powerpc64),isa(avx512f,popcntb)}, \ implementation={atomic_default_mem_order(seq_cst),made_up_selector("foo", 13, "bar")}, \ user={condition(3-3)}) +/* { dg-warning "unknown selector 'made_up_selector'" "" { target *-*-* } .-2 } */ int baz (int, int, int *); int diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c index 3c2c12c9e03..97285fa3b74 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c @@ -42,10 +42,10 @@ void f20 (void); void f21 (void); /* { dg-error "cannot appear in a constant-expression" "" { target c++98_only } .-1 } */ #pragma omp declare variant (f1) match(user={condition(1, 2, 3)}) /* { dg-error "expected '\\)' before ',' token" } */ void f22 (void); -#pragma omp declare variant (f1) match(construct={master}) /* { dg-error "selector 'master' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={master}) /* { dg-warning "unknown selector 'master' for context selector set 'construct'" } */ void f23 (void); -#pragma omp declare variant (f1) match(construct={teams,parallel,master,for}) /* { dg-error "selector 'master' not allowed for context selector set 'construct'" } */ -void f24 (void); /* { dg-error "expected '\\\}' before ',' token" "" { target c } .-1 } */ +#pragma omp declare variant (f1) match(construct={teams,parallel,master,for}) /* { dg-warning "unknown selector 'master' for context selector set 'construct'" } */ +void f24 (void); #pragma omp declare variant (f1) match(construct={parallel(1 /* { dg-error "selector 'parallel' does not accept any properties" } */ void f25 (void); /* { dg-error "expected '\\\}' before end of line" "" { target c++ } .-1 } */ /* { dg-error "expected '\\\}' before '\\(' token" "" { target c } .-2 } */ @@ -79,11 +79,11 @@ void f38 (void); /* { dg-warning "unknown property 'foobar' of 'kind' sele void f39 (void); #pragma omp declare variant (f1) match(device={arch(17)}) /* { dg-error "expected identifier or string literal before numeric constant" } */ void f40 (void); -#pragma omp declare variant (f1) match(device={foobar(3)}) +#pragma omp declare variant (f1) match(device={foobar(3)}) /* { dg-warning "unknown selector 'foobar' for context selector set 'device'" } */ void f41 (void); #pragma omp declare variant (f1) match(device={arch(x86_64)},device={isa(avx512vl)}) /* { dg-error "selector set 'device' specified more than once" } */ void f42 (void); -#pragma omp declare variant (f1) match(implementation={foobar(3)}) +#pragma omp declare variant (f1) match(implementation={foobar(3)}) /* { dg-warning "unknown selector 'foobar' for context selector set 'implementation'" } */ void f43 (void); #pragma omp declare variant (f1) match(implementation={vendor}) /* { dg-error "expected '\\(' before '\\\}' token" } */ void f44 (void); @@ -115,10 +115,10 @@ void f55 (void); void f56 (void); #pragma omp declare variant (f1) match(implementation={atomic_default_mem_order(relaxed)},implementation={atomic_default_mem_order(relaxed)}) /* { dg-error "selector set 'implementation' specified more than once" } */ void f57 (void); -#pragma omp declare variant (f1) match(user={foobar(3)}) /* { dg-error "selector 'foobar' not allowed for context selector set 'user'" } */ -void f58 (void); /* { dg-error "expected '\\\}' before '\\(' token" "" { target c } .-1 } */ -#pragma omp declare variant (f1) match(construct={foobar(3)}) /* { dg-error "selector 'foobar' not allowed for context selector set 'construct'" } */ -void f59 (void); /* { dg-error "expected '\\\}' before '\\(' token" "" { target c } .-1 } */ +#pragma omp declare variant (f1) match(user={foobar(3)}) /* { dg-warning "unknown selector 'foobar' for context selector set 'user'" } */ +void f58 (void); +#pragma omp declare variant (f1) match(construct={foobar(3)}) /* { dg-warning "unknown selector 'foobar' for context selector set 'construct'" } */ +void f59 (void); #pragma omp declare variant (f1) match(construct={parallel},foobar={bar}) /* { dg-error "expected 'construct', 'device', 'implementation' or 'user' before 'foobar'" } */ void f60 (void); #pragma omp declare variant (f1) match(construct={parallel,parallel}) /* { dg-error "selector 'parallel' specified more than once in set 'construct'" } */ @@ -127,27 +127,27 @@ void f61 (void); void f62 (void); #pragma omp declare variant (f1) match(construct={target,teams,teams}) /* { dg-error "selector 'teams' specified more than once in set 'construct'" } */ void f63 (void); -#pragma omp declare variant (f1) match(construct={single}) /* { dg-error "selector 'single' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={single}) /* { dg-warning "unknown selector 'single' for context selector set 'construct'" } */ void f64 (void); -#pragma omp declare variant (f1) match(construct={taskgroup}) /* { dg-error "selector 'taskgroup' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={taskgroup}) /* { dg-warning "unknown selector 'taskgroup' for context selector set 'construct'" } */ void f65 (void); -#pragma omp declare variant (f1) match(construct={do}) /* { dg-error "selector 'do' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={do}) /* { dg-warning "unknown selector 'do' for context selector set 'construct'" } */ void f66 (void); -#pragma omp declare variant (f1) match(construct={threadprivate}) /* { dg-error "selector 'threadprivate' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={threadprivate}) /* { dg-warning "unknown selector 'threadprivate' for context selector set 'construct'" } */ void f67 (void); -#pragma omp declare variant (f1) match(construct={critical}) /* { dg-error "selector 'critical' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={critical}) /* { dg-warning "unknown selector 'critical' for context selector set 'construct'" } */ void f68 (void); -#pragma omp declare variant (f1) match(construct={task}) /* { dg-error "selector 'task' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={task}) /* { dg-warning "unknown selector 'task' for context selector set 'construct'" } */ void f69 (void); -#pragma omp declare variant (f1) match(construct={taskloop}) /* { dg-error "selector 'taskloop' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={taskloop}) /* { dg-warning "unknown selector 'taskloop' for context selector set 'construct'" } */ void f70 (void); -#pragma omp declare variant (f1) match(construct={sections}) /* { dg-error "selector 'sections' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={sections}) /* { dg-warning "unknown selector 'sections' for context selector set 'construct'" } */ void f71 (void); -#pragma omp declare variant (f1) match(construct={section}) /* { dg-error "selector 'section' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={section}) /* { dg-warning "unknown selector 'section' for context selector set 'construct'" } */ void f72 (void); -#pragma omp declare variant (f1) match(construct={workshare}) /* { dg-error "selector 'workshare' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={workshare}) /* { dg-warning "unknown selector 'workshare' for context selector set 'construct'" } */ void f73 (void); -#pragma omp declare variant (f1) match(construct={requires}) /* { dg-error "selector 'requires' not allowed for context selector set 'construct'" } */ +#pragma omp declare variant (f1) match(construct={requires}) /* { dg-warning "unknown selector 'requires' for context selector set 'construct'" } */ void f74 (void); void f75a (void); #pragma omp declare variant (f75a),match(construct={parallel}) diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-1.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-1.f90 index de09dbfe806..50d7e41613f 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-1.f90 @@ -25,6 +25,7 @@ module main !$omp & match (device={arch(x86_64,powerpc64),isa(avx512f,popcntb)}, & !$omp & implementation={atomic_default_mem_order(seq_cst),made_up_selector("foo", 13, "bar")}, & !$omp & user={condition(3-3)}) +! { dg-warning "unknown selector 'made_up_selector'" "" { target *-*-* } .-2 } end function subroutine quux diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 index 63d77780196..0aae0fe956d 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 @@ -69,10 +69,10 @@ contains !$omp declare variant (f1) match(user={condition(1, 2, 3)}) ! { dg-error "expected '\\)' at .1." } end subroutine subroutine f23 () - !$omp declare variant (f1) match(construct={master}) ! { dg-error "selector 'master' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={master}) ! { dg-warning "unknown selector 'master' for context selector set 'construct'" } end subroutine subroutine f24 () - !$omp declare variant (f1) match(construct={teams,parallel,master,do}) ! { dg-error "selector 'master' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={teams,parallel,master,do}) ! { dg-warning "unknown selector 'master' for context selector set 'construct'" } end subroutine subroutine f25 () !$omp declare variant (f1) match(construct={parallel(1 ! { dg-error "selector 'parallel' does not accept any properties at .1." } @@ -105,10 +105,10 @@ contains !$omp declare variant (f1) match(device={arch(17)}) ! { dg-error "expected identifier or string literal at .1." } end subroutine subroutine f41 () - !$omp declare variant (f1) match(device={foobar(3)}) + !$omp declare variant (f1) match(device={foobar(3)}) ! { dg-warning "unknown selector 'foobar' for context selector set 'device' at .1." } end subroutine subroutine f43 () - !$omp declare variant (f1) match(implementation={foobar(3)}) + !$omp declare variant (f1) match(implementation={foobar(3)}) ! { dg-warning "unknown selector 'foobar' for context selector set 'implementation' at .1." } end subroutine subroutine f44 () !$omp declare variant (f1) match(implementation={vendor}) ! { dg-error "expected '\\(' at .1." } @@ -141,46 +141,46 @@ contains !$omp declare variant (f1) match(implementation={atomic_default_mem_order(relaxed,seq_cst)}) ! { dg-error "expected '\\)' at .1." } end subroutine subroutine f58 () - !$omp declare variant (f1) match(user={foobar(3)}) ! { dg-error "selector 'foobar' not allowed for context selector set 'user' at .1." } + !$omp declare variant (f1) match(user={foobar(3)}) ! { dg-warning "unknown selector 'foobar' for context selector set 'user' at .1." } end subroutine subroutine f59 () - !$omp declare variant (f1) match(construct={foobar(3)}) ! { dg-error "selector 'foobar' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={foobar(3)}) ! { dg-warning "unknown selector 'foobar' for context selector set 'construct' at .1." } end subroutine subroutine f60 () !$omp declare variant (f1) match(construct={parallel},foobar={bar}) ! { dg-error "expected 'construct', 'device', 'implementation' or 'user' at .1." } end subroutine subroutine f64 () - !$omp declare variant (f1) match(construct={single}) ! { dg-error "selector 'single' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={single}) ! { dg-warning "unknown selector 'single' for context selector set 'construct' at .1." } end subroutine subroutine f65 () - !$omp declare variant (f1) match(construct={taskgroup}) ! { dg-error "selector 'taskgroup' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={taskgroup}) ! { dg-warning "unknown selector 'taskgroup' for context selector set 'construct' at .1." } end subroutine subroutine f66 () - !$omp declare variant (f1) match(construct={for}) ! { dg-error "selector 'for' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={for}) ! { dg-warning "unknown selector 'for' for context selector set 'construct' at .1." } end subroutine subroutine f67 () - !$omp declare variant (f1) match(construct={threadprivate}) ! { dg-error "selector 'threadprivate' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={threadprivate}) ! { dg-warning "unknown selector 'threadprivate' for context selector set 'construct' at .1." } end subroutine subroutine f68 () - !$omp declare variant (f1) match(construct={critical}) ! { dg-error "selector 'critical' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={critical}) ! { dg-warning "unknown selector 'critical' for context selector set 'construct' at .1." } end subroutine subroutine f69 () - !$omp declare variant (f1) match(construct={task}) ! { dg-error "selector 'task' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={task}) ! { dg-warning "unknown selector 'task' for context selector set 'construct' at .1." } end subroutine subroutine f70 () - !$omp declare variant (f1) match(construct={taskloop}) ! { dg-error "selector 'taskloop' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={taskloop}) ! { dg-warning "unknown selector 'taskloop' for context selector set 'construct' at .1." } end subroutine subroutine f71 () - !$omp declare variant (f1) match(construct={sections}) ! { dg-error "selector 'sections' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={sections}) ! { dg-warning "unknown selector 'sections' for context selector set 'construct' at .1." } end subroutine subroutine f72 () - !$omp declare variant (f1) match(construct={section}) ! { dg-error "selector 'section' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={section}) ! { dg-warning "unknown selector 'section' for context selector set 'construct' at .1." } end subroutine subroutine f73 () - !$omp declare variant (f1) match(construct={workshare}) ! { dg-error "selector 'workshare' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={workshare}) ! { dg-warning "unknown selector 'workshare' for context selector set 'construct' at .1." } end subroutine subroutine f74 () - !$omp declare variant (f1) match(construct={requires}) ! { dg-error "selector 'requires' not allowed for context selector set 'construct' at .1." } + !$omp declare variant (f1) match(construct={requires}) ! { dg-warning "unknown selector 'requires' for context selector set 'construct' at .1." } end subroutine subroutine f75 () !$omp declare variant (f1),match(construct={parallel}) ! { dg-error "expected 'match' at .1." } From patchwork Thu Dec 7 15:52:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1873282 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SmJjb2ybXz1ySY for ; Fri, 8 Dec 2023 02:54:11 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 56376385C422 for ; Thu, 7 Dec 2023 15:54:09 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) by sourceware.org (Postfix) with ESMTPS id CB6BF3860C2C for ; Thu, 7 Dec 2023 15:53:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CB6BF3860C2C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CB6BF3860C2C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.137.180 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964429; cv=none; b=Wr7KuHXk/nnwlhD2K7ZCIKlRwKTrnQUmBCxRNYiXiaWvcS940inT206brKtrDZqvDjBMMM2iktAbCZwTXYbKNv3HHtVvT/6J/2gOm1b88EmMIvNE4E6kuKUeMiWFAcq3ovJJY1W5ORj3AuZbAZNS+q2uG8l5dUecDiHcfCUyX8U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701964429; c=relaxed/simple; bh=5QQ9Y64wltxJjD07foCYg19WoK2kAGxY+iNBvFOkTDs=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=P2Bh5yg4sdLxBGOX6Y8jld58D2SOYu+LKgtNUuwv0nx5JYfPnom5SPs/TrZVKI6fq7oWfMl687UVtwmDatFe2p0H1KLPErANG2UOJEM2XcC0M2rWv2/gtzsJCj7Ghz2xhOf7O+N1RdvrufgIYrvvoZaUJ3cVj/DIBEKp00+dE/E= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: YUWxDdx7QcOciOeh9n+6Xw== X-CSE-MsgGUID: 02RoNpD/Sj++WmO8dEwk4g== X-IronPort-AV: E=Sophos;i="6.04,256,1695715200"; d="scan'208";a="24734415" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa3.mentor.iphmx.com with ESMTP; 07 Dec 2023 07:53:46 -0800 IronPort-SDR: jZAraNqq6KmSAkOYRgrdTxGZPLXn8piVuXoelxGam2IXKxgG1lIzcuUis9PYzY2AL4Cd3vsJoH Zar1mcWWp1bXpaqdVvorzrRLfdxRUovEVPvL/4FQIASYxPbXRpRgfgPuA45NdbtdxpQ0AHFf93 zApcAnRsxe2vBzKyonY6HCxeRlIpV/kt91AIjLG/XDTYFeiiQtWHp1vE1otH90UWy6itQJZjtl Lm7G+ogUh4UPrbCgefI4l/Sk6cNv0kiu550GvymLEhJiAvgKOgDo9M/0R79jJ+DCvY2SzfekJi Zek= From: Sandra Loosemore To: CC: , , Subject: [PATCH V3 4/4] OpenMP: Permit additional selector properties Date: Thu, 7 Dec 2023 08:52:47 -0700 Message-ID: <20231207155247.372718-5-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207155247.372718-1-sandra@codesourcery.com> References: <20231207155247.372718-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: svr-orw-mbx-11.mgc.mentorg.com (147.34.90.211) To svr-orw-mbx-13.mgc.mentorg.com (147.34.90.213) X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org This patch adds "hpe" to the known properties for the "vendor" selector, and support for "acquire" and "release" for "atomic_default_mem_order". gcc/ChangeLog * omp-general.cc (vendor_properties): Add "hpe". (atomic_default_mem_order_properties): Add "acquire" and "release". (omp_context_selector_matches): Handle "acquire" and "release". gcc/testsuite/ChangeLog * c-c++-common/gomp/declare-variant-2.c: Don't expect error on "acquire" and "release". * gfortran.dg/gomp/declare-variant-2a.f90: Likewise. --- gcc/omp-general.cc | 10 ++++++++-- gcc/testsuite/c-c++-common/gomp/declare-variant-2.c | 4 ++-- gcc/testsuite/gfortran.dg/gomp/declare-variant-2a.f90 | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/gcc/omp-general.cc b/gcc/omp-general.cc index 5f0cb041ffa..4f7c83fbd2c 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1126,12 +1126,12 @@ const char *omp_tss_map[] = static const char *const kind_properties[] = { "host", "nohost", "cpu", "gpu", "fpga", "any", NULL }; static const char *const vendor_properties[] = - { "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel", + { "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "hpe", "ibm", "intel", "llvm", "nvidia", "pgi", "ti", "unknown", NULL }; static const char *const extension_properties[] = { NULL }; static const char *const atomic_default_mem_order_properties[] = - { "seq_cst", "relaxed", "acq_rel", NULL }; + { "seq_cst", "relaxed", "acq_rel", "acquire", "release", NULL }; struct omp_ts_info omp_ts_map[] = { @@ -1551,6 +1551,12 @@ omp_context_selector_matches (tree ctx) else if (!strcmp (prop, "acq_rel") && omo != OMP_MEMORY_ORDER_ACQ_REL) return 0; + else if (!strcmp (prop, "acquire") + && omo != OMP_MEMORY_ORDER_ACQUIRE) + return 0; + else if (!strcmp (prop, "release") + && omo != OMP_MEMORY_ORDER_RELEASE) + return 0; } break; case OMP_TRAIT_DEVICE_ARCH: diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c index 97285fa3b74..bc3f443379f 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-2.c @@ -105,9 +105,9 @@ void f50 (void); /* { dg-error "expected '\\\}' before '\\(' token" "" { void f51 (void); /* { dg-error "expected '\\\}' before '\\(' token" "" { target c } .-1 } */ #pragma omp declare variant (f1) match(implementation={atomic_default_mem_order}) /* { dg-error "expected '\\(' before '\\\}' token" } */ void f52 (void); -#pragma omp declare variant (f1) match(implementation={atomic_default_mem_order(acquire)}) /* { dg-error "incorrect property 'acquire' of 'atomic_default_mem_order' selector" } */ +#pragma omp declare variant (f1) match(implementation={atomic_default_mem_order(acquire)}) void f53 (void); -#pragma omp declare variant (f1) match(implementation={atomic_default_mem_order(release)}) /* { dg-error "incorrect property 'release' of 'atomic_default_mem_order' selector" } */ +#pragma omp declare variant (f1) match(implementation={atomic_default_mem_order(release)}) void f54 (void); #pragma omp declare variant (f1) match(implementation={atomic_default_mem_order(foobar)}) /* { dg-error "incorrect property 'foobar' of 'atomic_default_mem_order' selector" } */ void f55 (void); diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2a.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2a.f90 index 56de1177789..edc9b27f884 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2a.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2a.f90 @@ -29,10 +29,10 @@ contains !$omp declare variant (f1) match(implementation={vendor("foobar")}) ! { dg-warning "unknown property '.foobar.' of 'vendor' selector" } end subroutine subroutine f53 () - !$omp declare variant (f1) match(implementation={atomic_default_mem_order(acquire)}) ! { dg-error "incorrect property 'acquire' of 'atomic_default_mem_order' selector" } + !$omp declare variant (f1) match(implementation={atomic_default_mem_order(acquire)}) end subroutine subroutine f54 () - !$omp declare variant (f1) match(implementation={atomic_default_mem_order(release)}) ! { dg-error "incorrect property 'release' of 'atomic_default_mem_order' selector" } + !$omp declare variant (f1) match(implementation={atomic_default_mem_order(release)}) end subroutine subroutine f55 () !$omp declare variant (f1) match(implementation={atomic_default_mem_order(foobar)}) ! { dg-error "incorrect property 'foobar' of 'atomic_default_mem_order' selector" }