On Tue, Nov 10, 2020 at 12:40:08AM +0100, Tobias Burnus wrote: > --- a/gcc/fortran/openmp.c > +++ b/gcc/fortran/openmp.c > @@ -762,6 +762,10 @@ enum omp_mask1 > OMP_CLAUSE_SHARED, > OMP_CLAUSE_COPYIN, > OMP_CLAUSE_REDUCTION, > + OMP_CLAUSE_REDUCTION_DEFAULT, > + OMP_CLAUSE_REDUCTION_MODIFIER,
I don't understand the need for OMP_CLAUSE_REDUCTION_DEFAULT, default modifier is allowed in all OpenMP reduction clauses and your gfc_match_omp_clause_reduction function has the openacc argument. So why can't you keep using OMP_CLAUSE_REDUCTION in place where you use OMP_CLAUSE_REDUCTION_DEFAULT now and just decide based on !openacc whether to parse any reduction modifiers? One could probably get away even without OMP_CLAUSE_REDUCTION_MODIFIER, just allow all the modifiers first and during resolving complain if [OMP_LIST_REDUCTION_INSCAN] and/or [OMP_LIST_REDUCTION_TASK] is non-NULL on constructs where it shouldn't. When splitting clauses, OMP_LIST_REDUCTION_TASK applies only on the innermost construct that accepts it (others should treat it as OMP_LIST_REDUCTION), and inscan is severely limited to which constructs it can appear on. For task modifier, do you diagnose somewhere what c_split_omp_clauses diagnoses? E.g. if task modifier appears with innermost combined construct simd/loop, or if task modifier appears and not combined with parallel/do/sections? Inscan is allowed only on do, simd, do simd, parallel do and parallel do sim.d Also, I think there should be an error or sorry on the inscan modifier somewhere until the rest of the scan support is implemented (in particular the changes in the parsing of do/simd body with inscan reductions including the parsing of the inclusive/exclusive directives in there). > #define OMP_DECLARE_SIMD_CLAUSES \ > (omp_mask (OMP_CLAUSE_SIMDLEN) | OMP_CLAUSE_LINEAR \ > | OMP_CLAUSE_UNIFORM | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_INBRANCH > \ I wonder why we have the occassional tabs in the middle of the OMP_*_CLAUSES defines. > + | OMP_CLAUSE_SAFELEN | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED \ > + | OMP_CLAUSE_SIMDLEN | OMP_CLAUSE_IF | OMP_CLAUSE_ORDER > \ Here too. > + for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++) > + { > + if (mask & GFC_OMP_MASK_TEAMS) > + clausesa[GFC_OMP_SPLIT_TEAMS].lists[i] > + = code->ext.omp_clauses->lists[i]; > + if (mask & GFC_OMP_MASK_PARALLEL) > + clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i] > + = code->ext.omp_clauses->lists[i]; > + else if (mask & GFC_OMP_MASK_DO) > + clausesa[GFC_OMP_SPLIT_DO].lists[i] > + = code->ext.omp_clauses->lists[i]; > + if (mask & GFC_OMP_MASK_SIMD) > + clausesa[GFC_OMP_SPLIT_SIMD].lists[i] > + = code->ext.omp_clauses->lists[i]; > + } Seems in the middle-end we just ignore OMP_CLAUSE_REDUCTION_TASK on anything but parallel/{for,do}/sections, so guess this is ok. Jakub