if (n->u2.ns != ns_iter)
{
if (n != n2)
- fputs (list_type == OMP_LIST_AFFINITY
- ? ") AFFINITY(" : ") DEPEND(", dumpfile);
+ {
+ fputs (") ", dumpfile);
+ if (list_type == OMP_LIST_AFFINITY)
+ fputs ("AFFINITY (", dumpfile);
+ else if (n->u.depend_doacross_op == OMP_DOACROSS_SINK_FIRST)
+ fputs ("DOACROSS (", dumpfile);
+ else
+ fputs ("DEPEND (", dumpfile);
+ }
if (n->u2.ns)
{
fputs ("ITERATOR(", dumpfile);
default: break;
}
else if (list_type == OMP_LIST_DEPEND)
- switch (n->u.depend_op)
+ switch (n->u.depend_doacross_op)
{
case OMP_DEPEND_IN: fputs ("in:", dumpfile); break;
case OMP_DEPEND_OUT: fputs ("out:", dumpfile); break;
fputs ("mutexinoutset:", dumpfile);
break;
case OMP_DEPEND_SINK_FIRST:
+ case OMP_DOACROSS_SINK_FIRST:
fputs ("sink:", dumpfile);
while (1)
{
- fprintf (dumpfile, "%s", n->sym->name);
+ if (!n->sym)
+ fputs ("omp_cur_iteration", dumpfile);
+ else
+ fprintf (dumpfile, "%s", n->sym->name);
if (n->expr)
{
fputc ('+', dumpfile);
}
if (n->next == NULL)
break;
- else if (n->next->u.depend_op != OMP_DEPEND_SINK)
+ else if (n->next->u.depend_doacross_op != OMP_DOACROSS_SINK)
{
- fputs (") DEPEND(", dumpfile);
+ if (n->next->u.depend_doacross_op
+ == OMP_DOACROSS_SINK_FIRST)
+ fputs (") DOACROSS(", dumpfile);
+ else
+ fputs (") DEPEND(", dumpfile);
break;
}
fputc (',', dumpfile);
case OMP_LIST_AFFINITY: type = "AFFINITY"; break;
case OMP_LIST_ALIGNED: type = "ALIGNED"; break;
case OMP_LIST_LINEAR: type = "LINEAR"; break;
- case OMP_LIST_DEPEND: type = "DEPEND"; break;
+ case OMP_LIST_DEPEND:
+ if (omp_clauses->lists[list_type]
+ && (omp_clauses->lists[list_type]->u.depend_doacross_op
+ == OMP_DOACROSS_SINK_FIRST))
+ type = "DOACROSS";
+ else
+ type = "DEPEND";
+ break;
case OMP_LIST_MAP: type = "MAP"; break;
case OMP_LIST_TO: type = "TO"; break;
case OMP_LIST_FROM: type = "FROM"; break;
fputs (" DESTROY", dumpfile);
if (omp_clauses->depend_source)
fputs (" DEPEND(source)", dumpfile);
+ if (omp_clauses->doacross_source)
+ fputs (" DOACROSS(source:)", dumpfile);
if (omp_clauses->capture)
fputs (" CAPTURE", dumpfile);
if (omp_clauses->depobj_update != OMP_DEPEND_UNSET)
OMP_REDUCTION_USER
};
-enum gfc_omp_depend_op
+enum gfc_omp_depend_doacross_op
{
OMP_DEPEND_UNSET,
OMP_DEPEND_IN,
OMP_DEPEND_MUTEXINOUTSET,
OMP_DEPEND_DEPOBJ,
OMP_DEPEND_SINK_FIRST,
- OMP_DEPEND_SINK
+ OMP_DOACROSS_SINK_FIRST,
+ OMP_DOACROSS_SINK
};
enum gfc_omp_map_op
union
{
gfc_omp_reduction_op reduction_op;
- gfc_omp_depend_op depend_op;
+ gfc_omp_depend_doacross_op depend_doacross_op;
gfc_omp_map_op map_op;
struct
{
unsigned nowait:1, ordered:1, untied:1, mergeable:1, ancestor:1;
unsigned inbranch:1, notinbranch:1, nogroup:1;
unsigned sched_simd:1, sched_monotonic:1, sched_nonmonotonic:1;
- unsigned simd:1, threads:1, depend_source:1, destroy:1, order_concurrent:1;
+ unsigned simd:1, threads:1, doacross_source:1, depend_source:1, destroy:1;
unsigned order_unconstrained:1, order_reproducible:1, capture:1;
unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1;
- unsigned non_rectangular:1;
+ unsigned non_rectangular:1, order_concurrent:1;
ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3;
ENUM_BITFIELD (gfc_omp_device_type) device_type:2;
ENUM_BITFIELD (gfc_omp_memorder) memorder:3;
ENUM_BITFIELD (gfc_omp_memorder) fail:3;
ENUM_BITFIELD (gfc_omp_cancel_kind) cancel:3;
ENUM_BITFIELD (gfc_omp_proc_bind_kind) proc_bind:3;
- ENUM_BITFIELD (gfc_omp_depend_op) depobj_update:4;
+ ENUM_BITFIELD (gfc_omp_depend_doacross_op) depobj_update:4;
ENUM_BITFIELD (gfc_omp_bind_type) bind:2;
ENUM_BITFIELD (gfc_omp_at_type) at:2;
ENUM_BITFIELD (gfc_omp_severity_type) severity:2;
}
-/* Match depend(sink : ...) construct a namelist from it. */
+/* Match doacross(sink : ...) construct a namelist from it;
+ if depend is true, match legacy 'depend(sink : ...)'. */
static match
-gfc_match_omp_depend_sink (gfc_omp_namelist **list)
+gfc_match_omp_doacross_sink (gfc_omp_namelist **list, bool depend)
{
+ char n[GFC_MAX_SYMBOL_LEN+1];
gfc_omp_namelist *head, *tail, *p;
locus old_loc, cur_loc;
gfc_symbol *sym;
for (;;)
{
cur_loc = gfc_current_locus;
- switch (gfc_match_symbol (&sym, 1))
+
+ if (gfc_match_name (n) != MATCH_YES)
+ goto syntax;
+ if (UNLIKELY (strcmp (n, "omp_all_memory") == 0))
{
- case MATCH_YES:
- gfc_set_sym_referenced (sym);
- p = gfc_get_omp_namelist ();
- if (head == NULL)
- {
- head = tail = p;
- head->u.depend_op = OMP_DEPEND_SINK_FIRST;
- }
- else
- {
- tail->next = p;
- tail = tail->next;
- tail->u.depend_op = OMP_DEPEND_SINK;
- }
- tail->sym = sym;
- tail->expr = NULL;
- tail->where = cur_loc;
- if (UNLIKELY (strcmp (sym->name, "omp_all_memory") == 0))
- {
- gfc_error ("%<omp_all_memory%> used with DEPEND kind "
- "other than OUT or INOUT at %C");
- goto cleanup;
- }
- if (gfc_match_char ('+') == MATCH_YES)
- {
- if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
- goto syntax;
- }
- else if (gfc_match_char ('-') == MATCH_YES)
- {
- if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
- goto syntax;
- tail->expr = gfc_uminus (tail->expr);
- }
- break;
- case MATCH_NO:
- goto syntax;
- case MATCH_ERROR:
+ gfc_error ("%<omp_all_memory%> used with dependence-type "
+ "other than OUT or INOUT at %C");
goto cleanup;
}
-
+ sym = NULL;
+ if (!(strcmp (n, "omp_cur_iteration") == 0))
+ {
+ gfc_symtree *st;
+ if (gfc_get_ha_sym_tree (n, &st))
+ goto syntax;
+ sym = st->n.sym;
+ gfc_set_sym_referenced (sym);
+ }
+ p = gfc_get_omp_namelist ();
+ if (head == NULL)
+ {
+ head = tail = p;
+ head->u.depend_doacross_op = (depend ? OMP_DEPEND_SINK_FIRST
+ : OMP_DOACROSS_SINK_FIRST);
+ }
+ else
+ {
+ tail->next = p;
+ tail = tail->next;
+ tail->u.depend_doacross_op = OMP_DOACROSS_SINK;
+ }
+ tail->sym = sym;
+ tail->expr = NULL;
+ tail->where = cur_loc;
+ if (gfc_match_char ('+') == MATCH_YES)
+ {
+ if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
+ goto syntax;
+ }
+ else if (gfc_match_char ('-') == MATCH_YES)
+ {
+ if (gfc_match_literal_constant (&tail->expr, 0) != MATCH_YES)
+ goto syntax;
+ tail->expr = gfc_uminus (tail->expr);
+ }
if (gfc_match_char (')') == MATCH_YES)
break;
if (gfc_match_char (',') != MATCH_YES)
return MATCH_YES;
syntax:
- gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C");
+ gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C");
cleanup:
gfc_free_omp_namelist (head, false);
OMP_CLAUSE_NOHOST,
OMP_CLAUSE_HAS_DEVICE_ADDR, /* OpenMP 5.1 */
OMP_CLAUSE_ENTER, /* OpenMP 5.2 */
+ OMP_CLAUSE_DOACROSS, /* OpenMP 5.2 */
/* This must come last. */
OMP_MASK2_LAST
};
OMP_MAP_RELEASE, true,
allow_derived))
continue;
- if ((mask & OMP_CLAUSE_DEPEND)
- && gfc_match ("depend ( ") == MATCH_YES)
+ /* DOACROSS: match 'doacross' and 'depend' with sink/source.
+ DEPEND: match 'depend' but not sink/source. */
+ m = MATCH_NO;
+ if (((mask & OMP_CLAUSE_DOACROSS)
+ && gfc_match ("doacross ( ") == MATCH_YES)
+ || (((mask & OMP_CLAUSE_DEPEND) || (mask & OMP_CLAUSE_DOACROSS))
+ && (m = gfc_match ("depend ( ")) == MATCH_YES))
{
bool has_omp_all_memory;
+ bool is_depend = m == MATCH_YES;
gfc_namespace *ns_iter = NULL, *ns_curr = gfc_current_ns;
- match m_it = gfc_match_iterator (&ns_iter, false);
+ match m_it = MATCH_NO;
+ if (is_depend)
+ m_it = gfc_match_iterator (&ns_iter, false);
if (m_it == MATCH_ERROR)
break;
if (m_it == MATCH_YES && gfc_match (" , ") != MATCH_YES)
break;
m = MATCH_YES;
- gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
+ gfc_omp_depend_doacross_op depend_op = OMP_DEPEND_OUT;
if (gfc_match ("inoutset") == MATCH_YES)
depend_op = OMP_DEPEND_INOUTSET;
else if (gfc_match ("inout") == MATCH_YES)
depend_op = OMP_DEPEND_MUTEXINOUTSET;
else if (gfc_match ("depobj") == MATCH_YES)
depend_op = OMP_DEPEND_DEPOBJ;
- else if (!c->depend_source
- && gfc_match ("source )") == MATCH_YES)
+ else if (gfc_match ("source") == MATCH_YES)
{
if (m_it == MATCH_YES)
{
gfc_error ("ITERATOR may not be combined with SOURCE "
"at %C");
- gfc_free_omp_clauses (c);
- return MATCH_ERROR;
+ goto error;
+ }
+ if (!(mask & OMP_CLAUSE_DOACROSS))
+ {
+ gfc_error ("SOURCE at %C not permitted as dependence-type"
+ " for this directive");
+ goto error;
+ }
+ if (c->doacross_source)
+ {
+ gfc_error ("Duplicated clause with SOURCE dependence-type"
+ " at %C");
+ goto error;
+ }
+ gfc_gobble_whitespace ();
+ m = gfc_match (": ");
+ if (m != MATCH_YES && !is_depend)
+ {
+ gfc_error ("Expected %<:%> at %C");
+ goto error;
}
- c->depend_source = true;
+ if (gfc_match (")") != MATCH_YES
+ && !(m == MATCH_YES
+ && gfc_match ("omp_cur_iteration )") == MATCH_YES))
+ {
+ gfc_error ("Expected %<)%> or %<omp_cur_iteration)%> "
+ "at %C");
+ goto error;
+ }
+ c->doacross_source = true;
+ c->depend_source = is_depend;
continue;
}
- else if (gfc_match ("sink : ") == MATCH_YES)
+ else if (gfc_match ("sink ") == MATCH_YES)
{
+ if (!(mask & OMP_CLAUSE_DOACROSS))
+ {
+ gfc_error ("SINK at %C not permitted as dependence-type "
+ "for this directive");
+ goto error;
+ }
+ if (gfc_match (": ") != MATCH_YES)
+ {
+ gfc_error ("Expected %<:%> at %C");
+ goto error;
+ }
if (m_it == MATCH_YES)
{
gfc_error ("ITERATOR may not be combined with SINK "
"at %C");
- break;
+ goto error;
}
- if (gfc_match_omp_depend_sink (&c->lists[OMP_LIST_DEPEND])
- == MATCH_YES)
+ m = gfc_match_omp_doacross_sink (&c->lists[OMP_LIST_DEPEND],
+ is_depend);
+ if (m == MATCH_YES)
continue;
- m = MATCH_NO;
+ goto error;
}
else
m = MATCH_NO;
+ if (!(mask & OMP_CLAUSE_DEPEND))
+ {
+ gfc_error ("Expected dependence-type SINK or SOURCE at %C");
+ goto error;
+ }
head = NULL;
if (ns_iter)
gfc_current_ns = ns_iter;
gfc_omp_namelist *n;
for (n = *head; n; n = n->next)
{
- n->u.depend_op = depend_op;
+ n->u.depend_doacross_op = depend_op;
n->u2.ns = ns_iter;
if (ns_iter)
ns_iter->refs++;
if (c->depobj_update == OMP_DEPEND_UNSET && !c->destroy)
{
- if (!c->depend_source && !c->lists[OMP_LIST_DEPEND])
+ if (!c->doacross_source && !c->lists[OMP_LIST_DEPEND])
{
gfc_error ("Expected DEPEND, UPDATE, or DESTROY clause at %C");
goto error;
}
- if (c->depend_source
- || c->lists[OMP_LIST_DEPEND]->u.depend_op == OMP_DEPEND_SINK_FIRST
- || c->lists[OMP_LIST_DEPEND]->u.depend_op == OMP_DEPEND_SINK
- || c->lists[OMP_LIST_DEPEND]->u.depend_op == OMP_DEPEND_DEPOBJ)
+ if (c->lists[OMP_LIST_DEPEND]->u.depend_doacross_op == OMP_DEPEND_DEPOBJ)
{
gfc_error ("DEPEND clause at %L of OMP DEPOBJ construct shall not "
- "have dependence-type SOURCE, SINK or DEPOBJ",
+ "have dependence-type DEPOBJ",
c->lists[OMP_LIST_DEPEND]
? &c->lists[OMP_LIST_DEPEND]->where : &gfc_current_locus);
goto error;
match
gfc_match_omp_ordered_depend (void)
{
- return match_omp (EXEC_OMP_ORDERED, omp_mask (OMP_CLAUSE_DEPEND));
+ return match_omp (EXEC_OMP_ORDERED, omp_mask (OMP_CLAUSE_DOACROSS));
}
if (list == OMP_LIST_DEPEND)
{
- if (n->u.depend_op == OMP_DEPEND_SINK_FIRST
- || n->u.depend_op == OMP_DEPEND_SINK)
+ if (n->u.depend_doacross_op == OMP_DEPEND_SINK_FIRST
+ || n->u.depend_doacross_op == OMP_DOACROSS_SINK_FIRST
+ || n->u.depend_doacross_op == OMP_DOACROSS_SINK)
{
- if (code->op != EXEC_OMP_ORDERED)
- gfc_error ("SINK dependence type only allowed "
- "on ORDERED directive at %L", &n->where);
- else if (omp_clauses->depend_source)
+ if (omp_clauses->doacross_source)
{
- gfc_error ("DEPEND SINK used together with "
- "DEPEND SOURCE on the same construct "
- "at %L", &n->where);
- omp_clauses->depend_source = false;
+ gfc_error ("Dependence-type SINK used together with"
+ " SOURCE on the same construct at %L",
+ &n->where);
+ omp_clauses->doacross_source = false;
}
else if (n->expr)
{
gfc_error ("SINK addend not a constant integer "
"at %L", &n->where);
}
+ if (n->sym == NULL
+ && (n->expr == NULL
+ || mpz_cmp_si (n->expr->value.integer, -1) != 0))
+ gfc_error ("omp_cur_iteration at %L requires %<-1%> "
+ "as logical offset", &n->where);
continue;
}
- else if (code->op == EXEC_OMP_ORDERED)
- gfc_error ("Only SOURCE or SINK dependence types "
- "are allowed on ORDERED directive at %L",
- &n->where);
- else if (n->u.depend_op == OMP_DEPEND_DEPOBJ
+ else if (n->u.depend_doacross_op == OMP_DEPEND_DEPOBJ
&& !n->expr
&& (n->sym->ts.type != BT_INTEGER
|| n->sym->ts.kind
"type shall be a scalar integer of "
"OMP_DEPEND_KIND kind", n->sym->name,
&n->where);
- else if (n->u.depend_op == OMP_DEPEND_DEPOBJ
+ else if (n->u.depend_doacross_op == OMP_DEPEND_DEPOBJ
&& n->expr
&& (!gfc_resolve_expr (n->expr)
|| n->expr->ts.type != BT_INTEGER
resolve_scalar_int_expr (el->expr, "WAIT");
if (omp_clauses->collapse && omp_clauses->tile_list)
gfc_error ("Incompatible use of TILE and COLLAPSE at %L", &code->loc);
- if (omp_clauses->depend_source && code->op != EXEC_OMP_ORDERED)
- gfc_error ("SOURCE dependence type only allowed "
- "on ORDERED directive at %L", &code->loc);
if (omp_clauses->message)
{
gfc_expr *expr = omp_clauses->message;
case EXEC_OMP_CANCEL:
case EXEC_OMP_ERROR:
case EXEC_OMP_MASKED:
+ case EXEC_OMP_ORDERED:
case EXEC_OMP_PARALLEL_WORKSHARE:
case EXEC_OMP_PARALLEL:
case EXEC_OMP_PARALLEL_MASKED:
matcho ("loop", gfc_match_omp_loop, ST_OMP_LOOP);
break;
case 'o':
- if (gfc_match ("ordered depend (") == MATCH_YES)
+ if (gfc_match ("ordered depend (") == MATCH_YES
+ || gfc_match ("ordered doacross (") == MATCH_YES)
{
gfc_current_locus = old_locus;
if (!flag_openmp)
gfc_init_block (&iter_block);
prev = n;
if (list == OMP_LIST_DEPEND
- && n->u.depend_op == OMP_DEPEND_SINK_FIRST)
+ && (n->u.depend_doacross_op == OMP_DOACROSS_SINK_FIRST
+ || n->u.depend_doacross_op == OMP_DEPEND_SINK_FIRST))
{
tree vec = NULL_TREE;
unsigned int i;
+ bool is_depend
+ = n->u.depend_doacross_op == OMP_DEPEND_SINK_FIRST;
for (i = 0; ; i++)
{
tree addend = integer_zero_node, t;
bool neg = false;
- if (n->expr)
+ if (n->sym && n->expr)
{
addend = gfc_conv_constant_to_tree (n->expr);
if (TREE_CODE (addend) == INTEGER_CST
TREE_TYPE (addend), addend);
}
}
- t = gfc_trans_omp_variable (n->sym, false);
+
+ if (n->sym == NULL)
+ t = null_pointer_node; /* "omp_cur_iteration - 1". */
+ else
+ t = gfc_trans_omp_variable (n->sym, false);
if (t != error_mark_node)
{
if (i < vec_safe_length (doacross_steps)
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
}
if (n->next == NULL
- || n->next->u.depend_op != OMP_DEPEND_SINK)
+ || n->next->u.depend_doacross_op != OMP_DOACROSS_SINK)
break;
n = n->next;
}
tree node = build_omp_clause (input_location,
OMP_CLAUSE_DOACROSS);
OMP_CLAUSE_DOACROSS_KIND (node) = OMP_CLAUSE_DOACROSS_SINK;
- OMP_CLAUSE_DOACROSS_DEPEND (node) = 1;
+ OMP_CLAUSE_DOACROSS_DEPEND (node) = is_depend;
OMP_CLAUSE_DECL (node) = nreverse (vec);
omp_clauses = gfc_trans_add_clause (node, omp_clauses);
continue;
OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
}
if (list == OMP_LIST_DEPEND)
- switch (n->u.depend_op)
+ switch (n->u.depend_doacross_op)
{
case OMP_DEPEND_IN:
OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
- if (clauses->depend_source)
+ if (clauses->doacross_source)
{
c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DOACROSS);
OMP_CLAUSE_DOACROSS_KIND (c) = OMP_CLAUSE_DOACROSS_SOURCE;
- OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
+ OMP_CLAUSE_DOACROSS_DEPEND (c) = clauses->depend_source;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
init = make_tree_vec (collapse);
cond = make_tree_vec (collapse);
incr = make_tree_vec (collapse);
- orig_decls = clauses->orderedc ? make_tree_vec (collapse) : NULL_TREE;
+ orig_decls = clauses->ordered ? make_tree_vec (collapse) : NULL_TREE;
if (pblock == NULL)
{
MODIFY_EXPR,
type, dovar,
TREE_VEC_ELT (incr, i));
+ if (orig_decls && !clauses->orderedc)
+ orig_decls = NULL;
+ else if (orig_decls)
+ TREE_VEC_ELT (orig_decls, i) = dovar_decl;
}
else
{
vec_safe_grow_cleared (doacross_steps, clauses->orderedc, true);
(*doacross_steps)[i] = step;
}
+ if (orig_decls)
+ TREE_VEC_ELT (orig_decls, i) = dovar_decl;
}
- if (orig_decls)
- TREE_VEC_ELT (orig_decls, i) = dovar_decl;
if (dovar_found == 3
&& op == EXEC_OMP_SIMD
int k = -1; /* omp_clauses->destroy */
if (!code->ext.omp_clauses->destroy)
switch (code->ext.omp_clauses->depobj_update != OMP_DEPEND_UNSET
- ? code->ext.omp_clauses->depobj_update : n->u.depend_op)
+ ? code->ext.omp_clauses->depobj_update : n->u.depend_doacross_op)
{
case OMP_DEPEND_IN: k = GOMP_DEPEND_IN; break;
case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break;
!$omp target depend ( depobj : omp_all_memory) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
!!$omp end target
- !$omp ordered depend ( sink : omp_all_memory) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
+ !$omp ordered depend ( sink : omp_all_memory) ! { dg-error "used with dependence-type other than OUT or INOUT" }
end
!!$omp end task
!$omp task depend(iterator(i=1:5), source ) ! { dg-error "ITERATOR may not be combined with SOURCE" }
!!$omp end task
- !$omp task affinity (iterator(i=1:5): a) depend(iterator(i=1:5), sink : x) ! { dg-error "ITERATOR may not be combined with SINK" }
+ !$omp task affinity (iterator(i=1:5): a) depend(iterator(i=1:5), sink : x) ! { dg-error "SINK at .1. not permitted as dependence-type for this directive" }
!!$omp end task
end do
!$omp depobj(d) depend( inout : a) ! { dg-error "DEPOBJ in DEPOBJ construct at .1. shall be a scalar integer of OMP_DEPEND_KIND kind" }
!$omp depobj(depobj) depend( inout : a, b) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall have only a single locator" }
!$omp depobj(depobj) depend(mutexinoutset : a) ! OK
- !$omp depobj(depobj) depend(source) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
- !$omp depobj(depobj) depend(sink : i + 1) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
+ !$omp depobj(depobj) depend(source) ! { dg-error "SOURCE at .1. not permitted as dependence-type for this directive" }
+ !$omp depobj(depobj) depend(sink : i + 1) ! { dg-error "SINK at .1. not permitted as dependence-type for this directive" }
!$omp depobj(depobj) update(source) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(sink) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(depobj) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
! Valid in OpenMP 5.1:
- !$omp depobj(depobj5) depend(depobj: depobj3) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
+ !$omp depobj(depobj5) depend(depobj: depobj3) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type DEPOBJ" }
end subroutine f1
--- /dev/null
+subroutine foo (n)
+ integer i, n
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(source:)
+ !$omp ordered doacross(sink: i - 2)
+ end do
+end
+
+subroutine bar (n)
+ integer :: i, j, n
+
+ !$omp do collapse(2) ordered(2)
+ do i = 1, 8, n
+ do j = 1, 8, n
+ !$omp ordered doacross(source:omp_cur_iteration)
+ !$omp ordered doacross(sink: i - 2, j + 2)
+ end do
+ end do
+end
+
+subroutine baz ()
+ integer :: i, j
+
+ !$omp do ordered(1)
+ do i = 1, 64
+ !$omp ordered ! { dg-error "'ordered' construct without 'doacross' or 'depend' clauses must not have the same binding region as 'ordered' construct with those clauses" }
+ !$omp end ordered
+
+ !$omp ordered doacross(source:)
+
+ !$omp ordered doacross(sink: i - 1)
+ end do
+
+ !$omp do ordered
+ do i = 1, 64
+ !$omp ordered doacross(source: omp_cur_iteration )
+
+ !$omp ordered doacross(sink: i - 1)
+
+ !$omp ordered threads ! { dg-error "'ordered' construct without 'doacross' or 'depend' clauses must not have the same binding region as 'ordered' construct with those clauses" }
+ !$omp end ordered
+ end do
+ !$omp do ordered(2)
+ do i = 1, 64
+ do j = 1, 64
+ !$omp ordered ! { dg-error "'ordered' construct without 'doacross' or 'depend' clauses binds to loop where 'collapse' argument 1 is different from 'ordered' argument 2" }
+ !$omp end ordered
+ end do
+ end do
+ !$omp do ordered(2) collapse(1)
+ do i = 1, 8
+ do j = 1, 8
+ !$omp ordered threads ! { dg-error "'ordered' construct without 'doacross' or 'depend' clauses binds to loop where 'collapse' argument 1 is different from 'ordered' argument 2" }
+ !$omp end ordered
+ end do
+ end do
+end
+
+subroutine qux ()
+ integer :: i, j
+ j = 0
+ !$omp do ordered linear(j)
+ do i = 1, 64
+ j = j + 1
+ !$omp ordered
+ !$omp end ordered
+ end do
+ !$omp do ordered linear(j) ! { dg-error "'linear' clause may not be specified together with 'ordered' clause if stand-alone 'ordered' construct is nested in it" }
+ do i = 1, 64
+ j = j + 1
+ !$omp ordered doacross(source:)
+ !$omp ordered doacross(sink:i-1)
+ end do
+ !$omp do ordered(1) linear(j)
+ do i = 1, 64
+ j = j + 1
+ !$omp ordered
+ !$omp end ordered
+ end do
+ !$omp do ordered(1) linear(j) ! { dg-error "'linear' clause may not be specified together with 'ordered' clause if stand-alone 'ordered' construct is nested in it" }
+ do i = 1, 64
+ j = j + 1
+ !$omp ordered doacross(source:)
+ !$omp ordered doacross(sink:i-1)
+ end do
+end
--- /dev/null
+subroutine foo (n)
+ integer :: i, n
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(source) ! { dg-error "Expected ':'" }
+ end do
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(source:omp_current_iteration) ! { dg-error "Expected '\\\)' or 'omp_cur_iteration\\\)'" }
+ end do
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(source:i - 2) ! { dg-error "Expected '\\\)' or 'omp_cur_iteration\\\)'" }
+ end do
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink) ! { dg-error "Expected ':'" }
+ end do
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:) ! { dg-error "Syntax error in OpenMP SINK dependence-type list" }
+ end do
+end
+
+subroutine bar (n)
+ implicit none
+ integer i, n
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:omp_current_iteration - 1) ! { dg-error "Symbol 'omp_current_iteration' at .1. has no IMPLICIT type" }
+ end do
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:omp_cur_iteration) ! { dg-error "omp_cur_iteration at .1. requires '-1' as logical offset" }
+ end do
+end
+
+subroutine baz (n)
+ implicit none
+ integer i, n
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:omp_cur_iteration + 1) ! { dg-error "omp_cur_iteration at .1. requires '-1' as logical offset" }
+ end do
+end
+
+subroutine qux (n)
+ implicit none
+ integer i, n
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:omp_cur_iteration - (2 - 1)) ! { dg-error "Syntax error in OpenMP SINK dependence-type list" }
+ end do
+end
+
+subroutine corge (n)
+ implicit none
+ integer i, n
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:omp_cur_iteration - 1)
+ end do
+
+ !$omp do ordered
+ do i = 1, 8, n
+ !$omp ordered doacross(sink:omp_cur_iteration - 1_8)
+ end do
+end
@item Default map-type for @code{map} clause in @code{target enter/exit data}
@tab Y @tab
@item New @code{doacross} clause as alias for @code{depend} with
- @code{source}/@code{sink} modifier @tab N @tab
+ @code{source}/@code{sink} modifier @tab Y @tab
@item Deprecation of @code{depend} with @code{source}/@code{sink} modifier
@tab N @tab
-@item @code{omp_cur_iteration} keyword @tab N @tab
+@item @code{omp_cur_iteration} keyword @tab P
+ @tab @code{sink: omp_cur_iteration - 1} unsupported
@end multitable
@unnumberedsubsec Other new OpenMP 5.2 features