OpenMP: Add declare variant's 'append_args' clause in C/C++
Add the append_args clause of 'declare variant' to C and C++, fix/improve diagnostic for 'interop' clause and 'declare_variant' clauses on the way. Cleanup dispatch handling in gimplify_call_expr a bit and partially handle 'append_args'. (Namely, those parts that do not require libraries calls, i.e. a dispatch construct where the 'device' and 'interop' clause has been specified.) The sorry can be removed once an enum value like omp_ipr_(ompx_gnu_)omp_device_num (cf. OpenMP Spec Issue 4451) has to be added to the runtime side such that omp_get_interop_int returns the device number of an interop object (as passed to dispatch via the interop clause); and a call to GOMP_interop has to be added to create interop objects. Once available, only a very localized change in gimplify_call_expr is required to claim for full support. - And Fortran parsing support. gcc/c-family/ChangeLog: * c-omp.cc (c_omp_interop_t_p): Handle error_mark_node. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_clause_init_modifiers): New; split of from ... (c_parser_omp_clause_init): ... here; call it. (c_finish_omp_declare_variant): Parse 'append_args' clause. (c_parser_omp_clause_interop): Set tree used/read. gcc/cp/ChangeLog: * decl.cc (omp_declare_variant_finalize_one): Handle append_args. * parser.cc (cp_parser_omp_clause_init_modifiers): New; split of from ... (cp_parser_omp_clause_init): ... here; call it. (cp_parser_omp_all_clauses): Replace interop parsing by a call to ... (cp_parser_omp_clause_interop): ... this new function; set tree used/read. (cp_finish_omp_declare_variant): Parse 'append_args' clause. (cp_parser_omp_declare): Update comment. * pt.cc (tsubst_attribute, tsubst_omp_clauses): Handle template substitution also for declare variant's append_args clause, using for 'init' the same code as for interop's init clause. gcc/ChangeLog: * gimplify.cc (gimplify_call_expr): Update for OpenMP's append_args; cleanup of OpenMP's dispatch clause handling. gcc/testsuite/ChangeLog: * c-c++-common/gomp/declare-variant-2.c: Update dg-error msg. * c-c++-common/gomp/dispatch-12.c: Likewise. * c-c++-common/gomp/dispatch-11.c: Likewise and extend a bit. * c-c++-common/gomp/append-args-1.c: New test. * c-c++-common/gomp/append-args-2.c: New test. * c-c++-common/gomp/append-args-3.c: New test. * g++.dg/gomp/append-args-1.C: New test. * g++.dg/gomp/append-args-2.C: New test. * g++.dg/gomp/append-args-3.C: New test.
This commit is contained in:
parent
8479467185
commit
12dd892b1a
15 changed files with 1197 additions and 265 deletions
|
@ -669,6 +669,8 @@ c_finish_omp_atomic (location_t loc, enum tree_code code,
|
|||
bool
|
||||
c_omp_interop_t_p (tree type)
|
||||
{
|
||||
if (type == error_mark_node)
|
||||
return false;
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
return (TREE_CODE (type) == ENUMERAL_TYPE
|
||||
&& TYPE_NAME (type)
|
||||
|
|
|
@ -20630,6 +20630,73 @@ c_parser_omp_modifier_prefer_type (c_parser *parser)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* OpenMP 5.1
|
||||
modifiers of the 'init' clause, used by the 'init' and the
|
||||
'append_args' clauses.
|
||||
|
||||
Modifiers:
|
||||
target
|
||||
targetsync
|
||||
prefer_type (preference-specification)
|
||||
|
||||
Returns 'false' if an error has been issued. */
|
||||
|
||||
static bool
|
||||
c_parser_omp_clause_init_modifiers (c_parser *parser, bool *target,
|
||||
bool *targetsync, tree *prefer_type_tree)
|
||||
{
|
||||
*target = false;
|
||||
*targetsync = false;
|
||||
*prefer_type_tree = NULL_TREE;
|
||||
|
||||
do
|
||||
{
|
||||
c_token *tok = c_parser_peek_token (parser);
|
||||
if (tok->type != CPP_NAME)
|
||||
goto fail;
|
||||
const char *p = IDENTIFIER_POINTER (tok->value);
|
||||
if (strcmp ("targetsync", p) == 0)
|
||||
{
|
||||
if (*targetsync)
|
||||
error_at (tok->location, "duplicate %<targetsync%> modifier");
|
||||
*targetsync = true;
|
||||
c_parser_consume_token (parser);
|
||||
}
|
||||
else if (strcmp ("target", p) == 0)
|
||||
{
|
||||
if (*target)
|
||||
error_at (tok->location, "duplicate %<target%> modifier");
|
||||
*target = true;
|
||||
c_parser_consume_token (parser);
|
||||
}
|
||||
else if (strcmp ("prefer_type", p) == 0)
|
||||
{
|
||||
if (*prefer_type_tree != NULL_TREE)
|
||||
error_at (tok->location, "duplicate %<prefer_type%> modifier");
|
||||
c_parser_consume_token (parser);
|
||||
*prefer_type_tree = c_parser_omp_modifier_prefer_type (parser);
|
||||
if (*prefer_type_tree == error_mark_node)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
tok = c_parser_peek_token (parser);
|
||||
if (tok->type == CPP_COMMA)
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
continue;
|
||||
}
|
||||
/* Unknown token - either done or an error; handle it in the caller. */
|
||||
return true;
|
||||
}
|
||||
while (true);
|
||||
|
||||
fail:
|
||||
c_parser_error (parser, "%<init%> clause with modifier other than "
|
||||
"%<prefer_type%>, %<target%> or %<targetsync%>");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* OpenMP 5.1:
|
||||
init ( [init-modifier-list : ] variable-list )
|
||||
|
||||
|
@ -20647,17 +20714,17 @@ c_parser_omp_clause_init (c_parser *parser, tree list)
|
|||
if (!parens.require_open (parser))
|
||||
return list;
|
||||
|
||||
unsigned pos = 0, raw_pos = 1;
|
||||
unsigned raw_pos = 1;
|
||||
while (c_parser_peek_nth_token_raw (parser, raw_pos)->type == CPP_NAME)
|
||||
{
|
||||
pos++; raw_pos++;
|
||||
raw_pos++;
|
||||
if (c_parser_peek_nth_token_raw (parser, raw_pos)->type == CPP_OPEN_PAREN)
|
||||
{
|
||||
raw_pos++;
|
||||
c_parser_check_balanced_raw_token_sequence (parser, &raw_pos);
|
||||
if (c_parser_peek_nth_token_raw (parser, raw_pos)->type != CPP_CLOSE_PAREN)
|
||||
{
|
||||
pos = 0;
|
||||
raw_pos = 0;
|
||||
break;
|
||||
}
|
||||
raw_pos++;
|
||||
|
@ -20666,10 +20733,9 @@ c_parser_omp_clause_init (c_parser *parser, tree list)
|
|||
break;
|
||||
if (c_parser_peek_nth_token_raw (parser, raw_pos)->type != CPP_COMMA)
|
||||
{
|
||||
pos = 0;
|
||||
raw_pos = 0;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
raw_pos++;
|
||||
}
|
||||
|
||||
|
@ -20677,57 +20743,18 @@ c_parser_omp_clause_init (c_parser *parser, tree list)
|
|||
bool targetsync = false;
|
||||
tree prefer_type_tree = NULL_TREE;
|
||||
|
||||
for (unsigned pos2 = 0; pos2 < pos; ++pos2)
|
||||
if (raw_pos > 1
|
||||
&& (!c_parser_omp_clause_init_modifiers (parser, &target, &targetsync,
|
||||
&prefer_type_tree)
|
||||
|| !c_parser_require (parser, CPP_COLON, "expected %<:%>")))
|
||||
{
|
||||
c_token *tok = c_parser_peek_token (parser);
|
||||
if (tok->type == CPP_COMMA)
|
||||
{
|
||||
c_parser_consume_token (parser);
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *p = IDENTIFIER_POINTER (tok->value);
|
||||
if (strcmp ("targetsync", p) == 0)
|
||||
{
|
||||
if (targetsync)
|
||||
error_at (tok->location, "duplicate %<targetsync%> modifier");
|
||||
targetsync = true;
|
||||
c_parser_consume_token (parser);
|
||||
}
|
||||
else if (strcmp ("target", p) == 0)
|
||||
{
|
||||
if (target)
|
||||
error_at (tok->location, "duplicate %<target%> modifier");
|
||||
target = true;
|
||||
c_parser_consume_token (parser);
|
||||
}
|
||||
else if (strcmp ("prefer_type", p) == 0)
|
||||
{
|
||||
if (prefer_type_tree != NULL_TREE)
|
||||
error_at (tok->location, "duplicate %<prefer_type%> modifier");
|
||||
c_parser_consume_token (parser);
|
||||
prefer_type_tree = c_parser_omp_modifier_prefer_type (parser);
|
||||
if (prefer_type_tree == error_mark_node)
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_parser_error (parser, "%<init%> clause with modifier other than "
|
||||
"%<prefer_type%>, %<target%> or "
|
||||
"%<targetsync%>");
|
||||
parens.skip_until_found_close (parser);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
if (pos)
|
||||
{
|
||||
c_token *tok = c_parser_peek_token (parser);
|
||||
gcc_checking_assert (tok->type == CPP_COLON);
|
||||
c_parser_consume_token (parser);
|
||||
if (prefer_type_tree != error_mark_node)
|
||||
parens.skip_until_found_close (parser);
|
||||
return list;
|
||||
}
|
||||
|
||||
tree nl = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_INIT, list,
|
||||
false);
|
||||
false);
|
||||
parens.skip_until_found_close (parser);
|
||||
|
||||
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||
|
@ -20758,7 +20785,13 @@ static tree
|
|||
c_parser_omp_clause_interop (c_parser *parser, tree list)
|
||||
{
|
||||
check_no_duplicate_clause (list, OMP_CLAUSE_INTEROP, "interop");
|
||||
return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_INTEROP, list);
|
||||
tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_INTEROP, list);
|
||||
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||
{
|
||||
TREE_USED (OMP_CLAUSE_DECL (c)) = 1;
|
||||
DECL_READ_P (OMP_CLAUSE_DECL (c)) = 1;
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
|
||||
/* Parse all OpenACC clauses. The set clauses allowed by the directive
|
||||
|
@ -26322,7 +26355,7 @@ check_clauses:
|
|||
|
||||
OpenMP 5.1
|
||||
# pragma omp declare variant (identifier) match(context-selector) \
|
||||
adjust_args(adjust-op:argument-list) new-line
|
||||
adjust_args(adjust-op:argument-list) append_args(interop-list) new-line
|
||||
*/
|
||||
|
||||
#define OMP_DECLARE_SIMD_CLAUSE_MASK \
|
||||
|
@ -26786,10 +26819,15 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
|
||||
parens.require_close (parser);
|
||||
|
||||
tree append_args_tree = NULL_TREE;
|
||||
tree append_args_last;
|
||||
vec<tree> adjust_args_list = vNULL;
|
||||
bool has_match = false, has_adjust_args = false;
|
||||
location_t adjust_args_loc = UNKNOWN_LOCATION;
|
||||
tree need_device_ptr_list = make_node (TREE_LIST);
|
||||
location_t append_args_loc = UNKNOWN_LOCATION;
|
||||
location_t match_loc = UNKNOWN_LOCATION;
|
||||
tree need_device_ptr_list = NULL_TREE;
|
||||
tree ctx = error_mark_node;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -26798,26 +26836,36 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
c_parser_consume_token (parser);
|
||||
|
||||
const char *clause = "";
|
||||
location_t match_loc = c_parser_peek_token (parser)->location;
|
||||
location_t loc = c_parser_peek_token (parser)->location;
|
||||
if (c_parser_next_token_is (parser, CPP_NAME))
|
||||
clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
|
||||
|
||||
enum clause
|
||||
{
|
||||
match,
|
||||
adjust_args
|
||||
adjust_args,
|
||||
append_args
|
||||
} ccode;
|
||||
|
||||
if (strcmp (clause, "match") == 0)
|
||||
ccode = match;
|
||||
{
|
||||
ccode = match;
|
||||
match_loc = loc;
|
||||
}
|
||||
else if (strcmp (clause, "adjust_args") == 0)
|
||||
{
|
||||
ccode = adjust_args;
|
||||
adjust_args_loc = match_loc;
|
||||
adjust_args_loc = loc;
|
||||
}
|
||||
else if (strcmp (clause, "append_args") == 0)
|
||||
{
|
||||
ccode = append_args;
|
||||
append_args_loc = loc;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_parser_error (parser, "expected %<match%> clause");
|
||||
c_parser_error (parser, "expected %<match%>, %<adjust_args%> or "
|
||||
"%<append_args%> clause");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -26834,8 +26882,7 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
if (has_match)
|
||||
error_at (match_loc, "too many %<match%> clauses");
|
||||
has_match = true;
|
||||
tree ctx
|
||||
= c_parser_omp_context_selector_specification (parser, parms);
|
||||
ctx = c_parser_omp_context_selector_specification (parser, parms);
|
||||
if (ctx == error_mark_node)
|
||||
goto fail;
|
||||
ctx = omp_check_context_selector (match_loc, ctx);
|
||||
|
@ -26862,40 +26909,6 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
variant);
|
||||
variant = error_mark_node;
|
||||
}
|
||||
else if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
|
||||
OMP_TRAIT_CONSTRUCT_SIMD))
|
||||
{
|
||||
if (comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
|
||||
{
|
||||
if (TYPE_ARG_TYPES (TREE_TYPE (variant)) == NULL_TREE)
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant))
|
||||
= TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
}
|
||||
else
|
||||
{
|
||||
error_at (token->location,
|
||||
"variant %qD and base %qD have "
|
||||
"incompatible types",
|
||||
variant, fndecl);
|
||||
variant = error_mark_node;
|
||||
}
|
||||
}
|
||||
if (variant != error_mark_node)
|
||||
{
|
||||
C_DECL_USED (variant) = 1;
|
||||
tree construct
|
||||
= omp_get_context_selector_list (ctx,
|
||||
OMP_TRAIT_SET_CONSTRUCT);
|
||||
omp_mark_declare_variant (match_loc, variant, construct);
|
||||
if (omp_context_selector_matches (ctx))
|
||||
{
|
||||
tree attr = tree_cons (get_identifier (
|
||||
"omp declare variant base"),
|
||||
build_tree_list (variant, ctx),
|
||||
DECL_ATTRIBUTES (fndecl));
|
||||
DECL_ATTRIBUTES (fndecl) = attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ccode == adjust_args)
|
||||
|
@ -26912,7 +26925,7 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
c_parser_consume_token (parser); // need_device_ptr
|
||||
c_parser_consume_token (parser); // :
|
||||
|
||||
location_t loc = c_parser_peek_token (parser)->location;
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
tree list
|
||||
= c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_ERROR,
|
||||
NULL_TREE);
|
||||
|
@ -26978,19 +26991,180 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (ccode == append_args)
|
||||
{
|
||||
if (append_args_tree)
|
||||
error_at (append_args_loc, "too many %qs clauses", "append_args");
|
||||
do
|
||||
{
|
||||
location_t loc = c_parser_peek_token (parser)->location;
|
||||
if (!c_parser_next_token_is (parser, CPP_NAME)
|
||||
|| strcmp ("interop",
|
||||
IDENTIFIER_POINTER (
|
||||
c_parser_peek_token (parser)->value)))
|
||||
{
|
||||
error_at (loc, "expected %<interop%>");
|
||||
goto fail;
|
||||
}
|
||||
c_parser_consume_token (parser);
|
||||
|
||||
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
|
||||
goto fail;
|
||||
bool target = false;
|
||||
bool targetsync = false;
|
||||
tree prefer_type_tree = NULL_TREE;
|
||||
if (!c_parser_omp_clause_init_modifiers (parser, &target,
|
||||
&targetsync,
|
||||
&prefer_type_tree)
|
||||
|| !c_parser_require (parser, CPP_CLOSE_PAREN,
|
||||
"expected %<)%> or %<,%>"))
|
||||
goto fail;
|
||||
tree t = build_omp_clause (loc, OMP_CLAUSE_INIT);
|
||||
if (append_args_tree)
|
||||
OMP_CLAUSE_CHAIN (append_args_last) = t;
|
||||
else
|
||||
append_args_tree = append_args_last = t;
|
||||
if (target)
|
||||
OMP_CLAUSE_INIT_TARGET (t) = 1;
|
||||
if (targetsync)
|
||||
OMP_CLAUSE_INIT_TARGETSYNC (t) = 1;
|
||||
if (prefer_type_tree)
|
||||
OMP_CLAUSE_INIT_PREFER_TYPE (t) = prefer_type_tree;
|
||||
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
|
||||
break;
|
||||
if (!c_parser_require (parser, CPP_COMMA, "expected %<)%> or %<,%>"))
|
||||
goto fail;
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
parens.require_close (parser);
|
||||
} while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL));
|
||||
c_parser_skip_to_pragma_eol (parser);
|
||||
|
||||
if (has_adjust_args)
|
||||
if ((ctx != error_mark_node && variant != error_mark_node)
|
||||
&& !omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
|
||||
OMP_TRAIT_CONSTRUCT_SIMD))
|
||||
{
|
||||
bool fail = false;
|
||||
if (append_args_tree
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != NULL_TREE
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (variant)) != NULL_TREE)
|
||||
{
|
||||
int nappend_args = 0;
|
||||
int nbase_args = 0;
|
||||
for (tree t = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
t && TREE_VALUE (t) != void_type_node; t = TREE_CHAIN (t))
|
||||
nbase_args++;
|
||||
for (tree t = append_args_tree; t; t = TREE_CHAIN (t))
|
||||
nappend_args++;
|
||||
|
||||
tree args, arg;
|
||||
args = arg = TYPE_ARG_TYPES (TREE_TYPE (variant));
|
||||
for (int j = 0; j < nbase_args && arg; j++, arg = TREE_CHAIN (arg))
|
||||
args = arg;
|
||||
for (int i = 0; i < nappend_args && arg; i++)
|
||||
arg = TREE_CHAIN (arg);
|
||||
tree saved_args;
|
||||
if (nbase_args)
|
||||
{
|
||||
saved_args = TREE_CHAIN (args);
|
||||
TREE_CHAIN (args) = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
saved_args = args;
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant)) = arg;
|
||||
}
|
||||
if (!comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
|
||||
fail = true;
|
||||
if (nbase_args)
|
||||
TREE_CHAIN (args) = saved_args;
|
||||
else
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant)) = saved_args;
|
||||
arg = saved_args;
|
||||
if (!fail)
|
||||
for (int i = 0; i < nappend_args; i++, arg = TREE_CHAIN (arg))
|
||||
if (!arg || !c_omp_interop_t_p (TREE_VALUE (arg)))
|
||||
{
|
||||
error_at (DECL_SOURCE_LOCATION (variant),
|
||||
"argument %d of %qD must be of %<omp_interop_t%>",
|
||||
nbase_args + i + 1, variant);
|
||||
inform (append_args_loc, "%<append_args%> specified here");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
|
||||
{
|
||||
if (TYPE_ARG_TYPES (TREE_TYPE (variant)) == NULL_TREE
|
||||
&& TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != NULL_TREE)
|
||||
{
|
||||
if (!append_args_tree)
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant))
|
||||
= TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
else
|
||||
{
|
||||
tree new_args = NULL_TREE;
|
||||
tree arg, last_arg = NULL_TREE;
|
||||
for (arg = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
arg && arg != void_type_node; arg = TREE_CHAIN (arg))
|
||||
{
|
||||
if (new_args == NULL_TREE)
|
||||
new_args = last_arg = copy_node (arg);
|
||||
else
|
||||
{
|
||||
TREE_CHAIN (last_arg) = copy_node (arg);
|
||||
last_arg = TREE_CHAIN (last_arg);
|
||||
}
|
||||
}
|
||||
for (tree t3 = append_args_tree; t3; t3 = TREE_CHAIN (t3))
|
||||
{
|
||||
tree type = lookup_name (get_identifier ("omp_interop_t"));
|
||||
type = type ? TREE_TYPE (type) : ptr_type_node;
|
||||
last_arg = tree_cons (NULL_TREE, type, last_arg);
|
||||
}
|
||||
TREE_CHAIN (last_arg) = arg;
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant)) = new_args;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fail = true;
|
||||
}
|
||||
if (fail)
|
||||
{
|
||||
error_at (token->location,
|
||||
"variant %qD and base %qD have incompatible types",
|
||||
variant, fndecl);
|
||||
variant = error_mark_node;
|
||||
}
|
||||
}
|
||||
if (ctx != error_mark_node && variant != error_mark_node)
|
||||
{
|
||||
C_DECL_USED (variant) = 1;
|
||||
tree construct = omp_get_context_selector_list (ctx,
|
||||
OMP_TRAIT_SET_CONSTRUCT);
|
||||
omp_mark_declare_variant (match_loc, variant, construct);
|
||||
if (omp_context_selector_matches (ctx))
|
||||
{
|
||||
tree attr = tree_cons (get_identifier ("omp declare variant base"),
|
||||
build_tree_list (variant, ctx),
|
||||
DECL_ATTRIBUTES (fndecl));
|
||||
DECL_ATTRIBUTES (fndecl) = attr;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_adjust_args || append_args_tree)
|
||||
{
|
||||
if (!has_match)
|
||||
{
|
||||
error_at (adjust_args_loc,
|
||||
"an %<adjust_args%> clause requires a %<match%> clause");
|
||||
error_at (has_adjust_args ? adjust_args_loc : append_args_loc,
|
||||
"an %qs clause requires a %<match%> clause",
|
||||
has_adjust_args ? "adjust_args" : "append_args");
|
||||
}
|
||||
else
|
||||
else if (ctx != error_mark_node && variant != error_mark_node)
|
||||
{
|
||||
tree attr = lookup_attribute ("omp declare variant base",
|
||||
DECL_ATTRIBUTES (fndecl));
|
||||
|
@ -26999,23 +27173,24 @@ c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
|
|||
tree ctx = TREE_VALUE (TREE_VALUE (attr));
|
||||
if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
|
||||
OMP_TRAIT_CONSTRUCT_DISPATCH))
|
||||
error_at (
|
||||
adjust_args_loc,
|
||||
"an %<adjust_args%> clause can only be specified if the "
|
||||
"%<dispatch%> selector of the %<construct%> selector set "
|
||||
"appears in the %<match%> clause");
|
||||
error_at (has_adjust_args ? adjust_args_loc : append_args_loc,
|
||||
"an %qs clause can only be specified if the "
|
||||
"%<dispatch%> selector of the %<construct%> selector "
|
||||
"set appears in the %<match%> clause",
|
||||
has_adjust_args ? "adjust_args" : "append_args");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CHAIN (need_device_ptr_list) != NULL_TREE
|
||||
&& variant != error_mark_node)
|
||||
if ((ctx != error_mark_node && variant != error_mark_node)
|
||||
&& (need_device_ptr_list || append_args_tree))
|
||||
{
|
||||
tree variant_decl = tree_strip_nop_conversions (variant);
|
||||
tree t = build_tree_list (need_device_ptr_list,
|
||||
NULL_TREE /* need_device_addr */);
|
||||
TREE_CHAIN (t) = append_args_tree;
|
||||
DECL_ATTRIBUTES (variant_decl)
|
||||
= tree_cons (get_identifier ("omp declare variant variant adjust_args"),
|
||||
build_tree_list (need_device_ptr_list,
|
||||
NULL_TREE /*need_device_addr */),
|
||||
= tree_cons (get_identifier ("omp declare variant variant args"), t,
|
||||
DECL_ATTRIBUTES (variant_decl));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8473,6 +8473,39 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
|
|||
else
|
||||
vec_safe_push (args, build_zero_cst (TREE_TYPE (parm)));
|
||||
|
||||
unsigned nappend_args = 0;
|
||||
tree append_args_list = TREE_CHAIN (TREE_CHAIN (chain));
|
||||
if (append_args_list)
|
||||
{
|
||||
append_args_list = TREE_VALUE (append_args_list);
|
||||
if (append_args_list)
|
||||
append_args_list = TREE_CHAIN (append_args_list);
|
||||
for (tree t = append_args_list; t; t = TREE_CHAIN (t))
|
||||
nappend_args++;
|
||||
if (nappend_args)
|
||||
{
|
||||
tree type;
|
||||
if ((type = lookup_qualified_name (current_scope (),
|
||||
"omp_interop_t",
|
||||
LOOK_want::NORMAL,
|
||||
/*complain*/false)) == NULL_TREE
|
||||
|| !c_omp_interop_t_p (TREE_TYPE (type)))
|
||||
{
|
||||
variant = tree_strip_any_location_wrapper (variant);
|
||||
if (TREE_CODE (variant) == OVERLOAD && OVL_SINGLE_P (variant))
|
||||
variant = OVL_FIRST (variant);
|
||||
error_at (EXPR_LOC_OR_LOC (variant, DECL_SOURCE_LOCATION (variant)),
|
||||
"argument %d of %qE must be of %<omp_interop_t%>",
|
||||
args->length () + 1, variant);
|
||||
inform (OMP_CLAUSE_LOCATION (append_args_list),
|
||||
"%<append_args%> specified here");
|
||||
return true;
|
||||
}
|
||||
for (unsigned i = 0; i < nappend_args; i++)
|
||||
vec_safe_push (args, build_zero_cst (TREE_TYPE (type)));
|
||||
}
|
||||
}
|
||||
|
||||
bool koenig_p = false;
|
||||
if (idk == CP_ID_KIND_UNQUALIFIED || idk == CP_ID_KIND_TEMPLATE_ID)
|
||||
{
|
||||
|
@ -8522,8 +8555,57 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
|
|||
|
||||
if (variant)
|
||||
{
|
||||
bool fail;
|
||||
const char *varname = IDENTIFIER_POINTER (DECL_NAME (variant));
|
||||
if (!comptypes (TREE_TYPE (decl), TREE_TYPE (variant), 0))
|
||||
if (!nappend_args)
|
||||
fail = !comptypes (TREE_TYPE (decl), TREE_TYPE (variant),
|
||||
COMPARE_STRICT);
|
||||
else
|
||||
{
|
||||
unsigned nbase_args = 0;
|
||||
for (tree t = TYPE_ARG_TYPES (TREE_TYPE (decl));
|
||||
t && TREE_VALUE (t) != void_type_node; t = TREE_CHAIN (t))
|
||||
nbase_args++;
|
||||
tree vargs, varg;
|
||||
vargs = varg = TYPE_ARG_TYPES (TREE_TYPE (variant));
|
||||
for (unsigned i = 0; i < nbase_args && varg;
|
||||
i++, varg = TREE_CHAIN (varg))
|
||||
vargs = varg;
|
||||
for (unsigned i = 0; i < nappend_args && varg; i++)
|
||||
varg = TREE_CHAIN (varg);
|
||||
tree saved_vargs;
|
||||
if (nbase_args)
|
||||
{
|
||||
saved_vargs = TREE_CHAIN (vargs);
|
||||
TREE_CHAIN (vargs) = varg;
|
||||
}
|
||||
else
|
||||
{
|
||||
saved_vargs = vargs;
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant)) = varg;
|
||||
}
|
||||
/* Skip assert check that TYPE_CANONICAL is the same. */
|
||||
fail = !comptypes (TREE_TYPE (decl), TREE_TYPE (variant),
|
||||
COMPARE_STRUCTURAL);
|
||||
if (nbase_args)
|
||||
TREE_CHAIN (vargs) = saved_vargs;
|
||||
else
|
||||
TYPE_ARG_TYPES (TREE_TYPE (variant)) = saved_vargs;
|
||||
varg = saved_vargs;
|
||||
if (!fail && !processing_template_decl)
|
||||
for (unsigned i = 0; i < nappend_args;
|
||||
i++, varg = TREE_CHAIN (varg))
|
||||
if (!varg || !c_omp_interop_t_p (TREE_VALUE (varg)))
|
||||
{
|
||||
error_at (DECL_SOURCE_LOCATION (variant),
|
||||
"argument %d of %qD must be of %<omp_interop_t%>",
|
||||
nbase_args + i + 1, variant);
|
||||
inform (OMP_CLAUSE_LOCATION (append_args_list),
|
||||
"%<append_args%> specified here");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fail)
|
||||
{
|
||||
error_at (varid_loc, "variant %qD and base %qD have incompatible "
|
||||
"types", variant, decl);
|
||||
|
@ -8550,7 +8632,7 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
|
|||
tree adjust_args_list = TREE_CHAIN (TREE_CHAIN (chain));
|
||||
if (adjust_args_list != NULL_TREE)
|
||||
DECL_ATTRIBUTES (variant) = tree_cons (
|
||||
get_identifier ("omp declare variant variant adjust_args"),
|
||||
get_identifier ("omp declare variant variant args"),
|
||||
TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant));
|
||||
}
|
||||
}
|
||||
|
|
287
gcc/cp/parser.cc
287
gcc/cp/parser.cc
|
@ -42427,6 +42427,23 @@ cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
|
|||
return list;
|
||||
}
|
||||
|
||||
/* OpenMP 5.1:
|
||||
interop (var-list) */
|
||||
|
||||
static tree
|
||||
cp_parser_omp_clause_interop (cp_parser *parser, tree list,
|
||||
location_t location)
|
||||
{
|
||||
check_no_duplicate_clause (list, OMP_CLAUSE_INTEROP, "interop", location);
|
||||
tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_INTEROP, list);
|
||||
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||
{
|
||||
TREE_USED (OMP_CLAUSE_DECL (c)) = 1;
|
||||
DECL_READ_P (OMP_CLAUSE_DECL (c)) = 1;
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
|
||||
/* OpenMP 5.0:
|
||||
device_type ( host | nohost | any ) */
|
||||
|
||||
|
@ -42781,6 +42798,73 @@ cp_parser_omp_modifier_prefer_type (cp_parser *parser)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* OpenMP 5.1
|
||||
modifiers of the 'init' clause, used by the 'init' and the
|
||||
'append_args' clauses.
|
||||
|
||||
Modifiers:
|
||||
target
|
||||
targetsync
|
||||
prefer_type (preference-specification)
|
||||
|
||||
Returns 'false' if an error has been issued. */
|
||||
|
||||
static bool
|
||||
cp_parser_omp_clause_init_modifiers (cp_parser *parser, bool *target,
|
||||
bool *targetsync, tree *prefer_type_tree)
|
||||
{
|
||||
*target = false;
|
||||
*targetsync = false;
|
||||
*prefer_type_tree = NULL_TREE;
|
||||
|
||||
do
|
||||
{
|
||||
cp_token *tok = cp_lexer_peek_token (parser->lexer);
|
||||
if (tok->type != CPP_NAME)
|
||||
goto fail;
|
||||
const char *p = IDENTIFIER_POINTER (tok->u.value);
|
||||
if (strcmp ("targetsync", p) == 0)
|
||||
{
|
||||
if (*targetsync)
|
||||
error_at (tok->location, "duplicate %<targetsync%> modifier");
|
||||
*targetsync = true;
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
else if (strcmp ("target", p) == 0)
|
||||
{
|
||||
if (*target)
|
||||
error_at (tok->location, "duplicate %<target%> modifier");
|
||||
*target = true;
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
else if (strcmp ("prefer_type", p) == 0)
|
||||
{
|
||||
if (*prefer_type_tree != NULL_TREE)
|
||||
error_at (tok->location, "duplicate %<prefer_type%> modifier");
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
*prefer_type_tree = cp_parser_omp_modifier_prefer_type (parser);
|
||||
if (*prefer_type_tree == error_mark_node)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
tok = cp_lexer_peek_token (parser->lexer);
|
||||
if (tok->type == CPP_COMMA)
|
||||
{
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
continue;
|
||||
}
|
||||
/* Unknown token - either done or an error; handle it in the caller. */
|
||||
return true;
|
||||
}
|
||||
while (true);
|
||||
|
||||
fail:
|
||||
cp_parser_error (parser, "%<init%> clause with modifier other than "
|
||||
"%<prefer_type%>, %<target%> or %<targetsync%>");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* OpenMP 5.1:
|
||||
init ( [init-modifier-list : ] variable-list )
|
||||
|
||||
|
@ -42795,17 +42879,17 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list)
|
|||
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
|
||||
return list;
|
||||
|
||||
unsigned pos = 0, raw_pos = 1;
|
||||
unsigned raw_pos = 1;
|
||||
while (cp_lexer_peek_nth_token (parser->lexer, raw_pos)->type == CPP_NAME)
|
||||
{
|
||||
pos++; raw_pos++;
|
||||
raw_pos++;
|
||||
if (cp_lexer_peek_nth_token (parser->lexer, raw_pos)->type
|
||||
== CPP_OPEN_PAREN)
|
||||
{
|
||||
unsigned n = cp_parser_skip_balanced_tokens (parser, raw_pos);
|
||||
if (n == raw_pos)
|
||||
{
|
||||
pos = 0;
|
||||
raw_pos = 0;
|
||||
break;
|
||||
}
|
||||
raw_pos = n;
|
||||
|
@ -42814,10 +42898,9 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list)
|
|||
break;
|
||||
if (cp_lexer_peek_nth_token (parser->lexer, raw_pos)->type != CPP_COMMA)
|
||||
{
|
||||
pos = 0;
|
||||
raw_pos = 0;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
raw_pos++;
|
||||
}
|
||||
|
||||
|
@ -42825,54 +42908,17 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list)
|
|||
bool targetsync = false;
|
||||
tree prefer_type_tree = NULL_TREE;
|
||||
|
||||
for (unsigned pos2 = 0; pos2 < pos; ++pos2)
|
||||
if (raw_pos > 1
|
||||
&& (!cp_parser_omp_clause_init_modifiers (parser, &target, &targetsync,
|
||||
&prefer_type_tree)
|
||||
|| !cp_parser_require (parser, CPP_COLON, RT_COLON)))
|
||||
{
|
||||
cp_token *tok = cp_lexer_peek_token (parser->lexer);
|
||||
if (tok->type == CPP_COMMA)
|
||||
{
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
continue;
|
||||
}
|
||||
const char *p = IDENTIFIER_POINTER (tok->u.value);
|
||||
if (strcmp ("targetsync", p) == 0)
|
||||
{
|
||||
if (targetsync)
|
||||
error_at (tok->location, "duplicate %<targetsync%> modifier");
|
||||
targetsync = true;
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
else if (strcmp ("target", p) == 0)
|
||||
{
|
||||
if (target)
|
||||
error_at (tok->location, "duplicate %<target%> modifier");
|
||||
target = true;
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
}
|
||||
else if (strcmp ("prefer_type", p) == 0)
|
||||
{
|
||||
if (prefer_type_tree != NULL_TREE)
|
||||
error_at (tok->location, "duplicate %<prefer_type%> modifier");
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
prefer_type_tree = cp_parser_omp_modifier_prefer_type (parser);
|
||||
if (prefer_type_tree == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_parser_error (parser, "%<init%> clause with modifier other than "
|
||||
"%<prefer_type%>, %<target%> or "
|
||||
"%<targetsync%>");
|
||||
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
|
||||
/*or_comma=*/false,
|
||||
/*consume_paren=*/true);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
if (pos)
|
||||
{
|
||||
gcc_checking_assert (cp_lexer_peek_token (parser->lexer)->type
|
||||
== CPP_COLON);
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
if (prefer_type_tree == error_mark_node)
|
||||
return error_mark_node;
|
||||
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
|
||||
/*or_comma=*/false,
|
||||
/*consume_paren=*/true);
|
||||
return list;
|
||||
}
|
||||
|
||||
tree nl = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_INIT, list,
|
||||
|
@ -42880,11 +42926,11 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list)
|
|||
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||
{
|
||||
if (target)
|
||||
OMP_CLAUSE_INIT_TARGET (c) = 1;
|
||||
OMP_CLAUSE_INIT_TARGET (c) = 1;
|
||||
if (targetsync)
|
||||
OMP_CLAUSE_INIT_TARGETSYNC (c) = 1;
|
||||
OMP_CLAUSE_INIT_TARGETSYNC (c) = 1;
|
||||
if (prefer_type_tree)
|
||||
OMP_CLAUSE_INIT_PREFER_TYPE (c) = prefer_type_tree;
|
||||
OMP_CLAUSE_INIT_PREFER_TYPE (c) = prefer_type_tree;
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
|
@ -43536,10 +43582,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
|
|||
c_name = "use";
|
||||
break;
|
||||
case PRAGMA_OMP_CLAUSE_INTEROP:
|
||||
check_no_duplicate_clause (clauses, OMP_CLAUSE_INTEROP, "interop",
|
||||
token->location);
|
||||
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_INTEROP,
|
||||
clauses);
|
||||
clauses = cp_parser_omp_clause_interop (parser, clauses,
|
||||
token->location);
|
||||
c_name = "interop";
|
||||
break;
|
||||
case PRAGMA_OMP_CLAUSE_DETACH:
|
||||
|
@ -50086,10 +50130,14 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
|
|||
location_t finish_loc = get_finish (varid.get_location ());
|
||||
location_t varid_loc = make_location (caret_loc, start_loc, finish_loc);
|
||||
|
||||
tree append_args_tree = NULL_TREE;
|
||||
tree append_args_last;
|
||||
vec<tree> adjust_args_list = vNULL;
|
||||
bool has_match = false, has_adjust_args = false;
|
||||
location_t adjust_args_loc = UNKNOWN_LOCATION;
|
||||
tree need_device_ptr_list = make_node (TREE_LIST);
|
||||
location_t append_args_loc = UNKNOWN_LOCATION;
|
||||
tree need_device_ptr_list = NULL_TREE;
|
||||
tree ctx = NULL_TREE;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -50106,7 +50154,8 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
|
|||
enum clause
|
||||
{
|
||||
match,
|
||||
adjust_args
|
||||
adjust_args,
|
||||
append_args
|
||||
} ccode;
|
||||
|
||||
if (strcmp (clause, "match") == 0)
|
||||
|
@ -50116,9 +50165,15 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
|
|||
ccode = adjust_args;
|
||||
adjust_args_loc = match_loc;
|
||||
}
|
||||
else if (strcmp (clause, "append_args") == 0)
|
||||
{
|
||||
ccode = append_args;
|
||||
append_args_loc = match_loc;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp_parser_error (parser, "expected %<match%> clause");
|
||||
cp_parser_error (parser, "expected %<match%>, %<adjust_args%> or "
|
||||
"%<append_args%> clause");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -50132,8 +50187,7 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
|
|||
if (has_match)
|
||||
error_at (match_loc, "too many %<match%> clauses");
|
||||
has_match = true;
|
||||
tree ctx
|
||||
= cp_parser_omp_context_selector_specification (parser, true);
|
||||
ctx = cp_parser_omp_context_selector_specification (parser, true);
|
||||
if (ctx == error_mark_node)
|
||||
goto fail;
|
||||
ctx = omp_check_context_selector (match_loc, ctx);
|
||||
|
@ -50239,40 +50293,95 @@ cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
|
|||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (ccode == append_args)
|
||||
{
|
||||
if (append_args_tree)
|
||||
error_at (append_args_loc, "too many %qs clauses", "append_args");
|
||||
do
|
||||
{
|
||||
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
|
||||
if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME)
|
||||
|| strcmp ("interop",
|
||||
IDENTIFIER_POINTER (
|
||||
cp_lexer_peek_token (parser->lexer)->u.value)))
|
||||
{
|
||||
error_at (loc, "expected %<interop%>");
|
||||
goto fail;
|
||||
}
|
||||
cp_lexer_consume_token (parser->lexer); // :
|
||||
|
||||
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
|
||||
goto fail;
|
||||
bool target = false;
|
||||
bool targetsync = false;
|
||||
tree prefer_type_tree = NULL_TREE;
|
||||
if (!cp_parser_omp_clause_init_modifiers (parser, &target,
|
||||
&targetsync,
|
||||
&prefer_type_tree))
|
||||
goto fail;
|
||||
tree t = build_omp_clause (loc, OMP_CLAUSE_INIT);
|
||||
if (append_args_tree)
|
||||
OMP_CLAUSE_CHAIN (append_args_last) = t;
|
||||
else
|
||||
append_args_tree = append_args_last = t;
|
||||
if (target)
|
||||
OMP_CLAUSE_INIT_TARGET (t) = 1;
|
||||
if (targetsync)
|
||||
OMP_CLAUSE_INIT_TARGETSYNC (t) = 1;
|
||||
if (prefer_type_tree)
|
||||
OMP_CLAUSE_INIT_PREFER_TYPE (t) = prefer_type_tree;
|
||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
|
||||
{
|
||||
cp_parser_error (parser, "expected %<)%> or %<,%>");
|
||||
goto fail;
|
||||
}
|
||||
cp_lexer_consume_token (parser->lexer); // ')'
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
|
||||
{
|
||||
cp_lexer_consume_token (parser->lexer); // ','
|
||||
break;
|
||||
}
|
||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
|
||||
{
|
||||
cp_parser_error (parser, "expected %<)%> or %<,%>");
|
||||
goto fail;
|
||||
}
|
||||
cp_lexer_consume_token (parser->lexer); // ','
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
} while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL));
|
||||
|
||||
if (has_adjust_args)
|
||||
if ((ctx != error_mark_node && variant != error_mark_node)
|
||||
&& (has_adjust_args || append_args_tree))
|
||||
{
|
||||
if (!has_match)
|
||||
{
|
||||
error_at (adjust_args_loc,
|
||||
"an %<adjust_args%> clause requires a %<match%> clause");
|
||||
error_at (has_adjust_args ? adjust_args_loc : append_args_loc,
|
||||
"an %qs clause requires a %<match%> clause",
|
||||
has_adjust_args ? "adjust_args" : "append_args");
|
||||
}
|
||||
else
|
||||
{
|
||||
tree ctx = TREE_VALUE (TREE_VALUE (attrs));
|
||||
gcc_assert (TREE_PURPOSE (attrs)
|
||||
== get_identifier ("omp declare variant base"));
|
||||
gcc_assert (TREE_PURPOSE (TREE_VALUE (attrs)) == variant);
|
||||
ctx = TREE_VALUE (TREE_VALUE (attrs));
|
||||
if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
|
||||
OMP_TRAIT_CONSTRUCT_DISPATCH))
|
||||
error_at (
|
||||
adjust_args_loc,
|
||||
"an %<adjust_args%> clause can only be specified if the "
|
||||
"%<dispatch%> selector of the construct selector set appears "
|
||||
"in the %<match%> clause");
|
||||
else if (TREE_CHAIN (need_device_ptr_list) != NULL_TREE)
|
||||
{
|
||||
// We might not have a DECL for the variant yet. So we store the
|
||||
// need_device_ptr list in the base function attribute, after loc
|
||||
// nodes.
|
||||
gcc_assert (TREE_PURPOSE (attrs)
|
||||
== get_identifier ("omp declare variant base"));
|
||||
gcc_assert (TREE_PURPOSE (TREE_VALUE (attrs)) == variant);
|
||||
TREE_VALUE (attrs) = chainon (
|
||||
TREE_VALUE (attrs),
|
||||
build_tree_list (
|
||||
NULL_TREE,
|
||||
build_tree_list (need_device_ptr_list,
|
||||
NULL_TREE /*need_device_addr */)));
|
||||
}
|
||||
error_at (has_adjust_args ? adjust_args_loc : append_args_loc,
|
||||
"an %qs clause can only be specified if the %<dispatch%> "
|
||||
"selector of the construct selector set appears "
|
||||
"in the %<match%> clause",
|
||||
has_adjust_args ? "adjust_args" : "append_args");
|
||||
// We might not have a DECL for the variant yet. So we store the
|
||||
// need_device_ptr list in the base function attribute, after loc
|
||||
// nodes.
|
||||
tree t = build_tree_list (need_device_ptr_list,
|
||||
NULL_TREE /* need_device_addr */);
|
||||
TREE_CHAIN (t) = append_args_tree;
|
||||
TREE_VALUE (attrs) = chainon (TREE_VALUE (attrs),
|
||||
build_tree_list ( NULL_TREE, t));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51319,7 +51428,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
|
|||
|
||||
OpenMP 5.1
|
||||
#pragma omp declare variant (identifier) match (context-selector) \
|
||||
adjust_args (adjust-op:argument-list) */
|
||||
adjust_args (adjust-op:argument-list) append_args(interop-list) */
|
||||
|
||||
static bool
|
||||
cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
|
||||
|
|
11
gcc/cp/pt.cc
11
gcc/cp/pt.cc
|
@ -12094,6 +12094,15 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
|
|||
tree chain = TREE_CHAIN (val);
|
||||
location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain));
|
||||
tree ctx = copy_list (TREE_VALUE (val));
|
||||
tree append_args_list = TREE_CHAIN (TREE_CHAIN (chain));
|
||||
if (append_args_list)
|
||||
{
|
||||
append_args_list = TREE_VALUE (append_args_list);
|
||||
if (append_args_list)
|
||||
TREE_CHAIN (append_args_list)
|
||||
= tsubst_omp_clauses (TREE_CHAIN (append_args_list),
|
||||
C_ORT_OMP_DECLARE_SIMD, args, complain, in_decl);
|
||||
}
|
||||
for (tree tss = ctx; tss; tss = TREE_CHAIN (tss))
|
||||
{
|
||||
enum omp_tss_code set = OMP_TSS_CODE (tss);
|
||||
|
@ -17916,7 +17925,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
|
|||
complain, in_decl);
|
||||
break;
|
||||
case OMP_CLAUSE_INIT:
|
||||
if (ort == C_ORT_OMP_INTEROP
|
||||
if ((ort == C_ORT_OMP_INTEROP || ort == C_ORT_OMP_DECLARE_SIMD)
|
||||
&& OMP_CLAUSE_INIT_PREFER_TYPE (nc)
|
||||
&& TREE_CODE (OMP_CLAUSE_INIT_PREFER_TYPE (nc)) == TREE_LIST
|
||||
&& (OMP_CLAUSE_CHAIN (nc) == NULL_TREE
|
||||
|
|
162
gcc/gimplify.cc
162
gcc/gimplify.cc
|
@ -4096,24 +4096,126 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
|||
vars there. */
|
||||
bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
|
||||
|
||||
tree dispatch_device_num = NULL_TREE;
|
||||
tree dispatch_interop = NULL_TREE;
|
||||
tree dispatch_append_args = NULL_TREE;
|
||||
tree dispatch_adjust_args_list = NULL_TREE;
|
||||
if (flag_openmp
|
||||
&& gimplify_omp_ctxp != NULL
|
||||
&& gimplify_omp_ctxp->code == OMP_DISPATCH
|
||||
&& gimplify_omp_ctxp->clauses
|
||||
&& (dispatch_interop = omp_find_clause (gimplify_omp_ctxp->clauses,
|
||||
OMP_CLAUSE_INTEROP)) != NULL_TREE)
|
||||
/* FIXME: When implementing 'append_args, use the 'device_num' of
|
||||
the argument. */
|
||||
error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
|
||||
"number of list items in %<interop%> clause exceeds number of "
|
||||
"%<append_args%> items for %<declare variant%> candidate %qD",
|
||||
fndecl);
|
||||
&& !gimplify_omp_ctxp->in_call_args
|
||||
&& EXPR_P (CALL_EXPR_FN (*expr_p))
|
||||
&& DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0)))
|
||||
{
|
||||
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0);
|
||||
dispatch_adjust_args_list
|
||||
= lookup_attribute ("omp declare variant variant args",
|
||||
DECL_ATTRIBUTES (fndecl));
|
||||
if (dispatch_adjust_args_list)
|
||||
{
|
||||
dispatch_adjust_args_list = TREE_VALUE (dispatch_adjust_args_list);
|
||||
dispatch_append_args = TREE_CHAIN (dispatch_adjust_args_list);
|
||||
if (TREE_PURPOSE (dispatch_adjust_args_list) == NULL_TREE
|
||||
&& TREE_VALUE (dispatch_adjust_args_list) == NULL_TREE)
|
||||
dispatch_adjust_args_list = NULL_TREE;
|
||||
}
|
||||
dispatch_device_num = omp_find_clause (gimplify_omp_ctxp->clauses,
|
||||
OMP_CLAUSE_DEVICE);
|
||||
if (dispatch_device_num)
|
||||
dispatch_device_num = OMP_CLAUSE_DEVICE_ID (dispatch_device_num);
|
||||
if (gimplify_omp_ctxp->clauses)
|
||||
dispatch_interop = omp_find_clause (gimplify_omp_ctxp->clauses,
|
||||
OMP_CLAUSE_INTEROP);
|
||||
/* Already processed? */
|
||||
if (dispatch_interop
|
||||
&& OMP_CLAUSE_DECL (dispatch_interop) == NULL_TREE)
|
||||
dispatch_interop = dispatch_append_args = NULL_TREE;
|
||||
|
||||
int nappend = 0, ninterop = 0;
|
||||
for (tree t = dispatch_append_args; t; t = TREE_CHAIN (t))
|
||||
nappend++;
|
||||
if (dispatch_interop)
|
||||
{
|
||||
for (tree t = dispatch_interop; t; t = TREE_CHAIN (t))
|
||||
if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
|
||||
ninterop++;
|
||||
if (nappend < ninterop)
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
|
||||
"number of list items in %<interop%> clause (%d) "
|
||||
"exceeds the number of %<append_args%> items (%d) for "
|
||||
"%<declare variant%> candidate %qD",
|
||||
ninterop, nappend, fndecl);
|
||||
inform (dispatch_append_args
|
||||
? OMP_CLAUSE_LOCATION (dispatch_append_args)
|
||||
: DECL_SOURCE_LOCATION (fndecl),
|
||||
"%<declare variant%> candidate %qD declared here",
|
||||
fndecl);
|
||||
}
|
||||
/* FIXME: obtain the device_number from 1st 'interop' clause item. */
|
||||
}
|
||||
if (dispatch_append_args && (nappend != ninterop || !dispatch_device_num))
|
||||
{
|
||||
sorry_at (OMP_CLAUSE_LOCATION (dispatch_append_args),
|
||||
"%<append_args%> clause not yet supported for %qD", fndecl);
|
||||
inform (gimplify_omp_ctxp->location,
|
||||
"required by %<dispatch%> construct");
|
||||
}
|
||||
else if (dispatch_append_args)
|
||||
{
|
||||
// Append interop objects
|
||||
int last_arg = 0;
|
||||
for (tree t = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
t && TREE_VALUE(t) != void_type_node; t = TREE_CHAIN (t))
|
||||
last_arg++;
|
||||
last_arg = last_arg - nappend;
|
||||
|
||||
int nvariadic = nargs - last_arg;
|
||||
nargs = last_arg + nappend + nvariadic;
|
||||
tree *buffer = XALLOCAVEC (tree, nargs);
|
||||
int i;
|
||||
for (i = 0; i < last_arg; i++)
|
||||
buffer[i] = CALL_EXPR_ARG (*expr_p, i);
|
||||
int j = nappend;
|
||||
for (tree t = dispatch_interop;
|
||||
t; t = TREE_CHAIN (t))
|
||||
if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
|
||||
buffer[i + --j] = OMP_CLAUSE_DECL (t);
|
||||
i += nappend;
|
||||
for (j = last_arg; j < last_arg + nvariadic; j++)
|
||||
buffer[i++] = CALL_EXPR_ARG (*expr_p, j);
|
||||
tree call = *expr_p;
|
||||
*expr_p = build_call_array_loc (loc, TREE_TYPE (call),
|
||||
CALL_EXPR_FN (call),
|
||||
nargs, buffer);
|
||||
|
||||
/* Copy all CALL_EXPR flags. */
|
||||
CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
|
||||
CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
|
||||
CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
|
||||
= CALL_EXPR_RETURN_SLOT_OPT (call);
|
||||
CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
|
||||
SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
|
||||
CALL_EXPR_VA_ARG_PACK (*expr_p) = CALL_EXPR_VA_ARG_PACK (call);
|
||||
|
||||
/* Mark as already processed. */
|
||||
if (dispatch_interop)
|
||||
OMP_CLAUSE_DECL (dispatch_interop) = NULL_TREE;
|
||||
else
|
||||
{
|
||||
tree t = build_omp_clause (loc, OMP_CLAUSE_INTEROP);
|
||||
TREE_CHAIN (t) = gimplify_omp_ctxp->clauses;
|
||||
gimplify_omp_ctxp->clauses = t;
|
||||
}
|
||||
|
||||
/* Re-run. */
|
||||
return GS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Gimplify the function arguments. */
|
||||
if (nargs > 0)
|
||||
{
|
||||
tree device_num = NULL_TREE;
|
||||
for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
|
||||
PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
|
||||
PUSH_ARGS_REVERSED ? i-- : i++)
|
||||
|
@ -4125,18 +4227,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
|||
if ((i != 1) || !builtin_va_start_p)
|
||||
{
|
||||
tree *arg_p = &CALL_EXPR_ARG (*expr_p, i);
|
||||
tree adjust_args_list;
|
||||
if (flag_openmp && gimplify_omp_ctxp != NULL
|
||||
&& gimplify_omp_ctxp->code == OMP_DISPATCH
|
||||
&& !gimplify_omp_ctxp->in_call_args
|
||||
&& !integer_zerop (*arg_p)
|
||||
&& EXPR_P (CALL_EXPR_FN (*expr_p))
|
||||
&& DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))
|
||||
&& (adjust_args_list = lookup_attribute (
|
||||
"omp declare variant variant adjust_args",
|
||||
DECL_ATTRIBUTES (
|
||||
TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))))
|
||||
!= NULL_TREE)
|
||||
if (dispatch_adjust_args_list && !integer_zerop (*arg_p))
|
||||
{
|
||||
tree arg_types = TYPE_ARG_TYPES (
|
||||
TREE_TYPE (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0)));
|
||||
|
@ -4150,10 +4241,10 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
|||
bool need_device_addr = false;
|
||||
for (int need_addr = 0; need_addr <= 1; need_addr++)
|
||||
for (tree arg = need_addr
|
||||
? TREE_VALUE (TREE_VALUE (
|
||||
adjust_args_list))
|
||||
: TREE_PURPOSE (TREE_VALUE (
|
||||
adjust_args_list));
|
||||
? TREE_VALUE (
|
||||
dispatch_adjust_args_list)
|
||||
: TREE_PURPOSE (
|
||||
dispatch_adjust_args_list);
|
||||
arg != NULL; arg = TREE_CHAIN (arg))
|
||||
{
|
||||
if (TREE_VALUE (arg)
|
||||
|
@ -4204,6 +4295,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
|||
"%<need_device_addr%>",
|
||||
OMP_CLAUSE_DECL (c));
|
||||
is_device_ptr = true;
|
||||
break;
|
||||
}
|
||||
else if (decl1 == decl2)
|
||||
{
|
||||
|
@ -4217,36 +4309,36 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
|||
"%<need_device_ptr%>",
|
||||
OMP_CLAUSE_DECL (c));
|
||||
has_device_addr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE)
|
||||
device_num = OMP_CLAUSE_OPERAND (c, 0);
|
||||
}
|
||||
|
||||
if ((need_device_ptr && !is_device_ptr)
|
||||
|| (need_device_addr && !has_device_addr))
|
||||
{
|
||||
if (device_num == NULL_TREE)
|
||||
if (dispatch_device_num == NULL_TREE)
|
||||
{
|
||||
// device_num = omp_get_default_device ()
|
||||
tree fn = builtin_decl_explicit (
|
||||
BUILT_IN_OMP_GET_DEFAULT_DEVICE);
|
||||
gcall *call = gimple_build_call (fn, 0);
|
||||
device_num = create_tmp_var (
|
||||
dispatch_device_num = create_tmp_var (
|
||||
gimple_call_return_type (call));
|
||||
gimple_call_set_lhs (call, device_num);
|
||||
gimple_call_set_lhs (call,
|
||||
dispatch_device_num);
|
||||
gimplify_seq_add_stmt (pre_p, call);
|
||||
}
|
||||
|
||||
// mapped_arg = omp_get_mapped_ptr (arg,
|
||||
// device_num)
|
||||
// device_num)
|
||||
tree fn = builtin_decl_explicit (
|
||||
BUILT_IN_OMP_GET_MAPPED_PTR);
|
||||
gimplify_arg (arg_p, pre_p, loc);
|
||||
gimplify_arg (&device_num, pre_p, loc);
|
||||
call
|
||||
= gimple_build_call (fn, 2, *arg_p, device_num);
|
||||
gimplify_arg (&dispatch_device_num, pre_p, loc);
|
||||
call = gimple_build_call (fn, 2, *arg_p,
|
||||
dispatch_device_num);
|
||||
tree mapped_arg = create_tmp_var (
|
||||
gimple_call_return_type (call));
|
||||
gimple_call_set_lhs (call, mapped_arg);
|
||||
|
|
83
gcc/testsuite/c-c++-common/gomp/append-args-1.c
Normal file
83
gcc/testsuite/c-c++-common/gomp/append-args-1.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* The following definitions are in omp_lib, which cannot be included
|
||||
in gcc/testsuite/ */
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
|
||||
#else
|
||||
# define __GOMP_UINTPTR_T_ENUM
|
||||
#endif
|
||||
|
||||
typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
|
||||
{
|
||||
omp_interop_none = 0,
|
||||
__omp_interop_t_max__ = __UINTPTR_MAX__
|
||||
} omp_interop_t;
|
||||
|
||||
float repl0(short, short);
|
||||
#pragma omp declare variant(repl0) match(construct={dispatch}) append_args(interop(target), interop(targetsync))
|
||||
float base0();
|
||||
/* { dg-error "argument 1 of 'repl0' must be of 'omp_interop_t'" "" { target c } .-3 } */
|
||||
/* { dg-error "argument 1 of 'float repl0\\(short int, short int\\)' must be of 'omp_interop_t'" "" { target c++ } .-4 } */
|
||||
/* { dg-note "'append_args' specified here" "" { target *-*-* } .-4 } */
|
||||
|
||||
float repl1(omp_interop_t, omp_interop_t);
|
||||
#pragma omp declare variant(repl1) match(construct={dispatch}) append_args(interop(target), interop(targetsync))
|
||||
float base1();
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(omp_interop_t, omp_interop_t\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
void repl2(int *, int *, omp_interop_t, omp_interop_t);
|
||||
#pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y) \
|
||||
append_args(interop(target, targetsync, prefer_type(1)), \
|
||||
interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")})))
|
||||
void base2(int *x, int *y);
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'repl2'" "" { target c } .-3 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl2\\(int\\*, int\\*, omp_interop_t, omp_interop_t\\)'" "" { target c++ } .-4 } */
|
||||
|
||||
void repl3(int, omp_interop_t, ...);
|
||||
#pragma omp declare variant(repl3) match(construct={dispatch}) \
|
||||
append_args(interop(prefer_type("cuda", "hsa")))
|
||||
void base3(int, ...);
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'repl3'" "" { target c } .-2 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl3\\(int, omp_interop_t, \\.\\.\\.\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-note "'declare variant' candidate 'repl3' declared here" "" { target c } .-4 } */
|
||||
/* { dg-note "'declare variant' candidate 'void repl3\\(int, omp_interop_t, \\.\\.\\.\\)' declared here" "" { target c++ } .-5 } */
|
||||
|
||||
float repl4(short, short, omp_interop_t, short);
|
||||
#pragma omp declare variant(repl4) match(construct={dispatch}) append_args(interop(target)) append_args(interop(targetsync)) /* { dg-error "too many 'append_args' clauses" } */
|
||||
float base4(short, short);
|
||||
/* { dg-error "argument 4 of 'repl4' must be of 'omp_interop_t'" "" { target c } .-3 } */
|
||||
/* { dg-error "argument 4 of 'float repl4\\(short int, short int, omp_interop_t, short int\\)' must be of 'omp_interop_t'" "" { target c++ } .-4 } */
|
||||
/* { dg-note "'append_args' specified here" "" { target *-*-* } .-4 } */
|
||||
|
||||
|
||||
float
|
||||
test (int *a, int *b)
|
||||
{
|
||||
omp_interop_t obj1, obj2;
|
||||
float x;
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
x = base1 ();
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
base2 (a, b);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch
|
||||
base3 (5, 1, 2, 3);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop (obj2)
|
||||
base3 (5, 1, 2, 3);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop (obj2, obj1)
|
||||
base3 (5, 1, 2, 3);
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'repl3'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'void repl3\\(int, omp_interop_t, \\.\\.\\.\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-4 } */
|
||||
|
||||
return x;
|
||||
}
|
8
gcc/testsuite/c-c++-common/gomp/append-args-2.c
Normal file
8
gcc/testsuite/c-c++-common/gomp/append-args-2.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* omp_interop_t undefined (on purpose). */
|
||||
|
||||
float repl0(short, short);
|
||||
#pragma omp declare variant(repl0) match(construct={dispatch}) append_args(interop(target), interop(targetsync))
|
||||
float base0();
|
||||
/* { dg-error "argument 1 of 'repl0' must be of 'omp_interop_t'" "" { target c } .-3 } */
|
||||
/* { dg-error "argument 1 of 'repl0' must be of 'omp_interop_t'" "" { target c++ } .-4 } */
|
||||
/* { dg-note "'append_args' specified here" "" { target *-*-* } .-4 } */
|
57
gcc/testsuite/c-c++-common/gomp/append-args-3.c
Normal file
57
gcc/testsuite/c-c++-common/gomp/append-args-3.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* { dg-additional-options "-fdump-tree-gimple -Wall" } */
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
|
||||
#else
|
||||
# define __GOMP_UINTPTR_T_ENUM
|
||||
#endif
|
||||
|
||||
typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
|
||||
{
|
||||
omp_interop_none = 0,
|
||||
__omp_interop_t_max__ = __UINTPTR_MAX__
|
||||
} omp_interop_t;
|
||||
|
||||
|
||||
void g(int, const char *, omp_interop_t, omp_interop_t);
|
||||
#pragma omp declare variant(g) match(construct={dispatch}) append_args(interop(target),interop(targetsync))
|
||||
void f(int x, const char *y);
|
||||
|
||||
void foo()
|
||||
{
|
||||
omp_interop_t obj1; /* { dg-note "'obj1' was declared here" } */
|
||||
omp_interop_t obj2 = omp_interop_none;
|
||||
#pragma omp dispatch device(9) novariants(1)
|
||||
f(2, "abc");
|
||||
#pragma omp dispatch device(5) interop(obj1,obj2)
|
||||
f(3, "cde"); /* { dg-warning "'obj1' is used uninitialized \\\[-Wuninitialized\\\]" } */
|
||||
}
|
||||
|
||||
|
||||
void varvar(int, int, omp_interop_t, omp_interop_t, ...);
|
||||
#pragma omp declare variant(varvar) match(construct={dispatch}) append_args(interop(target),interop(targetsync))
|
||||
void varbase(int x, int y, ...);
|
||||
|
||||
void bar()
|
||||
{
|
||||
omp_interop_t obj3 = omp_interop_none;
|
||||
omp_interop_t obj4; /* { dg-note "'obj4' was declared here" } */
|
||||
#pragma omp dispatch device(3) nocontext(1)
|
||||
varbase(10, 11, 101, 202, 303);
|
||||
#pragma omp dispatch device(7) interop(obj3,obj4)
|
||||
varbase(20, 21, 111, 222, 333); /* { dg-warning "'obj4' is used uninitialized \\\[-Wuninitialized\\\]" } */
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 4 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(9\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(5\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(3\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(7\\);" 1 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(D\.\[0-9\]+\\);" 4 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "f \\(2, \"abc\"\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "g \\(3, \"cde\", obj1, obj2\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "varbase \\(10, 11, 101, 202, 303\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "varvar \\(20, 21, obj3, obj4, 111, 222, 333\\);" 1 "gimple" } } */
|
|
@ -8,9 +8,9 @@ void f3 (void);
|
|||
void f4 (void);
|
||||
#pragma omp declare variant match(user={condition(0)}) /* { dg-error "expected '\\(' before 'match'" } */
|
||||
void f5 (void);
|
||||
#pragma omp declare variant (f1) /* { dg-error "expected 'match' clause before end of line" } */
|
||||
#pragma omp declare variant (f1) /* { dg-error "expected 'match', 'adjust_args' or 'append_args' clause before end of line" } */
|
||||
void f6 (void);
|
||||
#pragma omp declare variant (f1) simd /* { dg-error "expected 'match' clause before 'simd'" } */
|
||||
#pragma omp declare variant (f1) simd /* { dg-error "expected 'match', 'adjust_args' or 'append_args' clause before 'simd'" } */
|
||||
void f7 (void);
|
||||
#pragma omp declare variant (f1) match /* { dg-error "expected '\\(' before end of line" } */
|
||||
void f8 (void);
|
||||
|
|
|
@ -24,6 +24,10 @@ void repl2(int *, int *);
|
|||
#pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y)
|
||||
void base2(int *x, int *y);
|
||||
|
||||
void repl3(int *, int *, omp_interop_t);
|
||||
#pragma omp declare variant(repl3) match(construct={dispatch}) adjust_args(need_device_ptr : y) append_args(interop(target))
|
||||
void base3(int *x, int *y);
|
||||
|
||||
|
||||
float
|
||||
dupl (int *a, int *b)
|
||||
|
@ -33,47 +37,69 @@ dupl (int *a, int *b)
|
|||
|
||||
#pragma omp dispatch interop ( obj1 ) interop(obj2) /* { dg-error "too many 'interop' clauses" } */
|
||||
x = base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1) nocontext(1) interop (obj2 ) /* { dg-error "too many 'interop' clauses" } */
|
||||
base2 (a, b);
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'base2'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'base2'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
|
||||
return x;
|
||||
}
|
||||
|
||||
/* { dg-note "'declare variant' candidate 'repl1' declared here" "" { target c } 19 } */
|
||||
/* { dg-note "'declare variant' candidate 'float repl1\\(\\)' declared here" "" { target c++ } 19 } */
|
||||
/* { dg-note "'declare variant' candidate 'base1' declared here" "" { target c } 21 } */
|
||||
/* { dg-note "'declare variant' candidate 'float base1\\(\\)' declared here" "" { target c++ } 21 } */
|
||||
/* { dg-note "'declare variant' candidate 'repl2' declared here" "" { target c } 23 } */
|
||||
/* { dg-note "'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)' declared here" "" { target c++ } 23 } */
|
||||
/* { dg-note "'declare variant' candidate 'base2' declared here" "" { target c } 25 } */
|
||||
/* { dg-note "'declare variant' candidate 'void base2\\(int\\*, int\\*\\)' declared here" "" { target c++ } 25 } */
|
||||
/* { dg-note "'declare variant' candidate 'repl3' declared here" "" { target c } 28 } */
|
||||
/* { dg-note "'declare variant' candidate 'void repl3\\(int\\*, int\\*, omp_interop_t\\)' declared here" "" { target c++ } 28 } */
|
||||
|
||||
float
|
||||
test (int *a, int *b)
|
||||
{
|
||||
omp_interop_t obj1, obj2;
|
||||
omp_interop_t obj1, obj2, obj3;
|
||||
float x, y;
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
x = base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1, obj1 ) /* Twice the same - should be fine. */
|
||||
x = base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch novariants(1) interop(obj2, obj1)
|
||||
y = base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'base1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'float base1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'base1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float base1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop(obj2, obj1)
|
||||
base2 (a, b);
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl2'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl2'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop(obj2) nocontext(1)
|
||||
base2 (a, b);
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'base2'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'base2'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop(obj3, obj2)
|
||||
base3 (a, b);
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'repl3'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'void repl3\\(int\\*, int\\*, omp_interop_t\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-4 } */
|
||||
|
||||
#pragma omp dispatch interop(obj3)
|
||||
base3 (a, b);
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'repl3'" "" { target c } 28 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl3\\(int\\*, int\\*, omp_interop_t\\)'" "" { target c++ } 28 } */
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-4 } */
|
||||
return x + y;
|
||||
}
|
||||
|
||||
|
@ -82,3 +108,5 @@ test (int *a, int *b)
|
|||
/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj2\\) novariants\\(1\\)\[\\n\\r\]" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "#pragma omp dispatch nocontext\\(1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj2\\) interop\\(obj3\\)\[\\n\\r\]" 1 "original" } } */
|
||||
/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj3\\)\[\\n\\r\]" 1 "original" } } */
|
||||
|
|
|
@ -28,26 +28,26 @@ test ()
|
|||
|
||||
#pragma omp dispatch interop ( obj1, obj2, obj1 ) /* { dg-error "'obj2' must be of 'omp_interop_t'" } */
|
||||
base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(3\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(3\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj3 ) /* { dg-error "'obj3' must be of 'omp_interop_t'" } */
|
||||
base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj2 ) /* { dg-error "'obj2' must be of 'omp_interop_t'" } */
|
||||
base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
|
||||
#pragma omp dispatch interop ( x ) /* { dg-error "'x' must be of 'omp_interop_t'" } */
|
||||
base1 ();
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause exceeds number of 'append_args' items for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */
|
||||
/* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */
|
||||
}
|
||||
|
|
134
gcc/testsuite/g++.dg/gomp/append-args-1.C
Normal file
134
gcc/testsuite/g++.dg/gomp/append-args-1.C
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* The following definitions are in omp_lib, which cannot be included
|
||||
gcc/testsuite/g++.dg/gomp/append-args-1.C in gcc/testsuite/ */
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
|
||||
#else
|
||||
# define __GOMP_UINTPTR_T_ENUM
|
||||
#endif
|
||||
|
||||
typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
|
||||
{
|
||||
omp_interop_none = 0,
|
||||
__omp_interop_t_max__ = __UINTPTR_MAX__
|
||||
} omp_interop_t;
|
||||
|
||||
template<typename T, typename T2>
|
||||
float repl1(T, T2, T2);
|
||||
#pragma omp declare variant(repl1) match(construct={dispatch}) append_args(interop(target,prefer_type(1,5,4)), interop(targetsync))
|
||||
template<typename T>
|
||||
float base1(T);
|
||||
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(T, T2, T2\\) \\\[with T = short int; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-4 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(T, T2, T2\\) \\\[with T = omp_interop_t; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-5 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(T, T2, T2\\) \\\[with T = float; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-6 } */
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T2, typename T3>
|
||||
void repl3inval(T, T2, float);
|
||||
#pragma omp declare variant(repl3inval) match(construct={dispatch}) adjust_args(nothing : y) \
|
||||
append_args(interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")}),target,targetsync))
|
||||
template<typename T, typename T2>
|
||||
void base2inval(T x, T2 y);
|
||||
|
||||
/* { dg-error "no matching function for call to 'repl3inval\\(int\\*, omp_interop_t, omp_interop_t\\)'" "" { target *-*-* } .-5 } */
|
||||
/* { dg-note "there is 1 candidate" "" { target *-*-* } .-6 } */
|
||||
/* { dg-note "candidate 1: 'template<class T, class T2, class T3> void repl3inval\\(T, T2, float\\)'" "" { target *-*-* } .-8 } */
|
||||
/* { dg-note "template argument deduction/substitution failed:" "" { target *-*-* } .-9 } */
|
||||
/* { dg-note "couldn't deduce template parameter 'T3'" "" { target *-*-* } .-9 } */
|
||||
|
||||
|
||||
template<typename T>
|
||||
void repl99(T);
|
||||
#pragma omp declare variant(repl99) match(construct={dispatch}) \
|
||||
append_args(interop(target, targetsync, prefer_type("cuda")))
|
||||
void base99();
|
||||
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl99\\(T\\) \\\[with T = omp_interop_t\\\]'" "" { target *-*-* } .-3 } */
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T2, typename T3>
|
||||
void repl2(T, T2, T3, T3);
|
||||
#pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y) \
|
||||
append_args(interop(target, targetsync, prefer_type(1)), \
|
||||
interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")})))
|
||||
template<typename T, typename T2>
|
||||
void base2(T x, T2 y);
|
||||
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl2\\(T, T2, T3, T3\\) \\\[with T = int\\*; T2 = int\\*; T3 = omp_interop_t\\\]'" "" { target *-*-* } .-5 } */
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl2\\(T, T2, T3, T3\\) \\\[with T = int\\*; T2 = omp_interop_t; T3 = omp_interop_t\\\]'" "" { target *-*-* } .-6 } */
|
||||
|
||||
|
||||
template<typename T,typename T3>
|
||||
void tooFewRepl(T, T, T3);
|
||||
#pragma omp declare variant(tooFewRepl) match(construct={dispatch}) \
|
||||
append_args(interop(target, targetsync, prefer_type(1)), \
|
||||
interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")})))
|
||||
template<typename T, typename T2>
|
||||
void tooFewBase(T x, T2 y);
|
||||
|
||||
/* { dg-error "no matching function for call to 'tooFewRepl\\(int\\*, int\\*, omp_interop_t, omp_interop_t\\)'" "" { target *-*-* } .-6 } */
|
||||
/* { dg-note "there is 1 candidate" "" { target *-*-* } .-7 } */
|
||||
/* { dg-note "candidate 1: 'template<class T, class T3> void tooFewRepl\\(T, T, T3\\)'" "" { target *-*-* } .-9 } */
|
||||
/* { dg-note "candidate expects 3 arguments, 4 provided" "" { target *-*-* } .-10 } */
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T2>
|
||||
void repl3(T, T2, ...);
|
||||
#pragma omp declare variant(repl3) match(construct={dispatch}) \
|
||||
append_args(interop(prefer_type("cuda", "hsa")))
|
||||
template<typename T>
|
||||
void base3(T, ...);
|
||||
|
||||
/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl3\\(T, T2, \.\.\.\\) \\\[with T = int\\*; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-4 } */
|
||||
|
||||
|
||||
|
||||
float
|
||||
test (int *a, int *b)
|
||||
{
|
||||
omp_interop_t obj1, obj2;
|
||||
float x, y;
|
||||
|
||||
#pragma omp dispatch interop ( obj1, obj2 )
|
||||
x = base1<short> (5);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch
|
||||
base2inval<int *, omp_interop_t> (a, omp_interop_none);
|
||||
|
||||
#pragma omp dispatch
|
||||
base99 ();
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
base2<int *, omp_interop_t> (b, omp_interop_none);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
base2<int *, int *> (b, a);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
x = base1<omp_interop_t> (omp_interop_none);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch interop ( obj1 )
|
||||
x = base1<float> (1.0f);
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
#pragma omp dispatch
|
||||
tooFewBase<int*,int*>(a,b);
|
||||
|
||||
#pragma omp dispatch nocontext(1)
|
||||
base3<int*>(a, 1, 2, "abc");
|
||||
|
||||
#pragma omp dispatch
|
||||
base3<int*>(a, 1, 2, "abc");
|
||||
/* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */
|
||||
|
||||
return x;
|
||||
}
|
53
gcc/testsuite/g++.dg/gomp/append-args-2.C
Normal file
53
gcc/testsuite/g++.dg/gomp/append-args-2.C
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* omp_interop_t is undefined (on purpose) */
|
||||
|
||||
|
||||
template<typename T, typename T2>
|
||||
float repl1(T, T2, T2); /* { dg-error "argument 2 of 'repl1' must be of 'omp_interop_t'" } */
|
||||
#pragma omp declare variant(repl1) match(construct={dispatch}) append_args(interop(target,prefer_type(1,5,4)), interop(targetsync)) /* { dg-note "'append_args' specified here" } */
|
||||
template<typename T>
|
||||
float base1(T);
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T2, typename T3>
|
||||
void repl3inval(T, T2, float); /* { dg-error "argument 3 of 'repl3inval' must be of 'omp_interop_t'" } */
|
||||
#pragma omp declare variant(repl3inval) match(construct={dispatch}) adjust_args(nothing : y) \
|
||||
append_args(interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")}),target,targetsync)) /* { dg-note "'append_args' specified here" } */
|
||||
template<typename T, typename T2>
|
||||
void base2inval(T x, T2 y);
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void repl99(T); /* { dg-error "argument 1 of 'repl99' must be of 'omp_interop_t'" } */
|
||||
#pragma omp declare variant(repl99) match(construct={dispatch}) \
|
||||
append_args(interop(target, targetsync, prefer_type("cuda"))) /* { dg-note "'append_args' specified here" } */
|
||||
void base99();
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T2, typename T3>
|
||||
void repl2(T, T2, T3, T3); /* { dg-error "argument 3 of 'repl2' must be of 'omp_interop_t'" } */
|
||||
#pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y) \
|
||||
append_args(interop(target, targetsync, prefer_type(1)), /* { dg-note "'append_args' specified here" } */ \
|
||||
interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")})))
|
||||
template<typename T, typename T2>
|
||||
void base2(T x, T2 y);
|
||||
|
||||
|
||||
template<typename T,typename T3>
|
||||
void tooFewRepl(T, T, T3); /* { dg-error "argument 3 of 'tooFewRepl' must be of 'omp_interop_t'" } */
|
||||
#pragma omp declare variant(tooFewRepl) match(construct={dispatch}) \
|
||||
append_args(interop(target, targetsync, prefer_type(1)), /* { dg-note "'append_args' specified here" } */ \
|
||||
interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")})))
|
||||
template<typename T, typename T2>
|
||||
void tooFewBase(T x, T2 y);
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T2>
|
||||
void repl3(T, T2, ...); /* { dg-error "argument 2 of 'repl3' must be of 'omp_interop_t'" } */
|
||||
#pragma omp declare variant(repl3) match(construct={dispatch}) \
|
||||
append_args(interop(prefer_type("cuda", "hsa"))) /* { dg-note "'append_args' specified here" } */
|
||||
template<typename T>
|
||||
void base3(T, ...);
|
100
gcc/testsuite/g++.dg/gomp/append-args-3.C
Normal file
100
gcc/testsuite/g++.dg/gomp/append-args-3.C
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* { dg-additional-options "-fdump-tree-gimple -Wall" } */
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
|
||||
#else
|
||||
# define __GOMP_UINTPTR_T_ENUM
|
||||
#endif
|
||||
|
||||
typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
|
||||
{
|
||||
omp_interop_none = 0,
|
||||
__omp_interop_t_max__ = __UINTPTR_MAX__
|
||||
} omp_interop_t;
|
||||
|
||||
|
||||
template<typename T, typename T2, typename T3>
|
||||
void g(T, T2, T3, T3);
|
||||
#pragma omp declare variant(g) match(construct={dispatch}) append_args(interop(target),interop(targetsync))
|
||||
template<typename T, typename T2>
|
||||
void f(T x, T2 y);
|
||||
|
||||
void foo()
|
||||
{
|
||||
omp_interop_t obj1; /* { dg-note "'obj1' was declared here" } */
|
||||
omp_interop_t obj2 = omp_interop_none;
|
||||
#pragma omp dispatch device(9) novariants(1)
|
||||
f<int, const char *>(2, (const char*)"abc");
|
||||
#pragma omp dispatch device(5) interop(obj1,obj2)
|
||||
f<int, const char *>(3, (const char*)"cde"); /* { dg-warning "'obj1' is used uninitialized \\\[-Wuninitialized\\\]" } */
|
||||
|
||||
#pragma omp dispatch device(9) novariants(1)
|
||||
f<int, omp_interop_t>(2, omp_interop_none);
|
||||
#pragma omp dispatch device(5) interop(obj1,obj2)
|
||||
f<int, omp_interop_t>(3, omp_interop_none);
|
||||
}
|
||||
|
||||
|
||||
template<typename Ta, typename Tb, typename Tc>
|
||||
void varvar(Ta, Tb, Tc, Tc, ...);
|
||||
#pragma omp declare variant(varvar) match(construct={dispatch}) append_args(interop(target),interop(targetsync))
|
||||
template<typename Ta, typename Tb>
|
||||
void varbase(Ta x, Tb y, ...);
|
||||
|
||||
void bar()
|
||||
{
|
||||
omp_interop_t obj3 = omp_interop_none;
|
||||
omp_interop_t obj4; /* { dg-note "'obj4' was declared here" } */
|
||||
#pragma omp dispatch device(3) nocontext(1)
|
||||
varbase<int, int>(10, 11, 101, 202, 303);
|
||||
#pragma omp dispatch device(7) interop(obj3,obj4)
|
||||
varbase<int, int>(20, 21, 111, 222, 333); /* { dg-warning "'obj4' is used uninitialized \\\[-Wuninitialized\\\]" } */
|
||||
|
||||
#pragma omp dispatch device(3) nocontext(1)
|
||||
varbase<int, omp_interop_t>(10, omp_interop_none, 101, 202, 303);
|
||||
#pragma omp dispatch device(7) interop(obj3,obj4)
|
||||
varbase<int, omp_interop_t>(20, omp_interop_none, 111, 222, 333);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
void nargVar(T, T);
|
||||
#pragma omp declare variant(nargVar) match(construct={dispatch}) append_args(interop(target),interop(targetsync))
|
||||
void nargsBase();
|
||||
|
||||
void foobar()
|
||||
{
|
||||
omp_interop_t obj5 = omp_interop_none;
|
||||
omp_interop_t obj6 = omp_interop_none;
|
||||
#pragma omp dispatch device(1) nocontext(1)
|
||||
nargsBase();
|
||||
#pragma omp dispatch device(2) interop(obj5,obj6)
|
||||
nargsBase();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 10 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(9\\);" 2 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(5\\);" 2 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(3\\);" 2 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(7\\);" 2 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(1\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(2\\);" 1 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(D\.\[0-9\]+\\);" 10 "gimple" } } */
|
||||
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "f<int, const char\\*> \\(2, \"abc\"\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "g<int, const char\\*, omp_interop_t> \\(3, \"cde\", obj1, obj2\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "f<int, omp_interop_t> \\(2, 0\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "g<int, omp_interop_t, omp_interop_t> \\(3, 0, obj1, obj2\\);" 1 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "varbase<int, int> \\(10, 11, 101, 202, 303\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "varvar<int, int, omp_interop_t> \\(20, 21, obj3, obj4, 111, 222, 333\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "varbase<int, omp_interop_t> \\(10, 0, 101, 202, 303\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "varvar<int, omp_interop_t, omp_interop_t> \\(20, 0, obj3, obj4, 111, 222, 333\\);" 1 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "nargsBase \\(\\);" 1 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump-times "nargVar<omp_interop_t> \\(obj5, obj6\\);" 1 "gimple" } } */
|
Loading…
Add table
Reference in a new issue