diff options
-rw-r--r-- | gcc/c/c-parser.cc | 27 | ||||
-rw-r--r-- | gcc/cp/parser.cc | 30 | ||||
-rw-r--r-- | gcc/cp/pt.cc | 82 | ||||
-rw-r--r-- | gcc/fortran/trans-openmp.cc | 27 | ||||
-rw-r--r-- | gcc/gimplify.cc | 4 | ||||
-rw-r--r-- | gcc/omp-general.cc | 293 | ||||
-rw-r--r-- | 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 a7dc096..a61381e 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24386,7 +24386,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) @@ -24405,6 +24408,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; @@ -24511,8 +24515,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); } @@ -24525,7 +24528,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); @@ -24536,7 +24540,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; @@ -24554,7 +24559,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 { @@ -24582,7 +24588,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); @@ -24602,7 +24608,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; @@ -24640,7 +24647,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); @@ -24716,7 +24723,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 1e2d520..5a91637 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47432,7 +47432,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) @@ -47451,6 +47454,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; @@ -47557,8 +47561,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 " @@ -47567,8 +47570,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 @@ -47588,7 +47590,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))) @@ -47596,7 +47599,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; @@ -47614,7 +47618,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 { @@ -47643,7 +47648,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); @@ -47663,7 +47668,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; @@ -47698,7 +47704,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); @@ -47780,7 +47786,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 7208c72..a752dcf 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. */ @@ -11888,50 +11889,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"); @@ -11940,20 +11963,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 9c51ac4..55f85d5 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -8403,6 +8403,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; @@ -8416,13 +8417,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: { @@ -8432,7 +8434,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: @@ -8449,17 +8452,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 a6bdcea..f61c8ae 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -14484,8 +14484,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 7f1ad0f..c95873b 100644 --- a/gcc/omp-general.cc +++ b/gcc/omp-general.cc @@ -1019,13 +1019,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")) @@ -1127,38 +1127,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<tree> 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; } } @@ -1179,49 +1181,45 @@ omp_check_context_selector (location_t loc, tree ctx) { "implementation", "extension", extension }, { "implementation", "atomic_default_mem_order", atomic_default_mem_order } }; - for (tree t1 = TREE_VALUE (t); t1; t1 = TREE_CHAIN (t1)) + for (tree ts = OMP_TSS_TRAIT_SELECTORS (tss); ts; ts = TREE_CHAIN (ts)) for (unsigned i = 0; i < ARRAY_SIZE (props); i++) - if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)), + if (!strcmp (IDENTIFIER_POINTER (OMP_TS_ID (ts)), props[i].selector) - && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)), + && !strcmp (IDENTIFIER_POINTER (OMP_TSS_ID (tss)), props[i].set)) - for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2)) + for (tree p = OMP_TS_PROPERTIES (ts); p; p = TREE_CHAIN (p)) for (unsigned j = 0; ; j++) { if (props[i].props[j] == NULL) { - if (TREE_PURPOSE (t2) - && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), - " score")) - break; if (props[i].props == atomic_default_mem_order) { error_at (loc, "incorrect property %qs of %qs selector", - IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + IDENTIFIER_POINTER (TREE_PURPOSE (p)), "atomic_default_mem_order"); return error_mark_node; } - else if (TREE_PURPOSE (t2)) + else if (OMP_TP_NAME (p)) warning_at (loc, OPT_Wopenmp, "unknown property %qs of %qs selector", - IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].selector); else warning_at (loc, OPT_Wopenmp, "unknown property %qE of %qs selector", - TREE_VALUE (t2), props[i].selector); + OMP_TP_VALUE (p), props[i].selector); break; } - else if (TREE_PURPOSE (t2) == NULL_TREE) + else if (OMP_TP_NAME (p) == NULL_TREE) { - const char *str = TREE_STRING_POINTER (TREE_VALUE (t2)); + const char *str = TREE_STRING_POINTER (OMP_TP_VALUE (p)); if (!strcmp (str, props[i].props[j]) - && ((size_t) TREE_STRING_LENGTH (TREE_VALUE (t2)) + && ((size_t) TREE_STRING_LENGTH (OMP_TP_VALUE (p)) == strlen (str) + (lang_GNU_Fortran () ? 0 : 1))) break; } - else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + else if (!strcmp (IDENTIFIER_POINTER (OMP_TP_NAME (p)), props[i].props[j])) break; } @@ -1256,18 +1254,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; @@ -1284,9 +1307,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 @@ -1304,7 +1327,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) { @@ -1335,20 +1359,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; } @@ -1379,13 +1402,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; @@ -1397,9 +1415,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; @@ -1499,9 +1517,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")) @@ -1560,9 +1578,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; @@ -1613,12 +1631,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; } @@ -1749,6 +1767,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. */ @@ -1758,57 +1777,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) @@ -1826,6 +1825,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 @@ -1847,26 +1847,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; } } @@ -1874,9 +1874,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; @@ -1886,16 +1886,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) @@ -1903,7 +1908,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; @@ -1937,15 +1942,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) @@ -1953,7 +1960,7 @@ omp_context_selector_compare (tree ctx1, tree ctx2) cnt++; break; } - if (t2 == NULL_TREE) + if (tss2 == NULL_TREE) { if (ret == -1) return 2; @@ -1976,14 +1983,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; } @@ -2006,25 +2013,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 759e847..4bd187b 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); |