aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/openmp.c
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2020-11-10 18:28:18 +0100
committerTobias Burnus <tobias@codesourcery.com>2020-11-10 18:28:18 +0100
commite929ef532ad52cde873dfc0849907b020ffc5afd (patch)
tree095a8e137a565634c9bfe46eb4542a857a21c539 /gcc/fortran/openmp.c
parent2cca9751700946f1398fc3bcb96d529bb2964f0f (diff)
downloadgcc-e929ef532ad52cde873dfc0849907b020ffc5afd.zip
gcc-e929ef532ad52cde873dfc0849907b020ffc5afd.tar.gz
gcc-e929ef532ad52cde873dfc0849907b020ffc5afd.tar.bz2
Fortran: OpenMP 5.0 (in_,task_)reduction clause extensions
gcc/fortran/ChangeLog: * dump-parse-tree.c (show_omp_clauses): Handle new reduction enums. * gfortran.h (OMP_LIST_REDUCTION_INSCAN, OMP_LIST_REDUCTION_TASK, OMP_LIST_IN_REDUCTION, OMP_LIST_TASK_REDUCTION): Add enums. * openmp.c (enum omp_mask1): Add OMP_CLAUSE_IN_REDUCTION and OMP_CLAUSE_TASK_REDUCTION. (gfc_match_omp_clause_reduction): Extend reduction handling; moved from ... (gfc_match_omp_clauses): ... here. Add calls to it. (OMP_TASK_CLAUSES, OMP_TARGET_CLAUSES, OMP_TASKLOOP_CLAUSES): Add OMP_CLAUSE_IN_REDUCTION. (gfc_match_omp_taskgroup): Add task_reduction matching. (resolve_omp_clauses): Update for new reduction clause changes; remove removed nonmonotonic-schedule restrictions. (gfc_resolve_omp_parallel_blocks): Add new enums to switch. * trans-openmp.c (gfc_omp_clause_default_ctor, gfc_trans_omp_reduction_list, gfc_trans_omp_clauses, gfc_split_omp_clauses): Handle updated reduction clause. gcc/ChangeLog: * gimplify.c (gimplify_scan_omp_clauses, gimplify_omp_loop): Use 'do' instead of 'for' in error messages for Fortran. * omp-low.c (check_omp_nesting_restrictions): Likewise gcc/testsuite/ChangeLog: * gfortran.dg/gomp/schedule-modifiers-2.f90: Remove some dg-error. * gfortran.dg/gomp/reduction4.f90: New test. * gfortran.dg/gomp/reduction5.f90: New test. * gfortran.dg/gomp/workshare-reduction-1.f90: New test. * gfortran.dg/gomp/workshare-reduction-2.f90: New test. * gfortran.dg/gomp/workshare-reduction-3.f90: New test. * gfortran.dg/gomp/workshare-reduction-4.f90: New test. * gfortran.dg/gomp/workshare-reduction-5.f90: New test. * gfortran.dg/gomp/workshare-reduction-6.f90: New test. * gfortran.dg/gomp/workshare-reduction-7.f90: New test. * gfortran.dg/gomp/workshare-reduction-8.f90: New test. * gfortran.dg/gomp/workshare-reduction-9.f90: New test. * gfortran.dg/gomp/workshare-reduction-10.f90: New test. * gfortran.dg/gomp/workshare-reduction-11.f90: New test. * gfortran.dg/gomp/workshare-reduction-12.f90: New test. * gfortran.dg/gomp/workshare-reduction-13.f90: New test. * gfortran.dg/gomp/workshare-reduction-14.f90: New test. * gfortran.dg/gomp/workshare-reduction-15.f90: New test. * gfortran.dg/gomp/workshare-reduction-16.f90: New test. * gfortran.dg/gomp/workshare-reduction-17.f90: New test. * gfortran.dg/gomp/workshare-reduction-18.f90: New test. * gfortran.dg/gomp/workshare-reduction-19.f90: New test. * gfortran.dg/gomp/workshare-reduction-20.f90: New test. * gfortran.dg/gomp/workshare-reduction-21.f90: New test. * gfortran.dg/gomp/workshare-reduction-22.f90: New test. * gfortran.dg/gomp/workshare-reduction-23.f90: New test. * gfortran.dg/gomp/workshare-reduction-24.f90: New test. * gfortran.dg/gomp/workshare-reduction-25.f90: New test. * gfortran.dg/gomp/workshare-reduction-26.f90: New test. * gfortran.dg/gomp/workshare-reduction-27.f90: New test. * gfortran.dg/gomp/workshare-reduction-28.f90: New test. * gfortran.dg/gomp/workshare-reduction-29.f90: New test. * gfortran.dg/gomp/workshare-reduction-30.f90: New test. * gfortran.dg/gomp/workshare-reduction-31.f90: New test. * gfortran.dg/gomp/workshare-reduction-32.f90: New test. * gfortran.dg/gomp/workshare-reduction-33.f90: New test. * gfortran.dg/gomp/workshare-reduction-34.f90: New test. * gfortran.dg/gomp/workshare-reduction-35.f90: New test. * gfortran.dg/gomp/workshare-reduction-36.f90: New test. * gfortran.dg/gomp/workshare-reduction-37.f90: New test. * gfortran.dg/gomp/workshare-reduction-38.f90: New test. * gfortran.dg/gomp/workshare-reduction-39.f90: New test. * gfortran.dg/gomp/workshare-reduction-40.f90: New test. * gfortran.dg/gomp/workshare-reduction-41.f90: New test. * gfortran.dg/gomp/workshare-reduction-42.f90: New test. * gfortran.dg/gomp/workshare-reduction-43.f90: New test. * gfortran.dg/gomp/workshare-reduction-44.f90: New test. * gfortran.dg/gomp/workshare-reduction-45.f90: New test. * gfortran.dg/gomp/workshare-reduction-46.f90: New test. * gfortran.dg/gomp/workshare-reduction-47.f90: New test. * gfortran.dg/gomp/workshare-reduction-48.f90: New test. * gfortran.dg/gomp/workshare-reduction-49.f90: New test. * gfortran.dg/gomp/workshare-reduction-50.f90: New test. * gfortran.dg/gomp/workshare-reduction-51.f90: New test. * gfortran.dg/gomp/workshare-reduction-52.f90: New test. * gfortran.dg/gomp/workshare-reduction-53.f90: New test. * gfortran.dg/gomp/workshare-reduction-54.f90: New test. * gfortran.dg/gomp/workshare-reduction-55.f90: New test. * gfortran.dg/gomp/workshare-reduction-56.f90: New test. * gfortran.dg/gomp/workshare-reduction-57.f90: New test. * gfortran.dg/gomp/workshare-reduction-58.f90: New test.
Diffstat (limited to 'gcc/fortran/openmp.c')
-rw-r--r--gcc/fortran/openmp.c377
1 files changed, 230 insertions, 147 deletions
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 2270c85..68d0b65 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -762,6 +762,8 @@ enum omp_mask1
OMP_CLAUSE_SHARED,
OMP_CLAUSE_COPYIN,
OMP_CLAUSE_REDUCTION,
+ OMP_CLAUSE_IN_REDUCTION,
+ OMP_CLAUSE_TASK_REDUCTION,
OMP_CLAUSE_IF,
OMP_CLAUSE_NUM_THREADS,
OMP_CLAUSE_SCHEDULE,
@@ -959,6 +961,163 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op,
return false;
}
+/* reduction ( reduction-modifier, reduction-operator : variable-list )
+ in_reduction ( reduction-operator : variable-list )
+ task_reduction ( reduction-operator : variable-list ) */
+
+static match
+gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
+ bool allow_derived)
+{
+ if (pc == 'r' && gfc_match ("reduction ( ") != MATCH_YES)
+ return MATCH_NO;
+ else if (pc == 'i' && gfc_match ("in_reduction ( ") != MATCH_YES)
+ return MATCH_NO;
+ else if (pc == 't' && gfc_match ("task_reduction ( ") != MATCH_YES)
+ return MATCH_NO;
+
+ locus old_loc = gfc_current_locus;
+ int list_idx = 0;
+
+ if (pc == 'r' && !openacc)
+ {
+ if (gfc_match ("inscan") == MATCH_YES)
+ list_idx = OMP_LIST_REDUCTION_INSCAN;
+ else if (gfc_match ("task") == MATCH_YES)
+ list_idx = OMP_LIST_REDUCTION_TASK;
+ else if (gfc_match ("default") == MATCH_YES)
+ list_idx = OMP_LIST_REDUCTION;
+ if (list_idx != 0 && gfc_match (", ") != MATCH_YES)
+ {
+ gfc_error ("Comma expected at %C");
+ gfc_current_locus = old_loc;
+ return MATCH_NO;
+ }
+ if (list_idx == 0)
+ list_idx = OMP_LIST_REDUCTION;
+ }
+ else if (pc == 'i')
+ list_idx = OMP_LIST_IN_REDUCTION;
+ else if (pc == 't')
+ list_idx = OMP_LIST_TASK_REDUCTION;
+ else
+ list_idx = OMP_LIST_REDUCTION;
+
+ gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
+ char buffer[GFC_MAX_SYMBOL_LEN + 3];
+ if (gfc_match_char ('+') == MATCH_YES)
+ rop = OMP_REDUCTION_PLUS;
+ else if (gfc_match_char ('*') == MATCH_YES)
+ rop = OMP_REDUCTION_TIMES;
+ else if (gfc_match_char ('-') == MATCH_YES)
+ rop = OMP_REDUCTION_MINUS;
+ else if (gfc_match (".and.") == MATCH_YES)
+ rop = OMP_REDUCTION_AND;
+ else if (gfc_match (".or.") == MATCH_YES)
+ rop = OMP_REDUCTION_OR;
+ else if (gfc_match (".eqv.") == MATCH_YES)
+ rop = OMP_REDUCTION_EQV;
+ else if (gfc_match (".neqv.") == MATCH_YES)
+ rop = OMP_REDUCTION_NEQV;
+ if (rop != OMP_REDUCTION_NONE)
+ snprintf (buffer, sizeof buffer, "operator %s",
+ gfc_op2string ((gfc_intrinsic_op) rop));
+ else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
+ {
+ buffer[0] = '.';
+ strcat (buffer, ".");
+ }
+ else if (gfc_match_name (buffer) == MATCH_YES)
+ {
+ gfc_symbol *sym;
+ const char *n = buffer;
+
+ gfc_find_symbol (buffer, NULL, 1, &sym);
+ if (sym != NULL)
+ {
+ if (sym->attr.intrinsic)
+ n = sym->name;
+ else if ((sym->attr.flavor != FL_UNKNOWN
+ && sym->attr.flavor != FL_PROCEDURE)
+ || sym->attr.external
+ || sym->attr.generic
+ || sym->attr.entry
+ || sym->attr.result
+ || sym->attr.dummy
+ || sym->attr.subroutine
+ || sym->attr.pointer
+ || sym->attr.target
+ || sym->attr.cray_pointer
+ || sym->attr.cray_pointee
+ || (sym->attr.proc != PROC_UNKNOWN
+ && sym->attr.proc != PROC_INTRINSIC)
+ || sym->attr.if_source != IFSRC_UNKNOWN
+ || sym == sym->ns->proc_name)
+ {
+ sym = NULL;
+ n = NULL;
+ }
+ else
+ n = sym->name;
+ }
+ if (n == NULL)
+ rop = OMP_REDUCTION_NONE;
+ else if (strcmp (n, "max") == 0)
+ rop = OMP_REDUCTION_MAX;
+ else if (strcmp (n, "min") == 0)
+ rop = OMP_REDUCTION_MIN;
+ else if (strcmp (n, "iand") == 0)
+ rop = OMP_REDUCTION_IAND;
+ else if (strcmp (n, "ior") == 0)
+ rop = OMP_REDUCTION_IOR;
+ else if (strcmp (n, "ieor") == 0)
+ rop = OMP_REDUCTION_IEOR;
+ if (rop != OMP_REDUCTION_NONE
+ && sym != NULL
+ && ! sym->attr.intrinsic
+ && ! sym->attr.use_assoc
+ && ((sym->attr.flavor == FL_UNKNOWN
+ && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
+ sym->name, NULL))
+ || !gfc_add_intrinsic (&sym->attr, NULL)))
+ rop = OMP_REDUCTION_NONE;
+ }
+ else
+ buffer[0] = '\0';
+ gfc_omp_udr *udr = (buffer[0] ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL)
+ : NULL);
+ gfc_omp_namelist **head = NULL;
+ if (rop == OMP_REDUCTION_NONE && udr)
+ rop = OMP_REDUCTION_USER;
+
+ if (gfc_match_omp_variable_list (" :", &c->lists[list_idx], false, NULL,
+ &head, openacc, allow_derived) != MATCH_YES)
+ {
+ gfc_current_locus = old_loc;
+ return MATCH_NO;
+ }
+ gfc_omp_namelist *n;
+ if (rop == OMP_REDUCTION_NONE)
+ {
+ n = *head;
+ *head = NULL;
+ gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
+ buffer, &old_loc);
+ gfc_free_omp_namelist (n);
+ }
+ else
+ for (n = *head; n; n = n->next)
+ {
+ n->u.reduction_op = rop;
+ if (udr)
+ {
+ n->udr = gfc_get_omp_namelist_udr ();
+ n->udr->udr = udr;
+ }
+ }
+ return MATCH_YES;
+}
+
/* Match OpenMP and OpenACC directive clauses. MASK is a bitmask of
clauses that are allowed for a particular directive. */
@@ -1379,6 +1538,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
needs_space = true;
continue;
}
+ if ((mask & OMP_CLAUSE_IN_REDUCTION)
+ && gfc_match_omp_clause_reduction (pc, c, openacc,
+ allow_derived) == MATCH_YES)
+ continue;
if ((mask & OMP_CLAUSE_INBRANCH)
&& !c->inbranch
&& !c->notinbranch
@@ -1717,124 +1880,24 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
continue;
}
if ((mask & OMP_CLAUSE_REDUCTION)
- && gfc_match ("reduction ( ") == MATCH_YES)
+ && gfc_match_omp_clause_reduction (pc, c, openacc,
+ allow_derived) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_MEMORDER)
+ && c->memorder == OMP_MEMORDER_UNSET
+ && gfc_match ("relaxed") == MATCH_YES)
{
- gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
- char buffer[GFC_MAX_SYMBOL_LEN + 3];
- if (gfc_match_char ('+') == MATCH_YES)
- rop = OMP_REDUCTION_PLUS;
- else if (gfc_match_char ('*') == MATCH_YES)
- rop = OMP_REDUCTION_TIMES;
- else if (gfc_match_char ('-') == MATCH_YES)
- rop = OMP_REDUCTION_MINUS;
- else if (gfc_match (".and.") == MATCH_YES)
- rop = OMP_REDUCTION_AND;
- else if (gfc_match (".or.") == MATCH_YES)
- rop = OMP_REDUCTION_OR;
- else if (gfc_match (".eqv.") == MATCH_YES)
- rop = OMP_REDUCTION_EQV;
- else if (gfc_match (".neqv.") == MATCH_YES)
- rop = OMP_REDUCTION_NEQV;
- if (rop != OMP_REDUCTION_NONE)
- snprintf (buffer, sizeof buffer, "operator %s",
- gfc_op2string ((gfc_intrinsic_op) rop));
- else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
- {
- buffer[0] = '.';
- strcat (buffer, ".");
- }
- else if (gfc_match_name (buffer) == MATCH_YES)
- {
- gfc_symbol *sym;
- const char *n = buffer;
-
- gfc_find_symbol (buffer, NULL, 1, &sym);
- if (sym != NULL)
- {
- if (sym->attr.intrinsic)
- n = sym->name;
- else if ((sym->attr.flavor != FL_UNKNOWN
- && sym->attr.flavor != FL_PROCEDURE)
- || sym->attr.external
- || sym->attr.generic
- || sym->attr.entry
- || sym->attr.result
- || sym->attr.dummy
- || sym->attr.subroutine
- || sym->attr.pointer
- || sym->attr.target
- || sym->attr.cray_pointer
- || sym->attr.cray_pointee
- || (sym->attr.proc != PROC_UNKNOWN
- && sym->attr.proc != PROC_INTRINSIC)
- || sym->attr.if_source != IFSRC_UNKNOWN
- || sym == sym->ns->proc_name)
- {
- sym = NULL;
- n = NULL;
- }
- else
- n = sym->name;
- }
- if (n == NULL)
- rop = OMP_REDUCTION_NONE;
- else if (strcmp (n, "max") == 0)
- rop = OMP_REDUCTION_MAX;
- else if (strcmp (n, "min") == 0)
- rop = OMP_REDUCTION_MIN;
- else if (strcmp (n, "iand") == 0)
- rop = OMP_REDUCTION_IAND;
- else if (strcmp (n, "ior") == 0)
- rop = OMP_REDUCTION_IOR;
- else if (strcmp (n, "ieor") == 0)
- rop = OMP_REDUCTION_IEOR;
- if (rop != OMP_REDUCTION_NONE
- && sym != NULL
- && ! sym->attr.intrinsic
- && ! sym->attr.use_assoc
- && ((sym->attr.flavor == FL_UNKNOWN
- && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
- sym->name, NULL))
- || !gfc_add_intrinsic (&sym->attr, NULL)))
- rop = OMP_REDUCTION_NONE;
- }
- else
- buffer[0] = '\0';
- gfc_omp_udr *udr
- = (buffer[0]
- ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
- gfc_omp_namelist **head = NULL;
- if (rop == OMP_REDUCTION_NONE && udr)
- rop = OMP_REDUCTION_USER;
-
- if (gfc_match_omp_variable_list (" :",
- &c->lists[OMP_LIST_REDUCTION],
- false, NULL, &head, openacc,
- allow_derived) == MATCH_YES)
- {
- gfc_omp_namelist *n;
- if (rop == OMP_REDUCTION_NONE)
- {
- n = *head;
- *head = NULL;
- gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
- "at %L", buffer, &old_loc);
- gfc_free_omp_namelist (n);
- }
- else
- for (n = *head; n; n = n->next)
- {
- n->u.reduction_op = rop;
- if (udr)
- {
- n->udr = gfc_get_omp_namelist_udr ();
- n->udr->udr = udr;
- }
- }
- continue;
- }
- else
- gfc_current_locus = old_loc;
+ c->memorder = OMP_MEMORDER_RELAXED;
+ needs_space = true;
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_MEMORDER)
+ && c->memorder == OMP_MEMORDER_UNSET
+ && gfc_match ("release") == MATCH_YES)
+ {
+ c->memorder = OMP_MEMORDER_RELEASE;
+ needs_space = true;
+ continue;
}
if ((mask & OMP_CLAUSE_MEMORDER)
&& c->memorder == OMP_MEMORDER_UNSET
@@ -1962,6 +2025,10 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
}
break;
case 't':
+ if ((mask & OMP_CLAUSE_TASK_REDUCTION)
+ && gfc_match_omp_clause_reduction (pc, c, openacc,
+ allow_derived) == MATCH_YES)
+ continue;
if ((mask & OMP_CLAUSE_THREAD_LIMIT)
&& c->thread_limit == NULL
&& gfc_match ("thread_limit ( %e )",
@@ -2696,18 +2763,19 @@ cleanup:
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
| OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \
| OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \
- | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
+ | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION)
#define OMP_TASKLOOP_CLAUSES \
(omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \
| OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \
| OMP_CLAUSE_DEFAULT | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL \
| OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE \
- | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
+ | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP \
+ | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_IN_REDUCTION)
#define OMP_TARGET_CLAUSES \
(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
| OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE \
| OMP_CLAUSE_FIRSTPRIVATE | OMP_CLAUSE_DEFAULTMAP \
- | OMP_CLAUSE_IS_DEVICE_PTR)
+ | OMP_CLAUSE_IS_DEVICE_PTR | OMP_CLAUSE_IN_REDUCTION)
#define OMP_TARGET_DATA_CLAUSES \
(omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF \
| OMP_CLAUSE_USE_DEVICE_PTR | OMP_CLAUSE_USE_DEVICE_ADDR)
@@ -4228,12 +4296,12 @@ gfc_match_omp_barrier (void)
match
gfc_match_omp_taskgroup (void)
{
- if (gfc_match_omp_eos () != MATCH_YES)
- {
- gfc_error ("Unexpected junk after $OMP TASKGROUP statement at %C");
- return MATCH_ERROR;
- }
+ gfc_omp_clauses *c;
+ if (gfc_match_omp_clauses (&c, OMP_CLAUSE_TASK_REDUCTION, true, true)
+ != MATCH_YES)
+ return MATCH_ERROR;
new_st.op = EXEC_OMP_TASKGROUP;
+ new_st.ext.omp_clauses = c;
return MATCH_YES;
}
@@ -4560,7 +4628,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
static const char *clause_names[]
= { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED",
"COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP",
- "TO", "FROM", "REDUCTION", "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
+ "TO", "FROM", "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/,
+ "IN_REDUCTION", "TASK_REDUCTION",
+ "DEVICE_RESIDENT", "LINK", "USE_DEVICE",
"CACHE", "IS_DEVICE_PTR", "USE_DEVICE_PTR", "USE_DEVICE_ADDR",
"NONTEMPORAL" };
STATIC_ASSERT (ARRAY_SIZE (clause_names) == OMP_LIST_NUM);
@@ -4727,21 +4797,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
if (omp_clauses->sched_kind != OMP_SCHED_NONE
&& omp_clauses->sched_nonmonotonic)
{
- if (omp_clauses->sched_kind != OMP_SCHED_DYNAMIC
- && omp_clauses->sched_kind != OMP_SCHED_GUIDED)
- {
- const char *p;
- switch (omp_clauses->sched_kind)
- {
- case OMP_SCHED_STATIC: p = "STATIC"; break;
- case OMP_SCHED_RUNTIME: p = "RUNTIME"; break;
- case OMP_SCHED_AUTO: p = "AUTO"; break;
- default: gcc_unreachable ();
- }
- gfc_error ("NONMONOTONIC modifier specified for %s schedule kind "
- "at %L", p, &code->loc);
- }
- else if (omp_clauses->sched_monotonic)
+ if (omp_clauses->sched_monotonic)
gfc_error ("Both MONOTONIC and NONMONOTONIC schedule modifiers "
"specified at %L", &code->loc);
else if (omp_clauses->ordered)
@@ -4818,7 +4874,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
&& (list != OMP_LIST_MAP || openacc)
&& list != OMP_LIST_FROM
&& list != OMP_LIST_TO
- && (list != OMP_LIST_REDUCTION || !openacc))
+ && (list != OMP_LIST_REDUCTION || !openacc)
+ && list != OMP_LIST_REDUCTION_INSCAN
+ && list != OMP_LIST_REDUCTION_TASK
+ && list != OMP_LIST_IN_REDUCTION
+ && list != OMP_LIST_TASK_REDUCTION)
for (n = omp_clauses->lists[list]; n; n = n->next)
{
bool component_ref_p = false;
@@ -5224,6 +5284,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
for (; n != NULL; n = n->next)
{
bool bad = false;
+ bool is_reduction = (list == OMP_LIST_REDUCTION
+ || list == OMP_LIST_REDUCTION_INSCAN
+ || list == OMP_LIST_REDUCTION_TASK
+ || list == OMP_LIST_IN_REDUCTION
+ || list == OMP_LIST_TASK_REDUCTION);
if (n->sym->attr.threadprivate)
gfc_error ("THREADPRIVATE object %qs in %s clause at %L",
n->sym->name, name, &n->where);
@@ -5233,15 +5298,15 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
if (n->sym->attr.associate_var)
gfc_error ("ASSOCIATE name %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (list != OMP_LIST_PRIVATE)
+ if (list != OMP_LIST_PRIVATE && is_reduction)
{
- if (n->sym->attr.proc_pointer && list == OMP_LIST_REDUCTION)
+ if (n->sym->attr.proc_pointer)
gfc_error ("Procedure pointer %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (n->sym->attr.pointer && list == OMP_LIST_REDUCTION)
+ if (n->sym->attr.pointer)
gfc_error ("POINTER object %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (n->sym->attr.cray_pointer && list == OMP_LIST_REDUCTION)
+ if (n->sym->attr.cray_pointer)
gfc_error ("Cray pointer %qs in %s clause at %L",
n->sym->name, name, &n->where);
}
@@ -5253,7 +5318,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
else if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE)
gfc_error ("Assumed size array %qs in %s clause at %L",
n->sym->name, name, &n->where);
- if (n->sym->attr.in_namelist && list != OMP_LIST_REDUCTION)
+ if (n->sym->attr.in_namelist && !is_reduction)
gfc_error ("Variable %qs in %s clause is used in "
"NAMELIST statement at %L",
n->sym->name, name, &n->where);
@@ -5273,7 +5338,21 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
switch (list)
{
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK:
+ if (code && (code->op == EXEC_OMP_TASKLOOP
+ || code->op == EXEC_OMP_TEAMS
+ || code->op == EXEC_OMP_TEAMS_DISTRIBUTE))
+ {
+ gfc_error ("Only DEFAULT permitted as reduction-"
+ "modifier in REDUCTION clause at %L",
+ &n->where);
+ break;
+ }
+ gcc_fallthrough ();
case OMP_LIST_REDUCTION:
+ case OMP_LIST_IN_REDUCTION:
+ case OMP_LIST_TASK_REDUCTION:
switch (n->u.reduction_op)
{
case OMP_REDUCTION_PLUS:
@@ -6102,6 +6181,10 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
case OMP_LIST_FIRSTPRIVATE:
case OMP_LIST_LASTPRIVATE:
case OMP_LIST_REDUCTION:
+ case OMP_LIST_REDUCTION_INSCAN:
+ case OMP_LIST_REDUCTION_TASK:
+ case OMP_LIST_IN_REDUCTION:
+ case OMP_LIST_TASK_REDUCTION:
case OMP_LIST_LINEAR:
for (n = omp_clauses->lists[list]; n; n = n->next)
ctx.sharing_clauses->add (n->sym);