From patchwork Sun Nov 19 09:21:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1865675 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 4SY4t72Fx6z1yS4 for ; Sun, 19 Nov 2023 20:22:39 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 94F4F3858D37 for ; Sun, 19 Nov 2023 09:22:36 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id 988673858429 for ; Sun, 19 Nov 2023 09:22:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 988673858429 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 988673858429 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.141.98 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700385738; cv=none; b=hoyE8tVIVDtk+s0G5tEpjBUg7AOGj02Czt9xUEDUWB+vsX3H/ojQHt4EXsdCjVZzhbh7ZBq9rECOu+AV1x8Djhq4WFHILMNJGGBer/4JMwizk4hHtTxBjwqeCR7ENAOEYWeEN8NVpS2m/0KexvFaoTTwaDx4rOT917lXLZ/kLdc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700385738; c=relaxed/simple; bh=B3uRdQeDLUwyS5qDnI6wU7Ekdlg8XF0PL1lNT70thb0=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=Z5QY/zRoa+DlfZ2SR42htsRaA4+WJtCAvo4CaY9Y/eVIkzmW2e9ydQGDRpFX9ihVn/aUPCgqGfsRf25iB/gvR/XhIM6KOM/pRvdGAlputPUjROMbAMtPR+AKYlqv4ruDlbdGp58Q0sRUo30Vzx5LShw5rRCptRPZRxX5sAXn1Tc= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: OdRzRXg+SByqE3fFsDVcxA== X-CSE-MsgGUID: o1dW4DqiRlCokGthdg4sBQ== X-IronPort-AV: E=Sophos;i="6.04,210,1695715200"; d="scan'208";a="25919867" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa2.mentor.iphmx.com with ESMTP; 19 Nov 2023 01:22:12 -0800 IronPort-SDR: w+qjJX0/NJs9q5Ix/d48ihB9kfs39uJnNX+qOmBNR6E60g3DrlqiqNFUtKTs6ln/KFsyrxpnYD 3Ls7nzYKdFrm9x7WRd+YobrzEdL+OPEWrBMLXK29EXdzjTIgiaf3O7JKQIWUmyt/fuBnZLcd/U B+8d1I7PJUgEdbQ7ZRDdPRJyQwWBofeYNo9D7ipvgYD/F0fnQvCX44jIDCFmWXYY/rWQBGBMFZ zd4OvtTQPqTVH5lfEJMqL7RQbeNWfznVbxM6AFHiixPDEIv7+mK24R6gr5UCefALkCoAJ5F6rD 3DA= From: Sandra Loosemore To: CC: , Subject: [PATCH 1/3] OpenMP: Introduce accessor macros and constructors for context selectors. Date: Sun, 19 Nov 2023 02:21:49 -0700 Message-ID: <20231119092151.1690294-2-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231119092151.1690294-1-sandra@codesourcery.com> References: <20231119092151.1690294-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: svr-orw-mbx-12.mgc.mentorg.com (147.34.90.212) 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 703f9570dbc..fcbacd461c7 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24032,7 +24032,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) @@ -24051,6 +24054,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; @@ -24157,8 +24161,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); } @@ -24171,7 +24174,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); @@ -24182,7 +24186,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; @@ -24200,7 +24205,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 { @@ -24228,7 +24234,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); @@ -24248,7 +24254,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; @@ -24286,7 +24293,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); @@ -24362,7 +24369,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 d1104336215..dd773570981 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47271,7 +47271,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) @@ -47290,6 +47293,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; @@ -47396,8 +47400,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 " @@ -47406,8 +47409,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 @@ -47427,7 +47429,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))) @@ -47435,7 +47438,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; @@ -47453,7 +47457,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 { @@ -47482,7 +47487,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); @@ -47502,7 +47507,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; @@ -47537,7 +47543,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); @@ -47619,7 +47625,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 324f6f01555..3af793dfe20 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. */ @@ -11841,50 +11842,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"); @@ -11893,20 +11916,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 77f07af6ec5..757654d5434 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -13541,8 +13541,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 b88d5930aab..4ea0d971273 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, 0, "unknown property %qs of %qs selector", - IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].selector); else warning_at (loc, 0, "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 Sun Nov 19 09:21:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1865674 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 4SY4sz4zb4z1yS4 for ; Sun, 19 Nov 2023 20:22:30 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 974E93858C56 for ; Sun, 19 Nov 2023 09:22:28 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id 68B503858418 for ; Sun, 19 Nov 2023 09:22:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 68B503858418 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 68B503858418 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.141.98 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700385738; cv=none; b=iN9zZlYHc+wY7vcJFiEvnlQtR9wHdXc4injR+85LPC1gA0jN+Po8rwLW5yF6WpS8Kl0A3wxh324oPun1X5M+VL2Fa3AuUGZtgXCY3FDHXOOMVmZGK3DKaXJA6azHsOohqtBIELaeCg3yTVcD9iEAFSU7crDdEoqafzsI4ppgxHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700385738; c=relaxed/simple; bh=yd5ebBo/ga+Cu3q3aOVEUMe97JE06TZVDCge6h7YZNo=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=HQnEIwUrbK8Spj2O023oCIcnqPWueFCdJgec4MbScGaIos6yHMpyNS1syM92cXV4YeMqF3iSFjGn9M88YbdOUQfvHXSgh8Ai9Q8J8nWdQZ76Ls0PyCmlseKOqOzImEYc7pCS7qGxMZpg6gXMCzIK1wMsZvntSbkITv23toZlq2c= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: OdRzRXg+SByqE3fFsDVcxA== X-CSE-MsgGUID: 80NIU5sXQVKLgzrlemJo7Q== X-IronPort-AV: E=Sophos;i="6.04,210,1695715200"; d="scan'208";a="25919871" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa2.mentor.iphmx.com with ESMTP; 19 Nov 2023 01:22:15 -0800 IronPort-SDR: cZjjNsKJvXtUfUtK325OibzElrkN5b8PWdv6mgrNq1evSXGwBj//M6tLLb7OAn/OoXqdAzkvgK +loOJ7115/ZjytyIgLGxTopo4eWqPhWrWJg6xhMu+bnCV7XQZxDDzicNVSXqYz2/zvSvQ2HjS5 kJBZbqfjYKPm9FqRFenrFb5BTTYA2O10NDHnTNHpl/cvpTjTKf+kyyVCDtXq1zJ2HyNnbHVRe7 rbphJZEdOL8wTJNsmysV8nhSPdy/wh7+D8TjTtdhDLdNwebwk9BDGaE6ybMOHnxXOzs6XsbO6k +6c= From: Sandra Loosemore To: CC: , Subject: [PATCH 2/3] OpenMP: Unify representation of name-list properties. Date: Sun, 19 Nov 2023 02:21:50 -0700 Message-ID: <20231119092151.1690294-3-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231119092151.1690294-1-sandra@codesourcery.com> References: <20231119092151.1690294-1-sandra@codesourcery.com> MIME-Version: 1.0 X-ClientProxiedBy: svr-orw-mbx-12.mgc.mentorg.com (147.34.90.212) 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 fcbacd461c7..a2ff381e0c1 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24217,11 +24217,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 dd773570981..9030365644d 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47469,11 +47469,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 3af793dfe20..c3815733651 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11892,7 +11892,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 4ea0d971273..e4e3890449e 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, 0, "unknown property %qs of %qs selector", IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].selector); - else - warning_at (loc, 0, - "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 Sun Nov 19 09:21:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 1865677 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 4SY4tp4s5Yz1yS4 for ; Sun, 19 Nov 2023 20:23:14 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3AEF33858C50 for ; Sun, 19 Nov 2023 09:23:12 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa4.mentor.iphmx.com (esa4.mentor.iphmx.com [68.232.137.252]) by sourceware.org (Postfix) with ESMTPS id 93D7538582B0 for ; Sun, 19 Nov 2023 09:22:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 93D7538582B0 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 93D7538582B0 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.137.252 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700385778; cv=none; b=Syz8cUWrmkAVi/9iox3aKR6SPX1ixhua0IPVaHWp5wtK9GnikRze3NXtJVsUUGyYNUj5TmtuLt6/nRjflpmSGZ9d0vTZML5Ggz0rH7Lufx5TGPFpxqFNEMAo+EYr8UZ9pqToyZxGkmQK18h7PRmTBQN0TrJdKn1+pvqRlk/9jVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700385778; c=relaxed/simple; bh=m/W10eSbpzaJTAsNUcPa3bwrW0SHImJVuXg2w03Y7Sg=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=TYVHGe8ibeng+tZsKYfQDXDNmcuaT3Anb5JhSTn+/aAAPG+BiIQSgtNuMwDZKU/XOVlmVh04LGC5SkZddmLSwN6ioA2G4L3cT3YP7vraM3oRqWBV3fBRcMDt03LNIHTWtyEw14N58AJGiWG/dfbOFDM4gUl4PKPZu12YLamMslI= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: wV8LTyrBQsaZS2poGtSMbQ== X-CSE-MsgGUID: 4QwJfrucQg6RTzes8Rewug== X-IronPort-AV: E=Sophos;i="6.04,210,1695715200"; d="scan'208";a="23139065" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa4.mentor.iphmx.com with ESMTP; 19 Nov 2023 01:22:50 -0800 IronPort-SDR: Pivq5d4XDZIk2x4MosuFnMAtzHOsROaxHL/X51eh7xXH6ATR9hb99gE7JHqBLx9knFWKfuZNXy qkhR7jlvEVkMkuIwuP5dJ28xnv8UrveNW1HKCQsLIysd22jHnD49xbw9Z4t9uNXu7JTEygOYZu tEqkY4K59BssBbp0Cljy3mpWTjq5W3ukkmH6IzyEb7/4eDDBUcFAxGttvKLtM/pcIqfBaG9YxR /YYytJpYrfpaiUB12VR/e++8caH1H//evMEXreNDlqVt+f9R/WHjHS0XiF9tq5vFW65FCaLCVD 3tQ= From: Sandra Loosemore To: CC: , Subject: [PATCH 3/3] OpenMP: Use enumerators for names of trait-sets and traits Date: Sun, 19 Nov 2023 02:21:51 -0700 Message-ID: <20231119092151.1690294-4-sandra@codesourcery.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231119092151.1690294-1-sandra@codesourcery.com> References: <20231119092151.1690294-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 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. This patch has only been lightly tested and still has at least one bug that causes an ICE. :-( gcc/ChangeLog * omp-general.h (enum omp_tss_code): New. (enum omp_ts_code): New. (enum omp_tp_type): New. (omp_tss_map): New. (struct omp_ts_info): New. (omp_ts_map): New. (OMP_TSS_CODE, OMP_TSS_NAME): New. (OMP_TS_CODE, OMP_TS_NAME): New. (make_trait_set_selector, make_trait_selector): Adjust declarations. (omp_context_selector_set_compare): Likewise. (omp_get_context_selector): Likewise. (omp_get_context_selector_list): New. (omp_lookup_tss_code): New. (omp_lookup_ts_code): New. * omp-general.cc (omp_construct_traits_to_codes): 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): Adjust for new representation. (make_trait_set_selector, make_trait_selector): Adjust for new representations. (omp_context_selector_matches): Simplify dispatch logic, also avoid fix-sized buffers. (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. 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. (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. (cp_parser_omp_context_selector_specification): Likewise. * pt.cc (tsubst_attribute): Adjust for new representations. gcc/fortran/ChangeLog * trans-openmp.cc (gfc_trans_omp_declare_variant): Adjust for new representations. --- gcc/c/c-parser.cc | 192 ++++---------- gcc/cp/decl.cc | 8 +- gcc/cp/parser.cc | 189 ++++---------- gcc/cp/pt.cc | 15 +- gcc/fortran/trans-openmp.cc | 41 ++- gcc/omp-general.cc | 496 +++++++++++++++++++++++------------- gcc/omp-general.h | 87 ++++++- 7 files changed, 555 insertions(+), 473 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index a2ff381e0c1..70c0e1828ca 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24016,16 +24016,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: @@ -24038,7 +24028,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 @@ -24052,80 +24043,52 @@ 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) + /* Some trait sets permit extension traits which are supposed + to be ignored if the implementation doesn't support them. + GCC does not support any extension traits, and if it did, they + would have their own identifiers. */ + if (set == OMP_TRAIT_SET_IMPLEMENTATION + || set == OMP_TRAIT_SET_DEVICE + || set == OMP_TRAIT_SET_TARGET_DEVICE) { - if (allow_user) - { - property_kind = CTX_PROPERTY_USER; - break; - } - else + c_parser_consume_token (parser); + 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)) { - 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; + continue; } + else + break; + } + else + { + error_at (c_parser_peek_token (parser)->location, + "selector %qs not allowed for context selector " + "set %qs", IDENTIFIER_POINTER (selector), + omp_tss_map[set]); + c_parser_consume_token (parser); + return error_mark_node; } - if (i == property_limit) - property_kind = CTX_PROPERTY_NONE; - if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0) - 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", @@ -24168,38 +24131,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)) { @@ -24214,7 +24146,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; @@ -24244,12 +24176,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 " @@ -24261,7 +24195,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 % " @@ -24286,15 +24222,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); @@ -24328,35 +24264,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 %<=%>")) @@ -24453,7 +24371,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 " @@ -24474,7 +24393,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 b8e1098d482..70693af9cc8 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8042,12 +8042,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; } @@ -8140,7 +8141,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 9030365644d..6f5514d40c9 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47255,16 +47255,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: @@ -47277,7 +47267,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 @@ -47292,78 +47283,53 @@ 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) + /* Some trait sets permit extension traits which are supposed + to be ignored if the implementation doesn't support them. + GCC does not support any extension traits, and if it did, they + would have their own identifiers. */ + if (set == OMP_TRAIT_SET_IMPLEMENTATION + || set == OMP_TRAIT_SET_DEVICE + || set == OMP_TRAIT_SET_TARGET_DEVICE) { - if (allow_user) - { - property_kind = CTX_PROPERTY_USER; - break; - } - else + cp_lexer_consume_token (parser->lexer); + 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)) { - 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; + continue; } + else + break; + } + else + { + error_at (cp_lexer_peek_token (parser->lexer)->location, + "selector %qs not allowed for context selector " + "set %qs", IDENTIFIER_POINTER (selector), + omp_tss_map[set]); + cp_lexer_consume_token (parser->lexer); + return error_mark_node; } - if (i == property_limit) - property_kind = CTX_PROPERTY_NONE; - if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0) - 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)); @@ -47420,38 +47386,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)) { @@ -47466,7 +47401,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; @@ -47497,7 +47432,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) { @@ -47514,7 +47451,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 % " @@ -47536,15 +47475,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); @@ -47580,35 +47519,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 c3815733651..ed51a838f12 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11841,18 +11841,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, @@ -11897,7 +11899,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; @@ -11921,7 +11924,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/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 60154ff3751..08e32636c9f 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -8208,11 +8208,34 @@ gfc_trans_omp_declare_variant (gfc_namespace *ns) { tree selectors = NULL_TREE; gfc_omp_selector *os; + enum omp_tss_code set + = omp_lookup_tss_code (oss->trait_set_selector_name); + 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; + + if (set == OMP_TRAIT_SET_CONSTRUCT + && !(strcmp (os->trait_selector_name, "do"))) + sel = OMP_TRAIT_CONSTRUCT_FOR; + else + sel = omp_lookup_ts_code (set, os->trait_selector_name); + + /* Some trait sets permit extension traits which are supposed + to be ignored if the implementation doesn't support them. + GCC does not support any extension traits, and if it did, + they would have their own identifiers. */ + if (sel == OMP_TRAIT_INVALID + && (set == OMP_TRAIT_SET_IMPLEMENTATION + || set == OMP_TRAIT_SET_DEVICE + || set == OMP_TRAIT_SET_TARGET_DEVICE)) + continue; + + gcc_assert (sel != OMP_TRAIT_INVALID); for (otp = os->properties; otp; otp = otp->next) { @@ -8263,13 +8286,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 +8318,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 +8338,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/omp-general.cc b/gcc/omp-general.cc index e4e3890449e..7c99b73ceec 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1014,28 +1014,26 @@ omp_max_simt_vf (void) } /* Store the construct selectors as tree codes from last to first, - return their number. */ + return their number. CTX is a list of trait selectors and + CONSTRUCTS holds the output. */ int omp_construct_traits_to_codes (tree ctx, 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; @@ -1114,6 +1112,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,112 +1261,92 @@ 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); + + /* 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, 0, + "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, 0, + "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, 0, + "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, 0, - "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; } @@ -1275,7 +1371,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 +1382,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 +1419,8 @@ 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); + 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 +1435,12 @@ omp_context_selector_matches (tree ctx) continue; } - enum tree_code constructs[5]; + tree selectors = OMP_TSS_TRAIT_SELECTORS (tss); + enum tree_code *constructs + = (enum tree_code *) alloca (list_length (selectors) + * sizeof (enum tree_code)); int nconstructs - = omp_construct_traits_to_codes (OMP_TSS_TRAIT_SELECTORS (tss), - constructs); + = omp_construct_traits_to_codes (selectors, constructs); if (cfun && (cfun->curr_properties & PROP_gimple_any) != 0) { @@ -1371,11 +1473,11 @@ omp_context_selector_matches (tree ctx) } for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); 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 +1488,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 +1526,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 +1565,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 +1578,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 +1594,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 +1610,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 +1625,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 +1688,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 +1741,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 +1884,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 +1898,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,7 +1946,7 @@ 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) { bool swapped = false; int ret = 0; @@ -1855,18 +1959,17 @@ 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 +2001,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 +2057,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 +2088,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,10 +2145,14 @@ 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 construct + = 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)) @@ -2035,15 +2167,17 @@ omp_context_compute_score (tree ctx, score_wide_int *score, bool declare_simd) if (construct || has_kind || has_arch || has_isa) { - int scores[12]; - enum tree_code constructs[5]; - int nconstructs = 0; + int nconstructs = construct ? list_length (construct) : 1; + enum tree_code *constructs + = (enum tree_code *) alloca (nconstructs * sizeof (enum tree_code)); if (construct) nconstructs = omp_construct_traits_to_codes (construct, constructs); + int b = declare_simd ? nconstructs + 1 : 0; + int *scores + = (int *) alloca ((b + nconstructs + 3) * sizeof (int)); if (omp_construct_selector_matches (constructs, nconstructs, scores) == 2) ret = true; - int b = declare_simd ? nconstructs + 1 : 0; if (scores[b + nconstructs] + 4U < score->get_precision ()) { for (int n = 0; n < nconstructs; ++n) diff --git a/gcc/omp-general.h b/gcc/omp-general.h index dc5e5f6ba1f..ecdd9aa9022 100644 --- a/gcc/omp-general.h +++ b/gcc/omp-general.h @@ -135,8 +135,83 @@ 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); +/* Data structures for context selectors. */ + +/* 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[]; + +#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); @@ -158,8 +233,12 @@ 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 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 *); 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);