aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c/c-parser.cc27
-rw-r--r--gcc/cp/parser.cc30
-rw-r--r--gcc/cp/pt.cc82
-rw-r--r--gcc/fortran/trans-openmp.cc27
-rw-r--r--gcc/gimplify.cc4
-rw-r--r--gcc/omp-general.cc293
-rw-r--r--gcc/omp-general.h48
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);