@@ -1452,319 +1452,6 @@ c_parser_external_declaration (c_parser *parser)
}
}
-static tree
-check_oacc_vars_1 (tree *tp, int *, void *l)
-{
- if (TREE_CODE (*tp) == VAR_DECL && TREE_PUBLIC (*tp))
- {
- location_t loc = DECL_SOURCE_LOCATION (*tp);
- tree attrs;
- attrs = lookup_attribute ("oacc declare", DECL_ATTRIBUTES (*tp));
- if (attrs)
- {
- tree t;
-
- for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
- {
- loc = EXPR_LOCATION ((tree) l);
-
- if (OMP_CLAUSE_MAP_KIND (TREE_VALUE (t)) == GOMP_MAP_LINK)
- {
- error_at (loc, "%<link%> clause cannot be used with %qE",
- *tp);
- break;
- }
- }
- }
- else
- error_at (loc, "no %<#pragma acc declare%> for %qE", *tp);
- }
- return NULL_TREE;
-}
-
-static tree
-check_oacc_vars (tree *tp, int *, void *)
-{
- if (TREE_CODE (*tp) == STATEMENT_LIST)
- {
- tree_stmt_iterator i;
-
- for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
- {
- tree t = tsi_stmt (i);
- walk_tree_without_duplicates (&t, check_oacc_vars_1, t);
- }
- }
-
- return NULL_TREE;
-}
-
-static struct oacc_return
-{
- tree_stmt_iterator iter;
- tree stmt;
- int op;
- struct oacc_return *next;
-} *oacc_returns;
-
-static tree
-find_oacc_return (tree *tp, int *, void *)
-{
- if (TREE_CODE (*tp) == STATEMENT_LIST)
- {
- tree_stmt_iterator i;
-
- for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
- {
- tree t;
- struct oacc_return *r;
-
- t = tsi_stmt (i);
-
- if (TREE_CODE (t) == RETURN_EXPR)
- {
- r = XNEW (struct oacc_return);
- r->iter = i;
- r->stmt = NULL_TREE;
- r->op = 1;
- r->next = NULL;
-
- if (oacc_returns)
- r->next = oacc_returns;
-
- oacc_returns = r;
- }
- else if (TREE_CODE (t) == COND_EXPR)
- {
- bool op1, op2;
- tree op;
-
- op1 = op2 = false;
-
- op = TREE_OPERAND (t, 1);
- op1 = (op && TREE_CODE (op) == RETURN_EXPR);
-
- op = TREE_OPERAND (t, 2);
- op2 = (op && TREE_CODE (op) == RETURN_EXPR);
-
- if (op1 || op2)
- {
- r = XNEW (struct oacc_return);
- r->stmt = t;
- r->op = op1 ? 1 : 2;
- r->next = NULL;
-
- if (oacc_returns)
- r->next = oacc_returns;
-
- oacc_returns = r;
- }
- }
- }
- }
-
- return NULL_TREE;
-}
-
-static void
-finish_oacc_declare (tree fnbody, tree decls)
-{
- tree t, stmt, body, c, ret_clauses, clauses;
- location_t loc;
- tree_stmt_iterator i;
- tree fndecl = current_function_decl;
-
- if (lookup_attribute ("oacc function", DECL_ATTRIBUTES (fndecl)))
- {
- if (lookup_attribute ("oacc declare", DECL_ATTRIBUTES (fndecl)))
- {
- location_t loc = DECL_SOURCE_LOCATION (fndecl);
- error_at (loc, "%<#pragma acc declare%> not allowed in %qE", fndecl);
- }
-
- walk_tree_without_duplicates (&fnbody, check_oacc_vars, NULL);
- return;
- }
-
- if (!decls)
- return;
-
- body = BIND_EXPR_BODY (fnbody);
-
- if (TREE_CODE (body) != STATEMENT_LIST)
- {
- tree list;
-
- list = alloc_stmt_list ();
- append_to_statement_list (body, &list);
- BIND_EXPR_BODY (fnbody) = list;
- body = list;
- }
-
- walk_tree_without_duplicates (&body, find_oacc_return, NULL);
-
- clauses = NULL_TREE;
-
- for (t = decls; t; t = TREE_CHAIN (t))
- {
- c = TREE_VALUE (TREE_VALUE (t));
-
- if (clauses)
- OMP_CLAUSE_CHAIN (c) = clauses;
- else
- loc = OMP_CLAUSE_LOCATION (c);
-
- clauses = c;
- }
-
- ret_clauses = NULL_TREE;
-
- for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
- {
- bool ret = false;
- HOST_WIDE_INT kind, new_op;
-
- kind = OMP_CLAUSE_MAP_KIND (c);
-
- switch (kind)
- {
- case GOMP_MAP_ALLOC:
- case GOMP_MAP_FORCE_ALLOC:
- case GOMP_MAP_FORCE_TO:
- new_op = GOMP_MAP_FORCE_DEALLOC;
- ret = true;
- break;
-
- case GOMP_MAP_FORCE_FROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
- new_op = GOMP_MAP_FORCE_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_FORCE_TOFROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_TO);
- new_op = GOMP_MAP_FORCE_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_FROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
- new_op = GOMP_MAP_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_TOFROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
- new_op = GOMP_MAP_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_DEVICE_RESIDENT:
- case GOMP_MAP_FORCE_DEVICEPTR:
- case GOMP_MAP_FORCE_PRESENT:
- case GOMP_MAP_LINK:
- case GOMP_MAP_POINTER:
- case GOMP_MAP_TO:
- break;
-
- default:
- gcc_unreachable ();
- break;
- }
-
- if (ret)
- {
- t = copy_node (c);
-
- OMP_CLAUSE_SET_MAP_KIND (t, new_op);
-
- if (ret_clauses)
- OMP_CLAUSE_CHAIN (t) = ret_clauses;
-
- ret_clauses = t;
- }
- }
-
- if (clauses)
- {
- bool found = false;
-
- stmt = make_node (OACC_DECLARE);
- TREE_TYPE (stmt) = void_type_node;
- OACC_DECLARE_CLAUSES (stmt) = clauses;
- SET_EXPR_LOCATION (stmt, loc);
-
- c = OMP_CLAUSE_DECL (TREE_VALUE (TREE_VALUE (decls)));
-
- for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
- {
- tree it;
-
- it = tsi_stmt (i);
-
- if ((TREE_CODE (it) == DECL_EXPR) && (DECL_EXPR_DECL (it) == c))
- {
- tsi_link_after (&i, stmt, TSI_CONTINUE_LINKING);
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- i = tsi_start (body);
- tsi_link_before (&i, stmt, TSI_CONTINUE_LINKING);
- }
- }
-
- while (oacc_returns)
- {
- struct oacc_return *r;
-
- stmt = make_node (OACC_DECLARE);
- TREE_TYPE (stmt) = void_type_node;
- OACC_DECLARE_CLAUSES (stmt) = ret_clauses;
- SET_EXPR_LOCATION (stmt, loc);
-
- r = oacc_returns;
- if (r->stmt)
- {
- tree l;
-
- l = alloc_stmt_list ();
- append_to_statement_list (stmt, &l);
- stmt = TREE_OPERAND (r->stmt, r->op);
- append_to_statement_list (stmt, &l);
- TREE_OPERAND (r->stmt, r->op) = l;
- }
- else
- tsi_link_before (&r->iter, stmt, TSI_CONTINUE_LINKING);
-
- oacc_returns = r->next;
- free (r);
- }
-
- for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
- {
- if (tsi_end_p (i))
- break;
- }
-
- if (ret_clauses)
- {
- stmt = make_node (OACC_DECLARE);
- TREE_TYPE (stmt) = void_type_node;
- OACC_DECLARE_CLAUSES (stmt) = ret_clauses;
- SET_EXPR_LOCATION (stmt, loc);
-
- tsi_link_before (&i, stmt, TSI_CONTINUE_LINKING);
- }
-
- DECL_ATTRIBUTES (fndecl)
- = remove_attribute ("oacc declare", DECL_ATTRIBUTES (fndecl));
-}
-
-
static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
static void c_finish_oacc_routine (c_parser *, tree, tree, bool);
@@ -2312,9 +1999,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
fnbody = c_parser_compound_statement (parser);
if (flag_cilkplus && contains_array_notation_expr (fnbody))
fnbody = expand_array_notation_exprs (fnbody);
- tree decls = lookup_attribute ("oacc declare",
- DECL_ATTRIBUTES (current_function_decl));
- finish_oacc_declare (fnbody, decls);
if (nested)
{
tree decl = current_function_decl;
@@ -12770,7 +12454,8 @@ static void
c_parser_oacc_declare (c_parser *parser)
{
location_t pragma_loc = c_parser_peek_token (parser)->location;
- tree clauses;
+ tree c, clauses, ret_clauses, stmt, t;
+
bool error = false;
c_parser_consume_pragma (parser);
@@ -12783,7 +12468,8 @@ c_parser_oacc_declare (c_parser *parser)
"no valid clauses specified in %<#pragma acc declare%>");
return;
}
- for (tree t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
+
+ for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
{
location_t loc = OMP_CLAUSE_LOCATION (t);
tree decl = OMP_CLAUSE_DECL (t);
@@ -12849,60 +12535,27 @@ c_parser_oacc_declare (c_parser *parser)
break;
}
- /* Store the clause in an attribute on the variable, at file
- scope, or the function, at block scope. */
- tree decl_for_attr;
- if (global_bindings_p ())
+ tree decl_for_attr = decl;
+ tree prev_attr = lookup_attribute ("oacc declare",
+ DECL_ATTRIBUTES (decl));
+ if (prev_attr)
{
- decl_for_attr = decl;
- tree prev_attr = lookup_attribute ("oacc declare",
- DECL_ATTRIBUTES (decl));
- if (prev_attr)
- {
- tree p = TREE_VALUE (prev_attr);
- tree cl = TREE_VALUE (p);
+ tree p = TREE_VALUE (prev_attr);
+ tree cl = TREE_VALUE (p);
- if (!devres
- && OMP_CLAUSE_MAP_KIND (cl) != GOMP_MAP_DEVICE_RESIDENT)
- {
- error_at (loc,
- "variable %qD used more than once with "
- "%<#pragma acc declare%>", decl);
- inform (OMP_CLAUSE_LOCATION (cl),
- "previous directive was here");
- error = true;
- continue;
- }
- }
- }
- else
- {
- decl_for_attr = current_function_decl;
- tree prev_attr = lookup_attribute ("oacc declare",
- DECL_ATTRIBUTES (decl_for_attr));
- for (;
- prev_attr;
- prev_attr = lookup_attribute ("oacc declare",
- TREE_CHAIN (prev_attr)))
+ if (!devres && OMP_CLAUSE_MAP_KIND (cl) != GOMP_MAP_DEVICE_RESIDENT)
{
- tree p = TREE_VALUE (prev_attr);
- tree cl = TREE_VALUE (p);
- if (OMP_CLAUSE_DECL (cl) == decl)
- {
- error_at (loc,
- "variable %qD used more than once with "
- "%<#pragma acc declare%>", decl);
- inform (OMP_CLAUSE_LOCATION (cl),
- "previous directive was here");
- error = true;
- break;
- }
+ error_at (loc, "variable %qD used more than once with "
+ "%<#pragma acc declare%>", decl);
+ inform (OMP_CLAUSE_LOCATION (cl), "previous directive was here");
+ error = true;
+ continue;
}
}
- if (!error)
+ if (!error && global_bindings_p ())
{
- tree attr = tree_cons (NULL_TREE, t, NULL_TREE);
+ tree attr = tree_cons (NULL_TREE, clauses, NULL_TREE);
tree attrs = tree_cons (get_identifier ("oacc declare"),
attr, NULL_TREE);
decl_attributes (&decl_for_attr, attrs, 0);
@@ -12912,6 +12565,74 @@ c_parser_oacc_declare (c_parser *parser)
if (error)
return;
+ ret_clauses = NULL_TREE;
+
+ for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ bool ret = false;
+ HOST_WIDE_INT kind, new_op;
+
+ kind = OMP_CLAUSE_MAP_KIND (c);
+
+ switch (kind)
+ {
+ case GOMP_MAP_ALLOC:
+ case GOMP_MAP_FORCE_ALLOC:
+ case GOMP_MAP_FORCE_TO:
+ new_op = GOMP_MAP_FORCE_DEALLOC;
+ ret = true;
+ break;
+
+ case GOMP_MAP_FORCE_FROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
+ new_op = GOMP_MAP_FORCE_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_FORCE_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_TO);
+ new_op = GOMP_MAP_FORCE_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_FROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
+ new_op = GOMP_MAP_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
+ new_op = GOMP_MAP_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_DEVICE_RESIDENT:
+ case GOMP_MAP_FORCE_DEVICEPTR:
+ case GOMP_MAP_FORCE_PRESENT:
+ case GOMP_MAP_LINK:
+ case GOMP_MAP_POINTER:
+ case GOMP_MAP_TO:
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ if (ret)
+ {
+ t = copy_node (c);
+
+ OMP_CLAUSE_SET_MAP_KIND (t, new_op);
+
+ if (ret_clauses)
+ OMP_CLAUSE_CHAIN (t) = ret_clauses;
+
+ ret_clauses = t;
+ }
+ }
+
if (global_bindings_p ())
{
char buf[128];
@@ -12971,6 +12692,16 @@ c_parser_oacc_declare (c_parser *parser)
finish_function ();
}
+ else
+ {
+ stmt = make_node (OACC_DECLARE);
+ TREE_TYPE (stmt) = void_type_node;
+ OACC_DECLARE_CLAUSES (stmt) = clauses;
+ OACC_DECLARE_RETURN_CLAUSES (stmt) = ret_clauses;
+ SET_EXPR_LOCATION (stmt, pragma_loc);
+
+ add_stmt (stmt);
+ }
}
/* OpenACC 2.0:
@@ -14114,332 +14114,6 @@ maybe_save_function_definition (tree fun)
register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
}
-static tree
-check_oacc_vars_1 (tree *tp, int *, void *l)
-{
- if (TREE_CODE (*tp) == VAR_DECL && TREE_PUBLIC (*tp))
- {
- location_t loc = DECL_SOURCE_LOCATION (*tp);
- tree attrs;
- attrs = lookup_attribute ("oacc declare", DECL_ATTRIBUTES (*tp));
- if (attrs)
- {
- tree t;
-
- for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
- {
- loc = EXPR_LOCATION ((tree) l);
-
- if (OMP_CLAUSE_MAP_KIND (TREE_VALUE (t)) == GOMP_MAP_LINK)
- {
- error_at (loc, "%<link%> clause cannot be used with %qE",
- *tp);
- break;
- }
- }
- }
- else
- error_at (loc, "no %<#pragma acc declare%> for %qE", *tp);
- }
- return NULL_TREE;
-}
-
-static tree
-check_oacc_vars (tree *tp, int *, void *)
-{
- if (TREE_CODE (*tp) == STATEMENT_LIST)
- {
- tree_stmt_iterator i;
-
- for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
- {
- tree t = tsi_stmt (i);
- walk_tree_without_duplicates (&t, check_oacc_vars_1, t);
- }
- }
-
- return NULL_TREE;
-}
-
-static struct oacc_return
-{
- tree_stmt_iterator iter;
- tree stmt;
- int op;
- struct oacc_return *next;
-} *oacc_returns;
-
-static tree
-find_oacc_return (tree *tp, int *, void *)
-{
- if (TREE_CODE (*tp) == STATEMENT_LIST)
- {
- tree_stmt_iterator i;
-
- for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
- {
- tree t;
- struct oacc_return *r;
-
- t = tsi_stmt (i);
-
- if (TREE_CODE (t) == RETURN_EXPR)
- {
- r = XNEW (struct oacc_return);
- r->iter = i;
- r->stmt = NULL_TREE;
- r->op = 1;
- r->next = NULL;
-
- if (oacc_returns)
- r->next = oacc_returns;
-
- oacc_returns = r;
- }
- else if (TREE_CODE (t) == IF_STMT)
- {
- bool op1, op2;
- tree op;
-
- op1 = op2 = false;
-
- op = TREE_OPERAND (t, 1);
- op1 = (op && TREE_CODE (op) == RETURN_EXPR);
-
- op = TREE_OPERAND (t, 2);
- op2 = (op && TREE_CODE (op) == RETURN_EXPR);
-
- if (op1 || op2)
- {
- r = XNEW (struct oacc_return);
- r->stmt = t;
- r->op = op1 ? 1 : 2;
- r->next = NULL;
-
- if (oacc_returns)
- r->next = oacc_returns;
-
- oacc_returns = r;
- }
- }
- }
- }
-
- return NULL_TREE;
-}
-
-static void
-finish_oacc_declare (tree fndecl)
-{
- tree t, stmt, list, c, ret_clauses, clauses, decls;
- location_t loc;
- tree_stmt_iterator i;
-
- if (DECL_USE_TEMPLATE (fndecl))
- return;
-
- list = cur_stmt_list;
-
- decls = lookup_attribute ("oacc declare", DECL_ATTRIBUTES (fndecl));
-
- if (lookup_attribute ("oacc function", DECL_ATTRIBUTES (fndecl)))
- {
- if (decls)
- {
- location_t loc = DECL_SOURCE_LOCATION (fndecl);
- error_at (loc, "%<#pragma acc declare%> not allowed in %qE", fndecl);
- }
-
- walk_tree_without_duplicates (&list, check_oacc_vars, NULL);
- return;
- }
-
- if (!decls)
- return;
-
- walk_tree_without_duplicates (&list, find_oacc_return, NULL);
-
- clauses = NULL_TREE;
-
- for (t = decls; t; t = TREE_CHAIN (t))
- {
- c = TREE_VALUE (TREE_VALUE (t));
-
- if (clauses)
- OMP_CLAUSE_CHAIN (c) = clauses;
- else
- loc = OMP_CLAUSE_LOCATION (c);
-
- clauses = c;
- }
-
- ret_clauses = NULL_TREE;
-
- for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
- {
- bool ret = false;
- HOST_WIDE_INT kind, new_op;
-
- kind = OMP_CLAUSE_MAP_KIND (c);
-
- switch (kind)
- {
- case GOMP_MAP_ALLOC:
- case GOMP_MAP_FORCE_ALLOC:
- case GOMP_MAP_FORCE_TO:
- new_op = GOMP_MAP_FORCE_DEALLOC;
- ret = true;
- break;
-
- case GOMP_MAP_FORCE_FROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
- new_op = GOMP_MAP_FORCE_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_FORCE_TOFROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_TO);
- new_op = GOMP_MAP_FORCE_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_FROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
- new_op = GOMP_MAP_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_TOFROM:
- OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
- new_op = GOMP_MAP_FROM;
- ret = true;
- break;
-
- case GOMP_MAP_DEVICE_RESIDENT:
- case GOMP_MAP_FORCE_DEVICEPTR:
- case GOMP_MAP_FORCE_PRESENT:
- case GOMP_MAP_POINTER:
- case GOMP_MAP_TO:
- break;
-
- case GOMP_MAP_LINK:
- continue;
-
- default:
- gcc_unreachable ();
- break;
- }
-
- if (ret)
- {
- t = copy_node (c);
-
- OMP_CLAUSE_SET_MAP_KIND (t, new_op);
-
- if (ret_clauses)
- OMP_CLAUSE_CHAIN (t) = ret_clauses;
-
- ret_clauses = t;
- }
- }
-
- i = tsi_start (list);
- if (!tsi_end_p (i))
- {
- t = tsi_stmt (i);
- if (TREE_CODE (t) == BIND_EXPR)
- {
- list = BIND_EXPR_BODY (t);
- if (TREE_CODE (list) != STATEMENT_LIST)
- {
- stmt = list;
- list = alloc_stmt_list ();
- BIND_EXPR_BODY (t) = list;
- i = tsi_start (list);
- tsi_link_after (&i, stmt, TSI_CONTINUE_LINKING);
- }
- }
- }
-
- if (clauses)
- {
- bool found = false;
-
- stmt = make_node (OACC_DECLARE);
- TREE_TYPE (stmt) = void_type_node;
- OMP_STANDALONE_CLAUSES (stmt) = clauses;
- SET_EXPR_LOCATION (stmt, loc);
-
- c = OMP_CLAUSE_DECL (TREE_VALUE (TREE_VALUE (decls)));
-
- for (i = tsi_start (list); !tsi_end_p (i); tsi_next (&i))
- {
- tree it;
-
- it = tsi_stmt (i);
-
- if ((TREE_CODE (it) == DECL_EXPR) && (DECL_EXPR_DECL (it) == c))
- {
- tsi_link_after (&i, stmt, TSI_CONTINUE_LINKING);
- found = true;
- break;
- }
- }
-
- if (!found)
- {
- i = tsi_start (list);
- tsi_link_before (&i, stmt, TSI_CONTINUE_LINKING);
- }
- }
-
- while (oacc_returns)
- {
- struct oacc_return *r;
-
- stmt = make_node (OACC_DECLARE);
- TREE_TYPE (stmt) = void_type_node;
- OMP_STANDALONE_CLAUSES (stmt) = ret_clauses;
- SET_EXPR_LOCATION (stmt, loc);
-
- r = oacc_returns;
- if (r->stmt)
- {
- tree l;
-
- l = alloc_stmt_list ();
- append_to_statement_list (stmt, &l);
- stmt = TREE_OPERAND (r->stmt, r->op);
- append_to_statement_list (stmt, &l);
- TREE_OPERAND (r->stmt, r->op) = l;
- }
- else
- tsi_link_before (&r->iter, stmt, TSI_CONTINUE_LINKING);
-
- oacc_returns = r->next;
- free (r);
- }
-
- if (ret_clauses)
- {
- for (i = tsi_start (list); !tsi_end_p (i); tsi_next (&i))
- {
- if (tsi_end_p (i))
- break;
- }
-
- stmt = make_node (OACC_DECLARE);
- TREE_TYPE (stmt) = void_type_node;
- OMP_STANDALONE_CLAUSES (stmt) = ret_clauses;
- SET_EXPR_LOCATION (stmt, loc);
-
- tsi_link_before (&i, stmt, TSI_CONTINUE_LINKING);
- }
-
- DECL_ATTRIBUTES (fndecl)
- = remove_attribute ("oacc declare", DECL_ATTRIBUTES (fndecl));
-}
-
/* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage
for the function definition.
@@ -14468,8 +14142,6 @@ finish_function (int flags)
gcc_assert (!defer_mark_used_calls);
defer_mark_used_calls = true;
- finish_oacc_declare (fndecl);
-
record_key_method_defined (fndecl);
fntype = TREE_TYPE (fndecl);
@@ -32179,12 +32179,14 @@ static int oacc_dcl_idx = 0;
static tree
cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
{
- tree clauses;
+ tree c, clauses, ret_clauses, stmt, t;
bool error = false;
+
clauses = cp_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
"#pragma acc declare", pragma_tok);
+
if (find_omp_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
{
error_at (pragma_tok->location,
@@ -32258,58 +32260,26 @@ cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
break;
}
- /* Store the clause in an attribute on the variable, at file
- scope, or the function, at block scope. */
- tree decl_for_attr;
- if (global_bindings_p ())
- {
- decl_for_attr = decl;
- tree prev_attr = lookup_attribute ("oacc declare",
+ tree decl_for_attr = decl;
+ tree prev_attr = lookup_attribute ("oacc declare",
DECL_ATTRIBUTES (decl));
- if (prev_attr)
- {
- tree p = TREE_VALUE (prev_attr);
- tree cl = TREE_VALUE (p);
-
- if (!devres
- && OMP_CLAUSE_MAP_KIND (cl) != GOMP_MAP_DEVICE_RESIDENT)
- {
- error_at (loc,
- "variable %qD used more than once with "
- "%<#pragma acc declare%>", decl);
- inform (OMP_CLAUSE_LOCATION (TREE_VALUE (p)),
- "previous directive was here");
- error = true;
- continue;
- }
- }
- }
- else
+ if (prev_attr)
{
- decl_for_attr = current_function_decl;
- tree prev_attr = lookup_attribute ("oacc declare",
- DECL_ATTRIBUTES (decl_for_attr));
- for (;
- prev_attr;
- prev_attr = lookup_attribute ("oacc declare",
- TREE_CHAIN (prev_attr)))
+ tree p = TREE_VALUE (prev_attr);
+ tree cl = TREE_VALUE (p);
+
+ if (!devres && OMP_CLAUSE_MAP_KIND (cl) != GOMP_MAP_DEVICE_RESIDENT)
{
- tree p = TREE_VALUE (prev_attr);
- tree cl = TREE_VALUE (p);
- if (OMP_CLAUSE_DECL (cl) == decl)
- {
- error_at (loc,
- "variable %qD used more than once with "
- "%<#pragma acc declare%>", decl);
- inform (OMP_CLAUSE_LOCATION (cl),
- "previous directive was here");
- error = true;
- break;
- }
+ error_at (loc, "variable %qD used more than once with "
+ "%<#pragma acc declare%>", decl);
+ inform (OMP_CLAUSE_LOCATION (TREE_VALUE (p)),
+ "previous directive was here");
+ error = true;
+ continue;
}
}
- if (!error)
+ if (!error && global_bindings_p ())
{
tree attr = tree_cons (NULL_TREE, t, NULL_TREE);
tree attrs = tree_cons (get_identifier ("oacc declare"),
@@ -32321,6 +32291,76 @@ cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
if (error)
return NULL_TREE;
+ ret_clauses = NULL_TREE;
+
+ for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ bool ret = false;
+ HOST_WIDE_INT kind, new_op;
+
+ kind = OMP_CLAUSE_MAP_KIND (c);
+
+ switch (kind)
+ {
+ case GOMP_MAP_ALLOC:
+ case GOMP_MAP_FORCE_ALLOC:
+ case GOMP_MAP_FORCE_TO:
+ new_op = GOMP_MAP_FORCE_DEALLOC;
+ ret = true;
+ break;
+
+ case GOMP_MAP_FORCE_FROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
+ new_op = GOMP_MAP_FORCE_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_FORCE_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_TO);
+ new_op = GOMP_MAP_FORCE_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_FROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_ALLOC);
+ new_op = GOMP_MAP_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
+ new_op = GOMP_MAP_FROM;
+ ret = true;
+ break;
+
+ case GOMP_MAP_DEVICE_RESIDENT:
+ case GOMP_MAP_FORCE_DEVICEPTR:
+ case GOMP_MAP_FORCE_PRESENT:
+ case GOMP_MAP_POINTER:
+ case GOMP_MAP_TO:
+ break;
+
+ case GOMP_MAP_LINK:
+ continue;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ if (ret)
+ {
+ t = copy_node (c);
+
+ OMP_CLAUSE_SET_MAP_KIND (t, new_op);
+
+ if (ret_clauses)
+ OMP_CLAUSE_CHAIN (t) = ret_clauses;
+
+ ret_clauses = t;
+ }
+ }
+
if (global_bindings_p ())
{
char buf[128];
@@ -32375,6 +32415,16 @@ cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
expand_or_defer_fn (finish_function (0));
obstack_free (&declarator_obstack, p);
}
+ else
+ {
+ stmt = make_node (OACC_DECLARE);
+ TREE_TYPE (stmt) = void_type_node;
+ OACC_DECLARE_CLAUSES (stmt) = clauses;
+ OACC_DECLARE_RETURN_CLAUSES (stmt) = ret_clauses;
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+
+ add_stmt (stmt);
+ }
return NULL_TREE;
}
@@ -13907,6 +13907,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
integral_constant_expression_p)
tree stmt, tmp;
+tree s;
tree r;
location_t loc;
@@ -14396,8 +14397,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
add_stmt (t);
break;
- case OMP_TARGET_UPDATE:
case OACC_DECLARE:
+ t = copy_node (t);
+ tmp = tsubst_omp_clauses (OACC_DECLARE_CLAUSES (t), false,
+ args, complain, in_decl);
+ OACC_DECLARE_CLAUSES (t) = tmp;
+ tmp = tsubst_omp_clauses (OACC_DECLARE_RETURN_CLAUSES (t), false,
+ args, complain, in_decl);
+ OACC_DECLARE_RETURN_CLAUSES (t) = tmp;
+ add_stmt (t);
+ break;
+
+ case OMP_TARGET_UPDATE:
case OACC_ENTER_DATA:
case OACC_EXIT_DATA:
case OACC_UPDATE:
@@ -1287,6 +1287,7 @@ typedef struct gfc_oacc_declare
locus where;
bool module_var;
gfc_omp_clauses *clauses;
+ gfc_omp_clauses *return_clauses;
}
gfc_oacc_declare;
#define gfc_get_oacc_declare() XCNEW (gfc_oacc_declare)
@@ -5864,8 +5864,7 @@ void
finish_oacc_declare (gfc_namespace *ns, enum sym_flavor flavor)
{
gfc_code *code, *end_c, *code2;
- gfc_oacc_declare *oc;
- gfc_omp_clauses *omp_clauses = NULL, *ret_clauses = NULL;
+ gfc_oacc_declare *oc, *new_oc;
gfc_omp_namelist *n;
locus where = gfc_current_locus;
@@ -5888,204 +5887,109 @@ finish_oacc_declare (gfc_namespace *ns, enum sym_flavor flavor)
for (oc = ns->oacc_declare; oc; oc = oc->next)
{
+ gfc_omp_clauses *omp_clauses, *ret_clauses;
+
if (oc->module_var)
continue;
if (oc->clauses)
{
- if (omp_clauses)
- {
- gfc_omp_namelist *p;
-
- for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
- p = n;
-
- p->next = oc->clauses->lists[OMP_LIST_MAP];
- }
- else
- {
- omp_clauses = oc->clauses;
- }
- }
- }
-
- while (ns->oacc_declare)
- {
- oc = ns->oacc_declare;
- ns->oacc_declare = oc->next;
- free (oc);
- }
-
- code = XCNEW (gfc_code);
- code->op = EXEC_OACC_DECLARE;
- code->loc = where;
- code->ext.omp_clauses = omp_clauses;
-
- for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
- {
- bool ret = false;
- gfc_omp_map_op new_op;
-
- switch (n->u.map_op)
- {
- case OMP_MAP_ALLOC:
- case OMP_MAP_FORCE_ALLOC:
- new_op = OMP_MAP_FORCE_DEALLOC;
- ret = true;
- break;
-
- case OMP_MAP_DEVICE_RESIDENT:
- n->u.map_op = OMP_MAP_FORCE_ALLOC;
- new_op = OMP_MAP_FORCE_DEALLOC;
- ret = true;
- break;
-
- case OMP_MAP_FORCE_FROM:
- n->u.map_op = OMP_MAP_FORCE_ALLOC;
- new_op = OMP_MAP_FORCE_FROM;
- ret = true;
- break;
-
- case OMP_MAP_FORCE_TO:
- new_op = OMP_MAP_FORCE_DEALLOC;
- ret = true;
- break;
-
- case OMP_MAP_FORCE_TOFROM:
- n->u.map_op = OMP_MAP_FORCE_TO;
- new_op = OMP_MAP_FORCE_FROM;
- ret = true;
- break;
-
- case OMP_MAP_FROM:
- n->u.map_op = OMP_MAP_FORCE_ALLOC;
- new_op = OMP_MAP_FROM;
- ret = true;
- break;
-
- case OMP_MAP_FORCE_DEVICEPTR:
- case OMP_MAP_FORCE_PRESENT:
- case OMP_MAP_LINK:
- case OMP_MAP_TO:
- break;
-
- case OMP_MAP_TOFROM:
- n->u.map_op = OMP_MAP_TO;
- new_op = OMP_MAP_FROM;
- ret = true;
- break;
-
- default:
- gcc_unreachable ();
- break;
- }
-
- if (ret)
- {
- gfc_omp_namelist *new_n;
+ code = XCNEW (gfc_code);
+ code->op = EXEC_OACC_DECLARE;
+ code->loc = where;
- new_n = gfc_get_omp_namelist ();
- new_n->sym = n->sym;
- new_n->u.map_op = new_op;
+ ret_clauses = NULL;
+ omp_clauses = oc->clauses;
- if (!ret_clauses)
- ret_clauses = gfc_get_omp_clauses ();
+ for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
+ {
+ bool ret = false;
+ gfc_omp_map_op new_op;
- if (ret_clauses->lists[OMP_LIST_MAP])
- new_n->next = ret_clauses->lists[OMP_LIST_MAP];
+ switch (n->u.map_op)
+ {
+ case OMP_MAP_ALLOC:
+ case OMP_MAP_FORCE_ALLOC:
+ new_op = OMP_MAP_FORCE_DEALLOC;
+ ret = true;
+ break;
- ret_clauses->lists[OMP_LIST_MAP] = new_n;
- ret = false;
- }
- }
+ case OMP_MAP_DEVICE_RESIDENT:
+ n->u.map_op = OMP_MAP_FORCE_ALLOC;
+ new_op = OMP_MAP_FORCE_DEALLOC;
+ ret = true;
+ break;
- if (!ret_clauses)
- {
- code->next = ns->code;
- ns->code = code;
- return;
- }
+ case OMP_MAP_FORCE_FROM:
+ n->u.map_op = OMP_MAP_FORCE_ALLOC;
+ new_op = OMP_MAP_FORCE_FROM;
+ ret = true;
+ break;
- code2 = XCNEW (gfc_code);
- code2->op = EXEC_OACC_DECLARE;
- code2->loc = where;
- code2->ext.omp_clauses = ret_clauses;
+ case OMP_MAP_FORCE_TO:
+ new_op = OMP_MAP_FORCE_DEALLOC;
+ ret = true;
+ break;
- if (ns->code)
- {
- find_oacc_return (ns->code);
+ case OMP_MAP_FORCE_TOFROM:
+ n->u.map_op = OMP_MAP_FORCE_TO;
+ new_op = OMP_MAP_FORCE_FROM;
+ ret = true;
+ break;
- if (ns->code->op == EXEC_END_PROCEDURE)
- {
- code2->next = ns->code;
- code->next = code2;
- }
- else
- {
- end_c = find_end (ns->code);
- if (end_c)
- {
- code2->next = end_c->next;
- end_c->next = code2;
- code->next = ns->code;
- }
- else
- {
- gfc_code *last;
+ case OMP_MAP_FROM:
+ n->u.map_op = OMP_MAP_FORCE_ALLOC;
+ new_op = OMP_MAP_FROM;
+ ret = true;
+ break;
- last = ns->code;
+ case OMP_MAP_FORCE_DEVICEPTR:
+ case OMP_MAP_FORCE_PRESENT:
+ case OMP_MAP_LINK:
+ case OMP_MAP_TO:
+ break;
- while (last->next)
- last = last->next;
+ case OMP_MAP_TOFROM:
+ n->u.map_op = OMP_MAP_TO;
+ new_op = OMP_MAP_FROM;
+ ret = true;
+ break;
- last->next = code2;
- code->next = ns->code;
- }
- }
- }
- else
- {
- code->next = code2;
- }
+ default:
+ gcc_unreachable ();
+ break;
+ }
- while (oacc_returns)
- {
- struct oacc_return *r;
+ if (ret)
+ {
+ gfc_omp_namelist *new_n;
- r = oacc_returns;
+ new_n = gfc_get_omp_namelist ();
+ new_n->sym = n->sym;
+ new_n->u.map_op = new_op;
- ret_clauses = gfc_get_omp_clauses ();
+ if (!ret_clauses)
+ ret_clauses = gfc_get_omp_clauses ();
- for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
- {
- if (n->u.map_op == OMP_MAP_FORCE_ALLOC
- || n->u.map_op == OMP_MAP_FORCE_TO)
- {
- gfc_omp_namelist *new_n;
+ if (ret_clauses->lists[OMP_LIST_MAP])
+ new_n->next = ret_clauses->lists[OMP_LIST_MAP];
- new_n = gfc_get_omp_namelist ();
- new_n->sym = n->sym;
- new_n->u.map_op = OMP_MAP_FORCE_DEALLOC;
+ ret_clauses->lists[OMP_LIST_MAP] = new_n;
+ ret = false;
+ }
+ }
- if (ret_clauses->lists[OMP_LIST_MAP])
- new_n->next = ret_clauses->lists[OMP_LIST_MAP];
+ code->ext.oacc_declare = gfc_get_oacc_declare ();
+ code->ext.oacc_declare->clauses = omp_clauses;
+ code->ext.oacc_declare->return_clauses = ret_clauses;
- ret_clauses->lists[OMP_LIST_MAP] = new_n;
- }
+ if (ns->code)
+ code->next = ns->code;
+ ns->code = code;
}
-
- code2 = XCNEW (gfc_code);
- code2->op = EXEC_OACC_DECLARE;
- code2->loc = where;
- code2->ext.omp_clauses = ret_clauses;
- code2->next = r->code->next;
- r->code->next = code2;
-
- oacc_returns = r->next;
- free (r);
}
- ns->code = code;
+ return;
}
@@ -4448,7 +4448,7 @@ tree
gfc_trans_oacc_declare (gfc_code *code)
{
stmtblock_t block;
- tree stmt, oacc_clauses;
+ tree stmt, c1, c2;
enum tree_code construct_code;
gfc_start_block (&block);
@@ -4456,11 +4456,15 @@ gfc_trans_oacc_declare (gfc_code *code)
construct_code = OACC_DECLARE;
gfc_start_block (&block);
- oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
- code->loc);
- stmt = build1_loc (input_location, construct_code, void_type_node,
- oacc_clauses);
+ c1 = gfc_trans_omp_clauses (&block, code->ext.oacc_declare->clauses,
+ code->loc);
+
+ c2 = gfc_trans_omp_clauses (&block, code->ext.oacc_declare->return_clauses,
+ code->loc);
+
+ stmt = build2_loc (input_location, construct_code, void_type_node, c1, c2);
gfc_add_expr_to_block (&block, stmt);
+
return gfc_finish_block (&block);
}
@@ -132,7 +132,8 @@ enum acc_region_kind
{
ARK_GENERAL, /* Default used for data, etc. regions. */
ARK_PARALLEL, /* Parallel construct. */
- ARK_KERNELS /* Kernels construct. */
+ ARK_KERNELS, /* Kernels construct. */
+ ARK_DECLARE /* Declare directive. */
};
/* Gimplify hashtable helper. */
@@ -176,6 +177,7 @@ struct gimplify_omp_ctx
enum acc_region_kind acc_region_kind;
bool combined_loop;
bool distribute;
+ gomp_target *stmt;
};
static struct gimplify_ctx *gimplify_ctxp;
@@ -7105,6 +7107,61 @@ gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
*expr_p = NULL_TREE;
}
+/* Gimplify OACC_DECLARE. */
+
+static void
+gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
+{
+ tree expr = *expr_p;
+ gomp_target *stmt;
+ tree clauses, t;
+
+ clauses = OACC_DECLARE_CLAUSES (expr);
+
+ gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, ORK_OACC);
+
+ gimplify_omp_ctxp->acc_region_kind = ARK_DECLARE;
+ gimplify_omp_ctxp->stmt = NULL;
+
+ for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
+ {
+ tree attrs, decl = OMP_CLAUSE_DECL (t);
+
+ if (TREE_CODE (decl) == MEM_REF)
+ continue;
+
+ omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
+
+ attrs = lookup_attribute ("oacc declare", DECL_ATTRIBUTES (decl));
+ if (attrs)
+ DECL_ATTRIBUTES (decl) = remove_attribute ("oacc declare", attrs);
+ }
+
+ stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
+ clauses);
+
+ gimplify_seq_add_stmt (pre_p, stmt);
+
+ clauses = OACC_DECLARE_RETURN_CLAUSES (expr);
+
+ if (clauses)
+ {
+ struct gimplify_omp_ctx *c;
+
+ gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, ORK_OACC);
+
+ c = gimplify_omp_ctxp;
+ gimplify_omp_ctxp = c->outer_context;
+ delete_omp_context (c);
+
+ stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
+ clauses);
+ gimplify_omp_ctxp->stmt = stmt;
+ }
+
+ *expr_p = NULL_TREE;
+}
+
static tree
gimplify_oacc_host_data_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
@@ -7933,10 +7990,6 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
switch (TREE_CODE (expr))
{
- case OACC_DECLARE:
- kind = GF_OMP_TARGET_KIND_OACC_DECLARE;
- ork = ORK_OACC;
- break;
case OACC_ENTER_DATA:
kind = GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA;
ork = ORK_OACC;
@@ -8914,6 +8967,11 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
case OACC_HOST_DATA:
ret = gimplify_oacc_host_data (expr_p, pre_p);
break;
+
+ case OACC_DECLARE:
+ gimplify_oacc_declare (expr_p, pre_p);
+ ret = GS_ALL_DONE;
+ break;
case OACC_KERNELS:
case OACC_PARALLEL:
@@ -8927,7 +8985,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
ret = GS_ALL_DONE;
break;
- case OACC_DECLARE:
case OACC_ENTER_DATA:
case OACC_EXIT_DATA:
case OACC_UPDATE:
@@ -9568,6 +9625,25 @@ gimplify_body (tree fndecl, bool do_parms)
gimplify_seq_add_stmt (&seq, outer_stmt);
}
+ if (flag_openacc && gimplify_omp_ctxp)
+ {
+ while (gimplify_omp_ctxp)
+ {
+ struct gimplify_omp_ctx *c;
+
+ if (gimplify_omp_ctxp->acc_region_kind == ARK_DECLARE
+ && gimplify_omp_ctxp->stmt)
+ {
+ gimplify_seq_add_stmt (&seq, gimplify_omp_ctxp->stmt);
+ gimplify_omp_ctxp->stmt = NULL;
+ }
+
+ c = gimplify_omp_ctxp;
+ gimplify_omp_ctxp = c->outer_context;
+ delete_omp_context (c);
+ }
+ }
+
/* The body must contain exactly one statement, a GIMPLE_BIND. If this is
not the case, wrap everything in a GIMPLE_BIND to make it so. */
if (gimple_code (outer_stmt) == GIMPLE_BIND
@@ -16,4 +16,3 @@ contains
end function foo
end program test
! { dg-final { scan-tree-dump-times "pragma acc declare map\\(force_to:i\\)" 2 "original" } }
-! { dg-final { scan-tree-dump-times "pragma acc declare map\\(force_from:i\\)" 2 "original" } }
@@ -1056,6 +1056,11 @@ DEFTREECODE (OACC_KERNELS, "oacc_kernels", tcc_statement, 2)
DEFTREECODE (OACC_DATA, "oacc_data", tcc_statement, 2)
+/* OpenACC - #pragma acc declare [clause1 ... clauseN]
+ Operand 0: OACC_DECLARE_CLAUSES: List of clauses.
+ Operand 1: OACC_DECLARE_RETURN_CLAUSES: List of clauses for returns. */
+DEFTREECODE (OACC_DECLARE, "oacc_declare", tcc_statement, 2)
+
/* OpenACC - #pragma acc host_data [clause1 ... clauseN]
Operand 0: OACC_HOST_DATA_BODY: Host_data construct body.
Operand 1: OACC_HOST_DATA_CLAUSES: List of clauses. */
@@ -1166,10 +1171,6 @@ DEFTREECODE (OMP_CRITICAL, "omp_critical", tcc_statement, 2)
OMP_CLAUSE__CACHE_ clauses). */
DEFTREECODE (OACC_CACHE, "oacc_cache", tcc_statement, 1)
-/* OpenACC - #pragma acc declare [clause1 ... clauseN]
- Operand 0: OACC_DECLARE_CLAUSES: List of clauses. */
-DEFTREECODE (OACC_DECLARE, "oacc_declare", tcc_statement, 1)
-
/* OpenACC - #pragma acc enter data [clause1 ... clauseN]
Operand 0: OACC_ENTER_DATA_CLAUSES: List of clauses. */
DEFTREECODE (OACC_ENTER_DATA, "oacc_enter_data", tcc_statement, 1)
@@ -1233,6 +1233,8 @@ extern void protected_set_expr_location (tree, location_t);
#define OACC_DECLARE_CLAUSES(NODE) \
TREE_OPERAND (OACC_DECLARE_CHECK (NODE), 0)
+#define OACC_DECLARE_RETURN_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_DECLARE_CHECK (NODE), 1)
#define OACC_ENTER_DATA_CLAUSES(NODE) \
TREE_OPERAND (OACC_ENTER_DATA_CHECK (NODE), 0)
@@ -1,3 +1,4 @@
+/* { dg-do run { target openacc_nvidia_accel_selected } } */
template<class T>
T foo()
@@ -6,6 +6,8 @@ int
main (int argc, char **argv)
{
float a, b;
+ float c;
+#pragma acc declare create (c)
a = 2.0;
b = 0.0;
@@ -60,5 +62,28 @@ main (int argc, char **argv)
if (a != 5.0)
abort ();
+#pragma acc parallel default (none) copy (a)
+ {
+ c = a;
+ a = 1.0;
+ a = a + c;
+ }
+
+ if (a != 6.0)
+ abort ();
+
+#pragma acc data copy (a)
+ {
+#pragma acc parallel default (none)
+ {
+ c = a;
+ a = 1.0;
+ a = a + c;
+ }
+ }
+
+ if (a != 7.0)
+ abort ();
+
return 0;
}
@@ -104,13 +104,11 @@ subroutine subr2 (a, b, c)
end subroutine
-subroutine subr1 (a, b, c)
+subroutine subr1 (a)
integer, parameter :: N = 8
integer :: i
integer :: a(N)
!$acc declare present (a)
- integer :: b(N)
- integer :: c(N)
i = 0
@@ -144,7 +142,7 @@ subroutine subr0 (a, b, c, d)
call test (b, .false.)
call test (c, .false.)
- call subr1 (a, b, c)
+ call subr1 (a)
call test (a, .true.)
call test (b, .false.)
@@ -3,6 +3,8 @@
program main
implicit none
real a, b
+ real c
+ !$acc declare create (c)
a = 2.0
b = 0.0
@@ -31,4 +33,22 @@ program main
if (a .ne. 5.0) call abort
+ !$acc parallel default (none) copy (a)
+ c = a
+ a = 1.0
+ a = a + c
+ !$acc end parallel
+
+ if (a .ne. 6.0) call abort
+
+ !$acc data copy (a)
+ !$acc parallel default (none)
+ c = a
+ a = 1.0
+ a = a + c
+ !$acc end parallel
+ !$acc end data
+
+ if (a .ne. 7.0) call abort
+
end program main