diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2019-05-17 21:13:15 +0200 |
---|---|---|
committer | Thomas Schwinge <tschwinge@gcc.gnu.org> | 2019-05-17 21:13:15 +0200 |
commit | 5bf04509f437ff175c001a1c84a13b3a845174eb (patch) | |
tree | 05c7809fb44b3510da14c00b79c3d9443f04d7d7 /gcc/omp-general.c | |
parent | e03436e7ac2ddbbf397a6d64309b01ad37cfcadf (diff) | |
download | gcc-5bf04509f437ff175c001a1c84a13b3a845174eb.zip gcc-5bf04509f437ff175c001a1c84a13b3a845174eb.tar.gz gcc-5bf04509f437ff175c001a1c84a13b3a845174eb.tar.bz2 |
[PR89433] Use 'oacc_verify_routine_clauses' for C/C++ OpenACC 'routine' directives
gcc/
PR middle-end/89433
* omp-general.c (oacc_build_routine_dims): Move some of its
processing into...
(oacc_verify_routine_clauses): ... this new function.
* omp-general.h (oacc_verify_routine_clauses): New prototype.
gcc/c/
PR c/89433
* c-parser.c (c_parser_oacc_routine): Normalize order of clauses.
(c_finish_oacc_routine): Call oacc_verify_routine_clauses.
gcc/cp/
PR c++/89433
* parser.c (cp_parser_oacc_routine)
(cp_parser_late_parsing_oacc_routine): Normalize order of clauses.
(cp_finalize_oacc_routine): Call oacc_verify_routine_clauses.
gcc/testsuite/
PR testsuite/89433
* c-c++-common/goacc/routine-2.c: Update, and move some test
into...
* c-c++-common/goacc/routine-level-of-parallelism-1.c: ... this
new file.
From-SVN: r271344
Diffstat (limited to 'gcc/omp-general.c')
-rw-r--r-- | gcc/omp-general.c | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/gcc/omp-general.c b/gcc/omp-general.c index 356772f..f1d859b 100644 --- a/gcc/omp-general.c +++ b/gcc/omp-general.c @@ -608,9 +608,61 @@ oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args) } } -/* Process the routine's dimension clauess to generate an attribute - value. Issue diagnostics as appropriate. We default to SEQ - (OpenACC 2.5 clarifies this). All dimensions have a size of zero +/* Verify OpenACC routine clauses. + + Upon returning, the chain of clauses will contain exactly one clause + specifying the level of parallelism. */ + +void +oacc_verify_routine_clauses (tree *clauses, location_t loc) +{ + tree c_level = NULL_TREE; + tree c_p = NULL_TREE; + for (tree c = *clauses; c; c_p = c, c = OMP_CLAUSE_CHAIN (c)) + switch (OMP_CLAUSE_CODE (c)) + { + case OMP_CLAUSE_GANG: + case OMP_CLAUSE_WORKER: + case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_SEQ: + if (c_level == NULL_TREE) + c_level = c; + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_CODE (c_level)) + { + /* This has already been diagnosed in the front ends. */ + /* Drop the duplicate clause. */ + gcc_checking_assert (c_p != NULL_TREE); + OMP_CLAUSE_CHAIN (c_p) = OMP_CLAUSE_CHAIN (c); + c = c_p; + } + else + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qs specifies a conflicting level of parallelism", + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); + inform (OMP_CLAUSE_LOCATION (c_level), + "... to the previous %qs clause here", + omp_clause_code_name[OMP_CLAUSE_CODE (c_level)]); + /* Drop the conflicting clause. */ + gcc_checking_assert (c_p != NULL_TREE); + OMP_CLAUSE_CHAIN (c_p) = OMP_CLAUSE_CHAIN (c); + c = c_p; + } + break; + default: + gcc_unreachable (); + } + if (c_level == NULL_TREE) + { + /* Default to an implicit 'seq' clause. */ + c_level = build_omp_clause (loc, OMP_CLAUSE_SEQ); + OMP_CLAUSE_CHAIN (c_level) = *clauses; + *clauses = c_level; + } +} + +/* Process the OpenACC 'routine' directive clauses to generate an attribute + for the level of parallelism. All dimensions have a size of zero (dynamic). TREE_PURPOSE is set to indicate whether that dimension can have a loop partitioned on it. non-zero indicates yes, zero indicates no. By construction once a non-zero has been @@ -632,16 +684,10 @@ oacc_build_routine_dims (tree clauses) for (ix = GOMP_DIM_MAX + 1; ix--;) if (OMP_CLAUSE_CODE (clauses) == ids[ix]) { - if (level >= 0) - error_at (OMP_CLAUSE_LOCATION (clauses), - "multiple loop axes specified for routine"); level = ix; break; } - - /* Default to SEQ. */ - if (level < 0) - level = GOMP_DIM_MAX; + gcc_checking_assert (level >= 0); tree dims = NULL_TREE; |