OpenMP: Introduce accessor macros and constructors for context selectors.

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.
This commit is contained in:
Sandra Loosemore 2023-11-19 00:56:47 +00:00
parent 1502d724df
commit 82b32adaa7
7 changed files with 297 additions and 214 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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)
else
{
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"))
/* 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 if (TREE_PURPOSE (t1) == NULL_TREE
&& TREE_PURPOSE (t2)
&& TREE_CODE (TREE_VALUE (t1)) == STRING_CST)
{
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"))
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;

View file

@ -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);