[flang-commits] [flang] 6e42a41 - [flang][openmp] Check clauses allowed semantic with tablegen generated map
via flang-commits
flang-commits at lists.llvm.org
Sat Jul 11 09:45:21 PDT 2020
Author: Valentin Clement
Date: 2020-07-11T12:45:12-04:00
New Revision: 6e42a417bacbfd5a1f58b0ccb7c9b34ff9e54523
URL: https://github.com/llvm/llvm-project/commit/6e42a417bacbfd5a1f58b0ccb7c9b34ff9e54523
DIFF: https://github.com/llvm/llvm-project/commit/6e42a417bacbfd5a1f58b0ccb7c9b34ff9e54523.diff
LOG: [flang][openmp] Check clauses allowed semantic with tablegen generated map
Summary:
This patch is enabling the generation of clauses enum sets for semantics check in Flang through
tablegen. Enum sets and directive - sets map is generated by the new tablegen infrsatructure for OpenMP
and other directive languages.
The semantic checks for OpenMP are modified to use this newly generated map.
Reviewers: DavidTruby, sscalpone, kiranchandramohan, ichoyjx, jdoerfert
Reviewed By: DavidTruby, ichoyjx
Subscribers: mgorny, yaxunl, hiraditya, guansong, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83326
Added:
Modified:
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/test/Semantics/omp-clause-validity01.f90
llvm/include/llvm/Frontend/Directive/DirectiveBase.td
llvm/include/llvm/Frontend/OpenMP/CMakeLists.txt
llvm/include/llvm/Frontend/OpenMP/OMP.td
llvm/test/TableGen/directive1.td
llvm/test/TableGen/directive2.td
llvm/utils/TableGen/DirectiveEmitter.cpp
llvm/utils/TableGen/TableGen.cpp
llvm/utils/TableGen/TableGenBackends.h
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b4e86faffe19..a5f65bcbc804 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -13,58 +13,6 @@
namespace Fortran::semantics {
-static OmpClauseSet doAllowedClauses{llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_linear, llvm::omp::Clause::OMPC_reduction};
-static OmpClauseSet doAllowedOnceClauses{llvm::omp::Clause::OMPC_schedule,
- llvm::omp::Clause::OMPC_collapse, llvm::omp::Clause::OMPC_ordered};
-
-static OmpClauseSet simdAllowedClauses{llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned, llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_lastprivate, llvm::omp::Clause::OMPC_reduction};
-static OmpClauseSet simdAllowedOnceClauses{llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_safelen, llvm::omp::Clause::OMPC_simdlen};
-
-static OmpClauseSet parallelAllowedClauses{llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared, llvm::omp::Clause::OMPC_copyin,
- llvm::omp::Clause::OMPC_reduction};
-static OmpClauseSet parallelAllowedOnceClauses{llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_num_threads, llvm::omp::Clause::OMPC_proc_bind};
-
-static OmpClauseSet taskloopAllowedClauses{llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_lastprivate, llvm::omp::Clause::OMPC_default,
- llvm::omp::Clause::OMPC_untied, llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_nogroup};
-static OmpClauseSet taskloopAllowedOnceClauses{llvm::omp::Clause::OMPC_collapse,
- llvm::omp::Clause::OMPC_if, llvm::omp::Clause::OMPC_final,
- llvm::omp::Clause::OMPC_priority};
-static OmpClauseSet taskloopAllowedExclusiveClauses{
- llvm::omp::Clause::OMPC_grainsize, llvm::omp::Clause::OMPC_num_tasks};
-
-static OmpClauseSet distributeAllowedClauses{llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_lastprivate};
-static OmpClauseSet distributeAllowedOnceClauses{
- llvm::omp::Clause::OMPC_collapse, llvm::omp::Clause::OMPC_dist_schedule};
-
-static OmpClauseSet targetAllowedClauses{llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_map, llvm::omp::Clause::OMPC_is_device_ptr,
- llvm::omp::Clause::OMPC_depend};
-static OmpClauseSet targetAllowedOnceClauses{llvm::omp::Clause::OMPC_device,
- llvm::omp::Clause::OMPC_defaultmap, llvm::omp::Clause::OMPC_nowait};
-
-static OmpClauseSet teamsAllowedClauses{llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_shared,
- llvm::omp::Clause::OMPC_reduction};
-static OmpClauseSet teamsAllowedOnceClauses{llvm::omp::Clause::OMPC_num_teams,
- llvm::omp::Clause::OMPC_thread_limit, llvm::omp::Clause::OMPC_default};
-
-static OmpClauseSet sectionsAllowedClauses{llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate, llvm::omp::Clause::OMPC_lastprivate,
- llvm::omp::Clause::OMPC_reduction};
-
std::string OmpStructureChecker::ContextDirectiveAsFortran() {
auto dir = llvm::omp::getOpenMPDirectiveName(GetContext().directive).str();
std::transform(dir.begin(), dir.end(), dir.begin(),
@@ -186,19 +134,18 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
CheckMatching<parser::OmpLoopDirective>(beginLoopDir, *endLoopDir);
}
- if (beginDir.v != llvm::omp::Directive::OMPD_do)
- PushContext(beginDir.source, beginDir.v);
+ if (beginDir.v != llvm::omp::Directive::OMPD_do) {
+ PushContextAndClauseSets(beginDir.source, beginDir.v);
+ } else {
+ // 2.7.1 do-clause -> private-clause |
+ // firstprivate-clause |
+ // lastprivate-clause |
+ // linear-clause |
+ // reduction-clause |
+ // schedule-clause |
+ // collapse-clause |
+ // ordered-clause
- switch (beginDir.v) {
- // 2.7.1 do-clause -> private-clause |
- // firstprivate-clause |
- // lastprivate-clause |
- // linear-clause |
- // reduction-clause |
- // schedule-clause |
- // collapse-clause |
- // ordered-clause
- case llvm::omp::Directive::OMPD_do: {
// nesting check
HasInvalidWorksharingNesting(beginDir.source,
{llvm::omp::Directive::OMPD_do, llvm::omp::Directive::OMPD_sections,
@@ -210,218 +157,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
llvm::omp::Directive::OMPD_ordered,
llvm::omp::Directive::OMPD_atomic,
llvm::omp::Directive::OMPD_master});
- PushContext(beginDir.source, llvm::omp::Directive::OMPD_do);
- SetContextAllowed(doAllowedClauses);
- SetContextAllowedOnce(doAllowedOnceClauses);
- } break;
-
- // 2.11.1 parallel-do-clause -> parallel-clause |
- // do-clause
- case llvm::omp::Directive::OMPD_parallel_do: {
- SetContextAllowed(parallelAllowedClauses | doAllowedClauses);
- SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses);
- } break;
-
- // 2.8.1 simd-clause -> safelen-clause |
- // simdlen-clause |
- // linear-clause |
- // aligned-clause |
- // private-clause |
- // lastprivate-clause |
- // reduction-clause |
- // collapse-clause
- case llvm::omp::Directive::OMPD_simd: {
- SetContextAllowed(simdAllowedClauses);
- SetContextAllowedOnce(simdAllowedOnceClauses);
- } break;
-
- // 2.8.3 do-simd-clause -> do-clause |
- // simd-clause
- case llvm::omp::Directive::OMPD_do_simd: {
- SetContextAllowed(doAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(doAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- // 2.11.4 parallel-do-simd-clause -> parallel-clause |
- // do-simd-clause
- case llvm::omp::Directive::OMPD_parallel_do_simd: {
- SetContextAllowed(
- parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(parallelAllowedOnceClauses | doAllowedOnceClauses |
- simdAllowedOnceClauses);
- } break;
-
- // 2.9.2 taskloop-clause -> if-clause |
- // shared-clause |
- // private-clause |
- // firstprivate-clause |
- // lastprivate-clause |
- // default-clause |
- // grainsize-clause |
- // num-tasks-clause |
- // collapse-clause |
- // final-clause |
- // priority-clause |
- // untied-clause |
- // mergeable-clause |
- // nogroup-clause
- case llvm::omp::Directive::OMPD_taskloop: {
- SetContextAllowed(taskloopAllowedClauses);
- SetContextAllowedOnce(taskloopAllowedOnceClauses);
- SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
- } break;
-
- // 2.9.3 taskloop-simd-clause -> taskloop-clause |
- // simd-clause
- case llvm::omp::Directive::OMPD_taskloop_simd: {
- SetContextAllowed((taskloopAllowedClauses | simdAllowedClauses) -
- llvm::omp::Clause::OMPC_reduction);
- SetContextAllowedOnce(taskloopAllowedOnceClauses | simdAllowedOnceClauses);
- SetContextAllowedExclusive(taskloopAllowedExclusiveClauses);
- } break;
-
- // 2.10.8 distribute-clause -> private-clause |
- // firstprivate-clause |
- // lastprivate-clause |
- // collapse-clause |
- // dist-schedule-clause
- case llvm::omp::Directive::OMPD_distribute: {
- SetContextAllowed(distributeAllowedClauses);
- SetContextAllowedOnce(distributeAllowedOnceClauses);
- } break;
-
- // 2.10.9 distribute-simd-clause -> distribute-clause |
- // simd-clause
- case llvm::omp::Directive::OMPD_distribute_simd: {
- SetContextAllowed(distributeAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(
- distributeAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- // 2.10.10 distribute-parallel-do-clause -> distribute-clause |
- // parallel-do-clause
- case llvm::omp::Directive::OMPD_distribute_parallel_do: {
- SetContextAllowed(
- distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
- SetContextAllowedOnce(distributeAllowedOnceClauses |
- parallelAllowedOnceClauses | doAllowedOnceClauses);
- } break;
-
- // 2.10.11 distribute-parallel-do-simd-clause -> distribute-clause |
- // parallel-do-simd-clause
- case llvm::omp::Directive::OMPD_distribute_parallel_do_simd: {
- SetContextAllowed(distributeAllowedClauses | parallelAllowedClauses |
- doAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(distributeAllowedOnceClauses |
- parallelAllowedOnceClauses | doAllowedOnceClauses | simdAllowedClauses);
- } break;
-
- // 2.11.6 target-parallel-do-clause -> target-clause |
- // parallel-do-clause
- case llvm::omp::Directive::OMPD_target_parallel_do: {
- SetContextAllowed(
- targetAllowedClauses | parallelAllowedClauses | doAllowedClauses);
- SetContextAllowedOnce(
- (targetAllowedOnceClauses | parallelAllowedOnceClauses |
- doAllowedOnceClauses) -
- llvm::omp::Clause::OMPC_nowait);
- } break;
-
- // 2.11.7 target-parallel-do-simd-clause -> target-clause |
- // parallel-do-simd-clause
- case llvm::omp::Directive::OMPD_target_parallel_do_simd: {
- SetContextAllowed(targetAllowedClauses | parallelAllowedClauses |
- doAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(
- (targetAllowedOnceClauses | parallelAllowedOnceClauses |
- doAllowedOnceClauses | simdAllowedOnceClauses) -
- llvm::omp::Clause::OMPC_nowait);
- } break;
-
- // 2.11.8 target-simd-clause -> target-clause |
- // simd-clause
- case llvm::omp::Directive::OMPD_target_simd: {
- SetContextAllowed(targetAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(targetAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- // 2.11.10 teams-distribute-clause -> teams-clause |
- // distribute-clause
- case llvm::omp::Directive::OMPD_teams_distribute: {
- SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses);
- SetContextAllowedOnce(
- teamsAllowedOnceClauses | distributeAllowedOnceClauses);
- } break;
-
- // 2.11.11 teams-distribute-simd-clause -> teams-clause |
- // distribute-simd-clause
- case llvm::omp::Directive::OMPD_teams_distribute_simd: {
- SetContextAllowed(
- teamsAllowedClauses | distributeAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(teamsAllowedOnceClauses |
- distributeAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- // 2.11.12 target-teams-distribute-clause -> target-clause |
- // teams-distribute-clause
- case llvm::omp::Directive::OMPD_target_teams_distribute: {
- SetContextAllowed(
- targetAllowedClauses | teamsAllowedClauses | distributeAllowedClauses);
- SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
- distributeAllowedOnceClauses);
- } break;
-
- // 2.11.13 target-teams-distribute-simd-clause -> target-clause |
- // teams-distribute-simd-clause
- case llvm::omp::Directive::OMPD_target_teams_distribute_simd: {
- SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
- distributeAllowedClauses | simdAllowedClauses);
- SetContextAllowed(targetAllowedOnceClauses | teamsAllowedOnceClauses |
- distributeAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- // 2.11.14 teams-distribute-parallel-do-clause -> teams-clause |
- // distribute-parallel-do-clause
- case llvm::omp::Directive::OMPD_teams_distribute_parallel_do: {
- SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
- parallelAllowedClauses | doAllowedClauses);
- SetContextAllowedOnce(teamsAllowedOnceClauses |
- distributeAllowedOnceClauses | parallelAllowedOnceClauses |
- doAllowedOnceClauses);
- } break;
-
- // 2.11.15 target-teams-distribute-parallel-do-clause -> target-clause |
- // teams-distribute-parallel-do-clause
- case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do: {
- SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
- distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses);
- SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
- distributeAllowedOnceClauses | parallelAllowedOnceClauses |
- doAllowedOnceClauses);
- } break;
-
- // 2.11.16 teams-distribute-parallel-do-clause -> teams-clause |
- // distribute-parallel-do-simd-clause
- case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd: {
- SetContextAllowed(teamsAllowedClauses | distributeAllowedClauses |
- parallelAllowedClauses | doAllowedClauses | simdAllowedClauses);
- SetContextAllowedOnce(teamsAllowedOnceClauses |
- distributeAllowedOnceClauses | parallelAllowedOnceClauses |
- doAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd: {
- SetContextAllowed(targetAllowedClauses | teamsAllowedClauses |
- distributeAllowedClauses | parallelAllowedClauses | doAllowedClauses |
- simdAllowedClauses);
- SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses |
- distributeAllowedOnceClauses | parallelAllowedOnceClauses |
- doAllowedOnceClauses | simdAllowedOnceClauses);
- } break;
-
- default:
- // TODO others
- break;
+ PushContextAndClauseSets(beginDir.source, llvm::omp::Directive::OMPD_do);
}
}
@@ -436,12 +172,8 @@ void OmpStructureChecker::Enter(const parser::OmpEndLoopDirective &x) {
// 2.7.1 end-do -> END DO [nowait-clause]
// 2.8.3 end-do-simd -> END DO SIMD [nowait-clause]
case llvm::omp::Directive::OMPD_do:
- SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_do);
- SetContextAllowed(OmpClauseSet{llvm::omp::Clause::OMPC_nowait});
- break;
case llvm::omp::Directive::OMPD_do_simd:
- SetContextDirectiveEnum(llvm::omp::Directive::OMPD_end_do_simd);
- SetContextAllowed(OmpClauseSet{llvm::omp::Clause::OMPC_nowait});
+ SetClauseSets(dir.v);
break;
default:
// no clauses are allowed
@@ -455,112 +187,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
const auto &beginDir{
CheckMatching<parser::OmpBlockDirective>(beginBlockDir, endBlockDir)};
- PushContext(beginDir.source, beginDir.v);
- switch (beginDir.v) {
- // 2.5 parallel-clause -> if-clause |
- // num-threads-clause |
- // default-clause |
- // private-clause |
- // firstprivate-clause |
- // shared-clause |
- // copyin-clause |
- // reduction-clause |
- // proc-bind-clause
- case llvm::omp::Directive::OMPD_parallel: {
- // reserve for nesting check
- SetContextAllowed(parallelAllowedClauses);
- SetContextAllowedOnce(parallelAllowedOnceClauses);
- } break;
- // 2.7.3 single-clause -> private-clause |
- // firstprivate-clause
- case llvm::omp::Directive::OMPD_single:
- SetContextAllowed({llvm::omp::Clause::OMPC_private,
- llvm::omp::Clause::OMPC_firstprivate});
- break;
- // 2.7.4 workshare (no clauses are allowed)
- case llvm::omp::Directive::OMPD_workshare:
- break;
- // 2.11.3 parallel-workshare-clause -> parallel-clause
- case llvm::omp::Directive::OMPD_parallel_workshare: {
- SetContextAllowed(parallelAllowedClauses);
- SetContextAllowedOnce(parallelAllowedOnceClauses);
- } break;
- // 2.9.1 task-clause -> if-clause |
- // final-clause |
- // untied-clause |
- // default-clause |
- // mergeable-clause |
- // private-clause |
- // firstprivate-clause |
- // shared-clause |
- // depend-clause |
- // priority-clause
- case llvm::omp::Directive::OMPD_task: {
- OmpClauseSet allowed{llvm::omp::Clause::OMPC_untied,
- llvm::omp::Clause::OMPC_default, llvm::omp::Clause::OMPC_mergeable,
- llvm::omp::Clause::OMPC_private, llvm::omp::Clause::OMPC_firstprivate,
- llvm::omp::Clause::OMPC_shared, llvm::omp::Clause::OMPC_depend};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_final, llvm::omp::Clause::OMPC_priority};
- SetContextAllowedOnce(allowedOnce);
- } break;
- // 2.10.4 target-clause -> if-clause |
- // device-clause |
- // private-clause |
- // firstprivate-clause |
- // map-clause |
- // is-device-ptr-clause |
- // defaultmap-clause |
- // nowait-clause |
- // depend-clause
- case llvm::omp::Directive::OMPD_target: {
- SetContextAllowed(targetAllowedClauses);
- SetContextAllowedOnce(targetAllowedOnceClauses);
- } break;
- // 2.10.7 teams-clause -> num-teams-clause |
- // thread-limit-clause |
- // default-clause |
- // private-clause |
- // firstprivate-clause |
- // shared-clause |
- // reduction-clause
- case llvm::omp::Directive::OMPD_teams: {
- SetContextAllowed(teamsAllowedClauses);
- SetContextAllowedOnce(teamsAllowedOnceClauses);
- } break;
- // 2.11.9 target-teams -> target-clause |
- // teams-clause
- case llvm::omp::Directive::OMPD_target_teams: {
- SetContextAllowed(targetAllowedClauses | teamsAllowedClauses);
- SetContextAllowedOnce(targetAllowedOnceClauses | teamsAllowedOnceClauses);
- } break;
- // 2.10.1 target-data-clause -> if-clause |
- // device-clause |
- // map-clause |
- // use-device-ptr-clause
- case llvm::omp::Directive::OMPD_target_data: {
- OmpClauseSet allowed{llvm::omp::Clause::OMPC_if,
- llvm::omp::Clause::OMPC_map, llvm::omp::Clause::OMPC_use_device_ptr};
- SetContextAllowed(allowed);
- SetContextAllowedOnce({llvm::omp::Clause::OMPC_device});
- SetContextRequired({llvm::omp::Clause::OMPC_map});
- } break;
- // 2.13.1 master (no clauses are allowed)
- case llvm::omp::Directive::OMPD_master:
- break;
- // 2.11.5 target-parallel-clause -> target-clause |
- // parallel-clause
- case llvm::omp::Directive::OMPD_target_parallel: {
- SetContextAllowed((targetAllowedClauses | parallelAllowedClauses) -
- llvm::omp::Clause::OMPC_copyin);
- SetContextAllowedOnce(
- targetAllowedOnceClauses | parallelAllowedOnceClauses);
- } break;
- default:
- // TODO others
- break;
- }
+ PushContextAndClauseSets(beginDir.source, beginDir.v);
}
void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
@@ -574,25 +201,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPSectionsConstruct &x) {
const auto &beginDir{CheckMatching<parser::OmpSectionsDirective>(
beginSectionsDir, endSectionsDir)};
- PushContext(beginDir.source, beginDir.v);
- switch (beginDir.v) {
- // 2.7.2 sections-clause -> private-clause |
- // firstprivate-clause |
- // lastprivate-clause |
- // reduction-clause
- case llvm::omp::Directive::OMPD_sections: {
- SetContextAllowed(sectionsAllowedClauses);
- } break;
- // 2.11.2 -> parallel-sections-clause -> parallel-clause |
- // sections-clause
- case llvm::omp::Directive::OMPD_parallel_sections: {
- SetContextAllowed(parallelAllowedClauses | sectionsAllowedClauses);
- SetContextAllowedOnce(parallelAllowedOnceClauses);
- } break;
- default:
- // TODO others
- break;
- }
+ PushContextAndClauseSets(beginDir.source, beginDir.v);
}
void OmpStructureChecker::Leave(const parser::OpenMPSectionsConstruct &) {
@@ -616,19 +225,7 @@ void OmpStructureChecker::Enter(const parser::OmpEndSectionsDirective &x) {
void OmpStructureChecker::Enter(const parser::OpenMPDeclareSimdConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContext(dir.source, llvm::omp::Directive::OMPD_declare_simd);
- // 2.8.2 declare-simd-clause -> simdlen-clause |
- // linear-clause |
- // aligned-clause |
- // uniform-clause |
- // inbranch-clause |
- // notinbranch-clause
- OmpClauseSet allowed{llvm::omp::Clause::OMPC_linear,
- llvm::omp::Clause::OMPC_aligned, llvm::omp::Clause::OMPC_uniform};
- SetContextAllowed(allowed);
- SetContextAllowedOnce({llvm::omp::Clause::OMPC_simdlen});
- SetContextAllowedExclusive(
- {llvm::omp::Clause::OMPC_inbranch, llvm::omp::Clause::OMPC_notinbranch});
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_declare_simd);
}
void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
@@ -652,57 +249,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &) {
void OmpStructureChecker::Enter(
const parser::OpenMPSimpleStandaloneConstruct &x) {
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
- PushContext(dir.source, dir.v);
- switch (dir.v) {
- case llvm::omp::Directive::OMPD_barrier: {
- // 2.13.3 barrier
- } break;
- case llvm::omp::Directive::OMPD_taskwait: {
- // 2.13.4 taskwait
- } break;
- case llvm::omp::Directive::OMPD_taskyield: {
- // 2.9.4 taskyield
- } break;
- case llvm::omp::Directive::OMPD_target_enter_data: {
- // 2.10.2 target-enter-data-clause -> if-clause |
- // device-clause |
- // map-clause |
- // depend-clause |
- // nowait-clause
- OmpClauseSet allowed{llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_depend, llvm::omp::Clause::OMPC_nowait};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- llvm::omp::Clause::OMPC_device, llvm::omp::Clause::OMPC_if};
- SetContextAllowedOnce(allowedOnce);
- SetContextRequired({llvm::omp::Clause::OMPC_map});
- } break;
- case llvm::omp::Directive::OMPD_target_exit_data: {
- // 2.10.3 target-enter-data-clause -> if-clause |
- // device-clause |
- // map-clause |
- // depend-clause |
- // nowait-clause
- OmpClauseSet allowed{llvm::omp::Clause::OMPC_map,
- llvm::omp::Clause::OMPC_depend, llvm::omp::Clause::OMPC_nowait};
- SetContextAllowed(allowed);
- OmpClauseSet allowedOnce{
- llvm::omp::Clause::OMPC_device, llvm::omp::Clause::OMPC_if};
- SetContextAllowedOnce(allowedOnce);
- SetContextRequired({llvm::omp::Clause::OMPC_map});
- } break;
- case llvm::omp::Directive::OMPD_target_update: {
- // 2.10.5 target-update
- } break;
- case llvm::omp::Directive::OMPD_ordered: {
- // 2.13.8 ordered-construct-clause -> depend-clause
- OmpClauseSet allowed{llvm::omp::Clause::OMPC_depend};
- SetContextAllowed(allowed);
- } break;
- default:
- // TODO others
- break;
- }
+ PushContextAndClauseSets(dir.source, dir.v);
}
void OmpStructureChecker::Leave(
@@ -712,7 +259,7 @@ void OmpStructureChecker::Leave(
void OmpStructureChecker::Enter(const parser::OpenMPFlushConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContext(dir.source, llvm::omp::Directive::OMPD_flush);
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_flush);
}
void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) {
@@ -721,7 +268,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPFlushConstruct &) {
void OmpStructureChecker::Enter(const parser::OpenMPCancelConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContext(dir.source, llvm::omp::Directive::OMPD_cancel);
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_cancel);
}
void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
@@ -731,7 +278,8 @@ void OmpStructureChecker::Leave(const parser::OpenMPCancelConstruct &) {
void OmpStructureChecker::Enter(
const parser::OpenMPCancellationPointConstruct &x) {
const auto &dir{std::get<parser::Verbatim>(x.t)};
- PushContext(dir.source, llvm::omp::Directive::OMPD_cancellation_point);
+ PushContextAndClauseSets(
+ dir.source, llvm::omp::Directive::OMPD_cancellation_point);
}
void OmpStructureChecker::Leave(
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 1585b0c861ad..eff0eb4aa76b 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -25,6 +25,9 @@ using OmpDirectiveSet = Fortran::common::EnumSet<llvm::omp::Directive,
using OmpClauseSet =
Fortran::common::EnumSet<llvm::omp::Clause, llvm::omp::Clause_enumSize>;
+#define GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+#include "llvm/Frontend/OpenMP/OMP.cpp.inc"
+
namespace llvm {
namespace omp {
static OmpDirectiveSet parallelSet{Directive::OMPD_distribute_parallel_do,
@@ -151,6 +154,9 @@ class OmpStructureChecker : public virtual BaseChecker {
void Enter(const parser::OmpScheduleClause &);
private:
+#define GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+#include "llvm/Frontend/OpenMP/OMP.cpp.inc"
+
struct OmpContext {
OmpContext(parser::CharBlock source, llvm::omp::Directive d)
: directiveSource{source}, directive{d} {}
@@ -216,7 +222,20 @@ class OmpStructureChecker : public virtual BaseChecker {
void PushContext(const parser::CharBlock &source, llvm::omp::Directive dir) {
ompContext_.emplace_back(source, dir);
}
-
+ void SetClauseSets(llvm::omp::Directive dir) {
+ ompContext_.back().allowedClauses = directiveClausesTable[dir].allowed;
+ ompContext_.back().allowedOnceClauses =
+ directiveClausesTable[dir].allowedOnce;
+ ompContext_.back().allowedExclusiveClauses =
+ directiveClausesTable[dir].allowedExclusive;
+ ompContext_.back().requiredClauses =
+ directiveClausesTable[dir].requiredOneOf;
+ }
+ void PushContextAndClauseSets(
+ const parser::CharBlock &source, llvm::omp::Directive dir) {
+ PushContext(source, dir);
+ SetClauseSets(dir);
+ }
void RequiresConstantPositiveParameter(
const llvm::omp::Clause &clause, const parser::ScalarIntConstantExpr &i);
void RequiresPositiveParameter(
diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90
index e3f43dc5445e..77e40e323e5f 100644
--- a/flang/test/Semantics/omp-clause-validity01.f90
+++ b/flang/test/Semantics/omp-clause-validity01.f90
@@ -458,7 +458,6 @@
enddo
!$omp end taskloop simd
- !ERROR: REDUCTION clause is not allowed on the TASKLOOP SIMD directive
!$omp taskloop simd reduction(+:a)
do i = 1, N
a = a + 3.14
diff --git a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
index 785a520613b9..3c295a1d7c5f 100644
--- a/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
+++ b/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -43,6 +43,9 @@ class DirectiveLanguage {
// Header file included in the implementation code generated. Ususally the
// output file of the declaration code generation. Can be left blank.
string includeHeader = "";
+
+ // EnumSet class name used for clauses to generated the allowed clauses map.
+ string clauseEnumSetClass = "";
}
// Information about a specific clause.
@@ -92,6 +95,9 @@ class Directive<string d> {
// List of clauses that are allowed to appear only once.
list<VersionedClause> allowedOnceClauses = [];
+ // List of clauses that are allowed but mutually exclusive.
+ list<VersionedClause> allowedExclusiveClauses = [];
+
// List of clauses that are required.
list<VersionedClause> requiredClauses = [];
diff --git a/llvm/include/llvm/Frontend/OpenMP/CMakeLists.txt b/llvm/include/llvm/Frontend/OpenMP/CMakeLists.txt
index 69f503675940..3ff89888bfd6 100644
--- a/llvm/include/llvm/Frontend/OpenMP/CMakeLists.txt
+++ b/llvm/include/llvm/Frontend/OpenMP/CMakeLists.txt
@@ -1,3 +1,4 @@
set(LLVM_TARGET_DEFINITIONS OMP.td)
tablegen(LLVM OMP.h.inc --gen-directive-decl)
+tablegen(LLVM OMP.cpp.inc --gen-directive-gen)
add_public_tablegen_target(omp_gen)
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index bd81eeb01127..a565bdf90b3f 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -24,6 +24,7 @@ def OpenMP : DirectiveLanguage {
let makeEnumAvailableInNamespace = 1;
let enableBitmaskEnumInNamespace = 1;
let includeHeader = "llvm/Frontend/OpenMP/OMP.h.inc";
+ let clauseEnumSetClass = "OmpClauseSet";
}
//===----------------------------------------------------------------------===//
@@ -201,10 +202,7 @@ def OMPC_Notinbranch : Clause<"notinbranch"> {}
def OMP_ThreadPrivate : Directive<"threadprivate"> {}
def OMP_Parallel : Directive<"parallel"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_Shared>,
@@ -212,11 +210,14 @@ def OMP_Parallel : Directive<"parallel"> {
VersionedClause<OMPC_Copyin>,
VersionedClause<OMPC_Allocate>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ ];
}
def OMP_Task : Directive<"task"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Final>,
VersionedClause<OMPC_Default>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
@@ -224,12 +225,16 @@ def OMP_Task : Directive<"task"> {
VersionedClause<OMPC_Untied>,
VersionedClause<OMPC_Mergeable>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_Priority>,
VersionedClause<OMPC_InReduction>,
VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_Detach, 50>,
VersionedClause<OMPC_Affinity, 50>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Priority>
+ ];
}
def OMP_Simd : Directive<"simd"> {
let allowedClauses = [
@@ -237,15 +242,17 @@ def OMP_Simd : Directive<"simd"> {
VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Linear>,
VersionedClause<OMPC_Aligned>,
- VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_Reduction>,
VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_If, 50>,
VersionedClause<OMPC_NonTemporal, 50>,
VersionedClause<OMPC_Order, 50>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_If, 50>,
+ ];
}
def OMP_For : Directive<"for"> {
let allowedClauses = [
@@ -273,7 +280,8 @@ def OMP_Do : Directive<"do"> {
let allowedOnceClauses = [
VersionedClause<OMPC_Schedule>,
VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_Ordered>
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_NoWait>
];
}
def OMP_Sections : Directive<"sections"> {
@@ -345,30 +353,34 @@ def OMP_Atomic : Directive<"atomic"> {
def OMP_Target : Directive<"target"> {
let allowedClauses = [
VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_IsDevicePtr>,
VersionedClause<OMPC_Reduction>,
VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_UsesAllocators, 50>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NoWait>
+ ];
}
def OMP_Teams : Directive<"teams"> {
let allowedClauses = [
- VersionedClause<OMPC_Default>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_NumTeams>,
- VersionedClause<OMPC_ThreadLimit>,
VersionedClause<OMPC_Allocate>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>
+ ];
}
def OMP_Cancel : Directive<"cancel"> {
let allowedClauses = [
@@ -386,50 +398,64 @@ def OMP_Requires : Directive<"requires"> {
}
def OMP_TargetData : Directive<"target data"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_UseDevicePtr>,
VersionedClause<OMPC_UseDeviceAddr, 50>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_If>
+ ];
+ let requiredClauses = [
+ VersionedClause<OMPC_Map>
+ ];
}
def OMP_TargetEnterData : Directive<"target enter data"> {
let allowedClauses = [
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_Map>
+ ];
+ let allowedOnceClauses = [
VersionedClause<OMPC_If>,
VersionedClause<OMPC_Device>,
- VersionedClause<OMPC_Map>,
- VersionedClause<OMPC_NoWait>,
- VersionedClause<OMPC_Depend>
+ VersionedClause<OMPC_NoWait>
];
}
def OMP_TargetExitData : Directive<"target exit data"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_Map>
+ ];
+ let allowedOnceClauses = [
VersionedClause<OMPC_Device>,
- VersionedClause<OMPC_Map>,
- VersionedClause<OMPC_NoWait>,
- VersionedClause<OMPC_Depend>
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NoWait>
+ ];
+ let requiredClauses = [
+ VersionedClause<OMPC_Map>
];
}
def OMP_TargetParallel : Directive<"target parallel"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
- VersionedClause<OMPC_DefaultMap>,
- VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
VersionedClause<OMPC_IsDevicePtr>,
VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_UsesAllocators, 50>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>
+ ];
}
def OMP_TargetParallelFor : Directive<"target parallel for"> {
let allowedClauses = [
@@ -459,27 +485,31 @@ def OMP_TargetParallelFor : Directive<"target parallel for"> {
}
def OMP_TargetParallelDo : Directive<"target parallel do"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
- VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
- VersionedClause<OMPC_NumThreads>,
- VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_Ordered>,
VersionedClause<OMPC_Linear>,
VersionedClause<OMPC_IsDevicePtr>,
VersionedClause<OMPC_Allocator>,
VersionedClause<OMPC_Order>,
- VersionedClause<OMPC_UsesAllocators>
+ VersionedClause<OMPC_UsesAllocators>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Copyin>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_NoWait>
];
}
def OMP_TargetUpdate : Directive<"target update"> {
@@ -558,27 +588,29 @@ def OMP_ParallelForSimd : Directive<"parallel for simd"> {
}
def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
VersionedClause<OMPC_Copyin>,
VersionedClause<OMPC_LastPrivate>,
- VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>,
VersionedClause<OMPC_Linear>,
VersionedClause<OMPC_Aligned>,
- VersionedClause<OMPC_Ordered>,
VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_NonTemporal>,
VersionedClause<OMPC_Order>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>
+ ];
}
def OMP_ParallelMaster : Directive<"parallel master"> {
let allowedClauses = [
@@ -597,7 +629,6 @@ def OMP_ParallelMaster : Directive<"parallel master"> {
def OMP_ParallelSections : Directive<"parallel sections"> {
let allowedClauses = [
VersionedClause<OMPC_If>,
- VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_Default>,
VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Private>,
@@ -608,6 +639,9 @@ def OMP_ParallelSections : Directive<"parallel sections"> {
VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Allocate>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NumThreads>
+ ];
}
def OMP_ForSimd : Directive<"for simd"> {
let allowedClauses = [
@@ -643,7 +677,8 @@ def OMP_DoSimd : Directive<"do simd"> {
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_Ordered>,
VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_NoWait>
];
}
def OMP_CancellationPoint : Directive<"cancellation point"> {}
@@ -653,53 +688,74 @@ def OMP_DeclareMapper : Directive<"declare mapper"> {
VersionedClause<OMPC_Map>
];
}
-def OMP_DeclareSimd : Directive<"declare simd"> {}
+def OMP_DeclareSimd : Directive<"declare simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Uniform>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_SimdLen>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<OMPC_Inbranch>,
+ VersionedClause<OMPC_Notinbranch>
+ ];
+}
def OMP_TaskLoop : Directive<"taskloop"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_Final>,
VersionedClause<OMPC_Untied>,
VersionedClause<OMPC_Mergeable>,
- VersionedClause<OMPC_Priority>,
- VersionedClause<OMPC_GrainSize>,
VersionedClause<OMPC_NoGroup>,
- VersionedClause<OMPC_NumTasks>,
VersionedClause<OMPC_Reduction>,
VersionedClause<OMPC_InReduction>,
VersionedClause<OMPC_Allocate>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Priority>,
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NumTasks>
+ ];
}
def OMP_TaskLoopSimd : Directive<"taskloop simd"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Shared>,
- VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_InReduction>,
VersionedClause<OMPC_LastPrivate>,
- VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_Final>,
- VersionedClause<OMPC_Untied>,
- VersionedClause<OMPC_Mergeable>,
- VersionedClause<OMPC_Priority>,
VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
- VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_Mergeable>,
VersionedClause<OMPC_NoGroup>,
- VersionedClause<OMPC_NumTasks>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_InReduction>,
- VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_NonTemporal, 50>,
VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Untied>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Priority>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NumTasks>
];
}
def OMP_Distribute : Directive<"distribute"> {
@@ -707,10 +763,12 @@ def OMP_Distribute : Directive<"distribute"> {
VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
- VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_DistSchedule>,
VersionedClause<OMPC_Allocate>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>
+ ];
}
def OMP_DeclareTarget : Directive<"declare target"> {}
def OMP_EndDeclareTarget : Directive<"end declare target"> {}
@@ -735,21 +793,25 @@ def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
}
def OMP_DistributeParallelDo : Directive<"distribute parallel do"> {
let allowedClauses = [
+ VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>
+ ];
+ let allowedOnceClauses = [
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_NumThreads>,
- VersionedClause<OMPC_Default>,
VersionedClause<OMPC_ProcBind>,
- VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_Shared>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_Copyin>,
VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_Order>
+ VersionedClause<OMPC_Ordered>
];
}
def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
@@ -802,22 +864,31 @@ def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
}
def OMP_DistributeSimd : Directive<"distribute simd"> {
let allowedClauses = [
- VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Linear>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>
+ ];
+ let allowedOnceClauses = [
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
- VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
- VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_If, 50>,
- VersionedClause<OMPC_NonTemporal, 50>,
- VersionedClause<OMPC_Order, 50>
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>
];
}
+
def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
let allowedClauses = [
VersionedClause<OMPC_If>,
@@ -880,27 +951,33 @@ def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
}
def OMP_TargetSimd : Directive<"target simd"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
- VersionedClause<OMPC_Map>,
- VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_IsDevicePtr>,
VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
- VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Map>,
VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_UsesAllocators, 50>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Schedule>
+ ];
}
def OMP_TeamsDistribute : Directive<"teams distribute"> {
let allowedClauses = [
@@ -919,26 +996,29 @@ def OMP_TeamsDistribute : Directive<"teams distribute"> {
}
def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> {
let allowedClauses = [
- VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_FirstPrivate>,
- VersionedClause<OMPC_Shared>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_NumTeams>,
- VersionedClause<OMPC_ThreadLimit>,
VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>
+ ];
+ let allowedOnceClauses = [
VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_DistSchedule>,
- VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_If, 50>,
+ VersionedClause<OMPC_NumTeams>,
VersionedClause<OMPC_SafeLen>,
VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_If, 50>,
- VersionedClause<OMPC_NonTemporal, 50>,
- VersionedClause<OMPC_Order, 50>
+ VersionedClause<OMPC_ThreadLimit>
];
}
+
def OMP_TeamsDistributeParallelForSimd :
Directive<"teams distribute parallel for simd"> {
let allowedClauses = [
@@ -968,27 +1048,29 @@ def OMP_TeamsDistributeParallelForSimd :
def OMP_TeamsDistributeParallelDoSimd :
Directive<"teams distribute parallel do simd"> {
let allowedClauses = [
+ VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_NonTemporal>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
- VersionedClause<OMPC_If>,
VersionedClause<OMPC_NumThreads>,
- VersionedClause<OMPC_Default>,
VersionedClause<OMPC_ProcBind>,
- VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_Shared>,
- VersionedClause<OMPC_Reduction>,
VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
VersionedClause<OMPC_SafeLen>,
VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_NumTeams>,
- VersionedClause<OMPC_ThreadLimit>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_NonTemporal>,
- VersionedClause<OMPC_Order>
+ VersionedClause<OMPC_If>,
];
}
def OMP_TeamsDistributeParallelFor :
@@ -1016,68 +1098,78 @@ def OMP_TeamsDistributeParallelFor :
def OMP_TeamsDistributeParallelDo :
Directive<"teams distribute parallel do"> {
let allowedClauses = [
+ VersionedClause<OMPC_Private>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>
+ ];
+let allowedOnceClauses = [
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Order>,
VersionedClause<OMPC_If>,
VersionedClause<OMPC_NumThreads>,
- VersionedClause<OMPC_Default>,
VersionedClause<OMPC_ProcBind>,
- VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_Shared>,
- VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_NumTeams>,
- VersionedClause<OMPC_ThreadLimit>,
- VersionedClause<OMPC_Copyin>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_Order>
+ VersionedClause<OMPC_Schedule>
];
}
def OMP_TargetTeams : Directive<"target teams"> {
let allowedClauses = [
VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_IsDevicePtr>,
- VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
- VersionedClause<OMPC_NumTeams>,
- VersionedClause<OMPC_ThreadLimit>,
VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_UsesAllocators, 50>
+ VersionedClause<OMPC_UsesAllocators, 50>,
+ VersionedClause<OMPC_Shared>
+ ];
+
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>
];
}
def OMP_TargetTeamsDistribute : Directive<"target teams distribute"> {
let allowedClauses = [
VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_IsDevicePtr>,
- VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators, 50>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_NumTeams>,
VersionedClause<OMPC_ThreadLimit>,
- VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Collapse>,
- VersionedClause<OMPC_DistSchedule>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_UsesAllocators, 50>
+ VersionedClause<OMPC_DistSchedule>
];
}
+
def OMP_TargetTeamsDistributeParallelFor :
Directive<"target teams distribute parallel for"> {
let allowedClauses = [
@@ -1110,28 +1202,33 @@ def OMP_TargetTeamsDistributeParallelDo :
Directive<"target teams distribute parallel do"> {
let allowedClauses = [
VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_IsDevicePtr>,
- VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Order>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_NumTeams>,
VersionedClause<OMPC_ThreadLimit>,
- VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_Order>,
- VersionedClause<OMPC_UsesAllocators>
];
}
def OMP_TargetTeamsDistributeParallelForSimd :
@@ -1170,63 +1267,69 @@ def OMP_TargetTeamsDistributeParallelForSimd :
def OMP_TargetTeamsDistributeParallelDoSimd :
Directive<"target teams distribute parallel do simd"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
VersionedClause<OMPC_Map>,
VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
VersionedClause<OMPC_IsDevicePtr>,
- VersionedClause<OMPC_Default>,
- VersionedClause<OMPC_Shared>,
VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_NonTemporal>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Default>,
VersionedClause<OMPC_NumTeams>,
VersionedClause<OMPC_ThreadLimit>,
- VersionedClause<OMPC_LastPrivate>,
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
VersionedClause<OMPC_NumThreads>,
VersionedClause<OMPC_ProcBind>,
VersionedClause<OMPC_Schedule>,
- VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
VersionedClause<OMPC_SafeLen>,
- VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_NonTemporal>,
- VersionedClause<OMPC_Order>,
- VersionedClause<OMPC_UsesAllocators>
+ VersionedClause<OMPC_SimdLen>
];
}
def OMP_TargetTeamsDistributeSimd :
Directive<"target teams distribute simd"> {
let allowedClauses = [
- VersionedClause<OMPC_If>,
- VersionedClause<OMPC_Device>,
- VersionedClause<OMPC_Map>,
- VersionedClause<OMPC_Private>,
- VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
VersionedClause<OMPC_Depend>,
- VersionedClause<OMPC_DefaultMap>,
VersionedClause<OMPC_FirstPrivate>,
- VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_If>,
VersionedClause<OMPC_IsDevicePtr>,
- VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NoWait>,
VersionedClause<OMPC_NumTeams>,
VersionedClause<OMPC_ThreadLimit>,
VersionedClause<OMPC_Collapse>,
VersionedClause<OMPC_DistSchedule>,
- VersionedClause<OMPC_Linear>,
- VersionedClause<OMPC_Aligned>,
VersionedClause<OMPC_SafeLen>,
VersionedClause<OMPC_SimdLen>,
- VersionedClause<OMPC_Allocate>,
- VersionedClause<OMPC_NonTemporal, 50>,
- VersionedClause<OMPC_Order, 50>,
- VersionedClause<OMPC_UsesAllocators, 50>
];
}
def OMP_Allocate : Directive<"allocate"> {
@@ -1359,7 +1462,22 @@ def OMP_Scan : Directive<"scan"> {
}
def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {}
def OMP_EndDeclareVariant : Directive<"end declare variant"> {}
-def OMP_ParallelWorkshare : Directive<"parallel workshare"> {}
+def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>
+ ];
+}
def OMP_Workshare : Directive<"workshare"> {}
def OMP_EndDo : Directive<"end do"> {}
def OMP_EndDoSimd : Directive<"end do simd"> {}
diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td
index 8b3cc8702bd4..b293196d4d55 100644
--- a/llvm/test/TableGen/directive1.td
+++ b/llvm/test/TableGen/directive1.td
@@ -1,5 +1,6 @@
// RUN: llvm-tblgen -gen-directive-decl -I %p/../../include %s | FileCheck -match-full-lines %s
// RUN: llvm-tblgen -gen-directive-impl -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=IMPL
+// RUN: llvm-tblgen -gen-directive-gen -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=GEN
include "llvm/Frontend/Directive/DirectiveBase.td"
@@ -126,3 +127,57 @@ def TDL_DirA : Directive<"dira"> {
// IMPL-NEXT: }
// IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind");
// IMPL-NEXT: }
+// IMPL-EMPTY:
+
+
+
+// GEN: #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+// GEN-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+// GEN-EMPTY:
+// GEN-NEXT: namespace llvm {
+// GEN-NEXT: namespace tdl {
+// GEN-EMPTY:
+// GEN-NEXT: // Sets for dira
+// GEN-EMPTY:
+// GEN-NEXT: static allowedClauses_TDLD_dira {
+// GEN-NEXT: llvm::tdl::Clause::TDLC_clausea,
+// GEN-NEXT: llvm::tdl::Clause::TDLC_clauseb,
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: static allowedOnceClauses_TDLD_dira {
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: static allowedExclusiveClauses_TDLD_dira {
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: static requiredClauses_TDLD_dira {
+// GEN-NEXT: };
+// GEN-NEXT: } // namespace tdl
+// GEN-NEXT: } // namespace llvm
+// GEN-EMPTY:
+// GEN-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+// GEN-EMPTY:
+// GEN-NEXT: #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+// GEN-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+// GEN-EMPTY:
+// GEN-NEXT: struct TdlDirectiveClauses {
+// GEN-NEXT: const allowed;
+// GEN-NEXT: const allowedOnce;
+// GEN-NEXT: const allowedExclusive;
+// GEN-NEXT: const requiredOneOf;
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: std::unordered_map<llvm::tdl::Directive, TdlDirectiveClauses>
+// GEN-NEXT: directiveClausesTable = {
+// GEN-NEXT: {llvm::tdl::Directive::TDLD_dira,
+// GEN-NEXT: {
+// GEN-NEXT: llvm::tdl::allowedClauses_TDLD_dira,
+// GEN-NEXT: llvm::tdl::allowedOnceClauses_TDLD_dira,
+// GEN-NEXT: llvm::tdl::allowedExclusiveClauses_TDLD_dira,
+// GEN-NEXT: llvm::tdl::requiredClauses_TDLD_dira,
+// GEN-NEXT: }
+// GEN-NEXT: },
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+
diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td
index 06c7aabcf3ad..517c79d45798 100644
--- a/llvm/test/TableGen/directive2.td
+++ b/llvm/test/TableGen/directive2.td
@@ -1,5 +1,6 @@
// RUN: llvm-tblgen -gen-directive-decl -I %p/../../include %s | FileCheck -match-full-lines %s
// RUN: llvm-tblgen -gen-directive-impl -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=IMPL
+// RUN: llvm-tblgen -gen-directive-gen -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=GEN
include "llvm/Frontend/Directive/DirectiveBase.td"
@@ -71,7 +72,7 @@ def TDL_DirA : Directive<"dira"> {
// IMPL-NEXT: using namespace llvm;
// IMPL-NEXT: using namespace tdl;
// IMPL-EMPTY:
-// IMPL: Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) {
+// IMPL-NEXT: Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) {
// IMPL-NEXT: return llvm::StringSwitch<Directive>(Str)
// IMPL-NEXT: .Case("dira",TDLD_dira)
// IMPL-NEXT: .Default(TDLD_dira);
@@ -119,3 +120,54 @@ def TDL_DirA : Directive<"dira"> {
// IMPL-NEXT: }
// IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind");
// IMPL-NEXT: }
+
+
+// GEN: #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+// GEN-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+// GEN-EMPTY:
+// GEN-NEXT: namespace llvm {
+// GEN-NEXT: namespace tdl {
+// GEN-EMPTY:
+// GEN-NEXT: // Sets for dira
+// GEN-EMPTY:
+// GEN-NEXT: static allowedClauses_TDLD_dira {
+// GEN-NEXT: llvm::tdl::Clause::TDLC_clausea,
+// GEN-NEXT: llvm::tdl::Clause::TDLC_clauseb,
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: static allowedOnceClauses_TDLD_dira {
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: static allowedExclusiveClauses_TDLD_dira {
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: static requiredClauses_TDLD_dira {
+// GEN-NEXT: };
+// GEN-NEXT: } // namespace tdl
+// GEN-NEXT: } // namespace llvm
+// GEN-EMPTY:
+// GEN-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_SETS
+// GEN-EMPTY:
+// GEN-NEXT: #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+// GEN-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_MAP
+// GEN-EMPTY:
+// GEN-NEXT: struct TdlDirectiveClauses {
+// GEN-NEXT: const allowed;
+// GEN-NEXT: const allowedOnce;
+// GEN-NEXT: const allowedExclusive;
+// GEN-NEXT: const requiredOneOf;
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: std::unordered_map<llvm::tdl::Directive, TdlDirectiveClauses>
+// GEN-NEXT: directiveClausesTable = {
+// GEN-NEXT: {llvm::tdl::Directive::TDLD_dira,
+// GEN-NEXT: {
+// GEN-NEXT: llvm::tdl::allowedClauses_TDLD_dira,
+// GEN-NEXT: llvm::tdl::allowedOnceClauses_TDLD_dira,
+// GEN-NEXT: llvm::tdl::allowedExclusiveClauses_TDLD_dira,
+// GEN-NEXT: llvm::tdl::requiredClauses_TDLD_dira,
+// GEN-NEXT: }
+// GEN-NEXT: },
+// GEN-NEXT: };
+// GEN-EMPTY:
+// GEN-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP
diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp
index f51f98872bb5..fc4a6757f808 100644
--- a/llvm/utils/TableGen/DirectiveEmitter.cpp
+++ b/llvm/utils/TableGen/DirectiveEmitter.cpp
@@ -14,12 +14,30 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
using namespace llvm;
+namespace {
+// Simple RAII helper for defining ifdef-undef-endif scopes.
+class IfDefScope {
+public:
+ IfDefScope(StringRef Name, raw_ostream &OS) : Name(Name), OS(OS) {
+ OS << "#ifdef " << Name << "\n"
+ << "#undef " << Name << "\n";
+ }
+
+ ~IfDefScope() { OS << "\n#endif // " << Name << "\n\n"; }
+
+private:
+ StringRef Name;
+ raw_ostream &OS;
+};
+} // end anonymous namespace
+
namespace llvm {
// Get Directive or Clause name formatted by replacing whitespaces with
@@ -205,16 +223,21 @@ void GenerateGetKind(const std::vector<Record *> &Records, raw_ostream &OS,
void GenerateCaseForVersionedClauses(const std::vector<Record *> &Clauses,
raw_ostream &OS, StringRef DirectiveName,
StringRef DirectivePrefix,
- StringRef ClausePrefix) {
+ StringRef ClausePrefix,
+ llvm::StringSet<> &Cases) {
for (const auto &C : Clauses) {
const auto MinVersion = C->getValueAsInt("minVersion");
const auto MaxVersion = C->getValueAsInt("maxVersion");
const auto SpecificClause = C->getValueAsDef("clause");
- const auto ClauseName = SpecificClause->getValueAsString("name");
- OS << " case " << ClausePrefix << getFormattedName(ClauseName)
- << ":\n";
- OS << " return " << MinVersion << " <= Version && " << MaxVersion
- << " >= Version;\n";
+ const auto ClauseName =
+ getFormattedName(SpecificClause->getValueAsString("name"));
+
+ if (Cases.find(ClauseName) == Cases.end()) {
+ Cases.insert(ClauseName);
+ OS << " case " << ClausePrefix << ClauseName << ":\n";
+ OS << " return " << MinVersion << " <= Version && " << MaxVersion
+ << " >= Version;\n";
+ }
}
}
@@ -239,24 +262,32 @@ void GenerateIsAllowedClause(const std::vector<Record *> &Directives,
const auto &AllowedClauses = D->getValueAsListOfDefs("allowedClauses");
const auto &AllowedOnceClauses =
D->getValueAsListOfDefs("allowedOnceClauses");
+ const auto &AllowedExclusiveClauses =
+ D->getValueAsListOfDefs("allowedExclusiveClauses");
const auto &RequiredClauses = D->getValueAsListOfDefs("requiredClauses");
OS << " case " << DirectivePrefix << getFormattedName(DirectiveName)
<< ":\n";
- if (AllowedClauses.size() == 0 && AllowedOnceClauses.size() == 0 &&
- AllowedOnceClauses.size() == 0) {
+ if (AllowedClauses.size() == 0 && AllowedOnceClauses.size() == 0 &&
+ AllowedExclusiveClauses.size() == 0 && RequiredClauses.size() == 0) {
OS << " return false;\n";
} else {
OS << " switch (C) {\n";
+ llvm::StringSet<> Cases;
+
GenerateCaseForVersionedClauses(AllowedClauses, OS, DirectiveName,
- DirectivePrefix, ClausePrefix);
+ DirectivePrefix, ClausePrefix, Cases);
GenerateCaseForVersionedClauses(AllowedOnceClauses, OS, DirectiveName,
- DirectivePrefix, ClausePrefix);
+ DirectivePrefix, ClausePrefix, Cases);
+
+ GenerateCaseForVersionedClauses(AllowedExclusiveClauses, OS,
+ DirectiveName, DirectivePrefix,
+ ClausePrefix, Cases);
GenerateCaseForVersionedClauses(RequiredClauses, OS, DirectiveName,
- DirectivePrefix, ClausePrefix);
+ DirectivePrefix, ClausePrefix, Cases);
OS << " default:\n";
OS << " return false;\n";
@@ -271,9 +302,143 @@ void GenerateIsAllowedClause(const std::vector<Record *> &Directives,
OS << "}\n"; // End of function isAllowedClauseForDirective
}
+// Generate a simple enum set with the give clauses.
+void GenerateClauseSet(const std::vector<Record *> &Clauses, raw_ostream &OS,
+ StringRef ClauseEnumSetClass, StringRef ClauseSetPrefix,
+ StringRef DirectiveName, StringRef DirectivePrefix,
+ StringRef ClausePrefix, StringRef CppNamespace) {
+
+ OS << "\n";
+ OS << " static " << ClauseEnumSetClass << " " << ClauseSetPrefix
+ << DirectivePrefix << getFormattedName(DirectiveName) << " {\n";
+
+ for (const auto &C : Clauses) {
+ const auto SpecificClause = C->getValueAsDef("clause");
+ const auto ClauseName = SpecificClause->getValueAsString("name");
+ OS << " llvm::" << CppNamespace << "::Clause::" << ClausePrefix
+ << getFormattedName(ClauseName) << ",\n";
+ }
+ OS << " };\n";
+}
+
+// Generate an enum set for the 4 kinds of clauses linked to a directive.
+void GenerateDirectiveClauseSets(const std::vector<Record *> &Directives,
+ raw_ostream &OS, StringRef LanguageName,
+ StringRef ClauseEnumSetClass,
+ StringRef DirectivePrefix,
+ StringRef ClausePrefix,
+ StringRef CppNamespace) {
+
+ IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_SETS", OS);
+
+ OS << "\n";
+ OS << "namespace llvm {\n";
+
+ // Open namespaces defined in the directive language.
+ llvm::SmallVector<StringRef, 2> Namespaces;
+ llvm::SplitString(CppNamespace, Namespaces, "::");
+ for (auto Ns : Namespaces)
+ OS << "namespace " << Ns << " {\n";
+
+ for (const auto &D : Directives) {
+ const auto DirectiveName = D->getValueAsString("name");
+
+ const auto &AllowedClauses = D->getValueAsListOfDefs("allowedClauses");
+ const auto &AllowedOnceClauses =
+ D->getValueAsListOfDefs("allowedOnceClauses");
+ const auto &AllowedExclusiveClauses =
+ D->getValueAsListOfDefs("allowedExclusiveClauses");
+ const auto &RequiredClauses = D->getValueAsListOfDefs("requiredClauses");
+
+ OS << "\n";
+ OS << " // Sets for " << DirectiveName << "\n";
+
+ GenerateClauseSet(AllowedClauses, OS, ClauseEnumSetClass, "allowedClauses_",
+ DirectiveName, DirectivePrefix, ClausePrefix,
+ CppNamespace);
+ GenerateClauseSet(AllowedOnceClauses, OS, ClauseEnumSetClass,
+ "allowedOnceClauses_", DirectiveName, DirectivePrefix,
+ ClausePrefix, CppNamespace);
+ GenerateClauseSet(AllowedExclusiveClauses, OS, ClauseEnumSetClass,
+ "allowedExclusiveClauses_", DirectiveName,
+ DirectivePrefix, ClausePrefix, CppNamespace);
+ GenerateClauseSet(RequiredClauses, OS, ClauseEnumSetClass,
+ "requiredClauses_", DirectiveName, DirectivePrefix,
+ ClausePrefix, CppNamespace);
+ }
+
+ // Closing namespaces
+ for (auto Ns : llvm::reverse(Namespaces))
+ OS << "} // namespace " << Ns << "\n";
+
+ OS << "} // namespace llvm\n";
+}
+
+// Generate a map of directive (key) with DirectiveClauses struct as values.
+// The struct holds the 4 sets of enumeration for the 4 kinds of clauses
+// allowances (allowed, allowed once, allowed exclusive and required).
+void GenerateDirectiveClauseMap(const std::vector<Record *> &Directives,
+ raw_ostream &OS, StringRef LanguageName,
+ StringRef ClauseEnumSetClass,
+ StringRef DirectivePrefix,
+ StringRef ClausePrefix,
+ StringRef CppNamespace) {
+
+ IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_MAP", OS);
+
+ OS << "\n";
+ OS << "struct " << LanguageName << "DirectiveClauses {\n";
+ OS << " const " << ClauseEnumSetClass << " allowed;\n";
+ OS << " const " << ClauseEnumSetClass << " allowedOnce;\n";
+ OS << " const " << ClauseEnumSetClass << " allowedExclusive;\n";
+ OS << " const " << ClauseEnumSetClass << " requiredOneOf;\n";
+ OS << "};\n";
+
+ OS << "\n";
+
+ OS << "std::unordered_map<llvm::" << CppNamespace << "::Directive, "
+ << LanguageName << "DirectiveClauses>\n";
+ OS << " directiveClausesTable = {\n";
+
+ for (const auto &D : Directives) {
+ const auto FormattedDirectiveName =
+ getFormattedName(D->getValueAsString("name"));
+ OS << " {llvm::" << CppNamespace << "::Directive::" << DirectivePrefix
+ << FormattedDirectiveName << ",\n";
+ OS << " {\n";
+ OS << " llvm::" << CppNamespace << "::allowedClauses_"
+ << DirectivePrefix << FormattedDirectiveName << ",\n";
+ OS << " llvm::" << CppNamespace << "::allowedOnceClauses_"
+ << DirectivePrefix << FormattedDirectiveName << ",\n";
+ OS << " llvm::" << CppNamespace << "::allowedExclusiveClauses_"
+ << DirectivePrefix << FormattedDirectiveName << ",\n";
+ OS << " llvm::" << CppNamespace << "::requiredClauses_"
+ << DirectivePrefix << FormattedDirectiveName << ",\n";
+ OS << " }\n";
+ OS << " },\n";
+ }
+
+ OS << "};\n";
+}
+
// Generate the implemenation section for the enumeration in the directive
// language
-void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
+void EmitDirectivesFlangImpl(const std::vector<Record *> &Directives,
+ raw_ostream &OS, StringRef LanguageName,
+ StringRef ClauseEnumSetClass,
+ StringRef DirectivePrefix, StringRef ClausePrefix,
+ StringRef CppNamespace) {
+
+ GenerateDirectiveClauseSets(Directives, OS, LanguageName, ClauseEnumSetClass,
+ DirectivePrefix, ClausePrefix, CppNamespace);
+
+ GenerateDirectiveClauseMap(Directives, OS, LanguageName, ClauseEnumSetClass,
+ DirectivePrefix, ClausePrefix, CppNamespace);
+}
+
+// Generate the implemenation section for the enumeration in the directive
+// language.
+void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
const auto &DirectiveLanguages =
Records.getAllDerivedDefinitions("DirectiveLanguage");
@@ -289,12 +454,40 @@ void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
StringRef LanguageName = DirectiveLanguage->getValueAsString("name");
StringRef ClausePrefix = DirectiveLanguage->getValueAsString("clausePrefix");
StringRef CppNamespace = DirectiveLanguage->getValueAsString("cppNamespace");
- StringRef IncludeHeader =
- DirectiveLanguage->getValueAsString("includeHeader");
+ StringRef ClauseEnumSetClass =
+ DirectiveLanguage->getValueAsString("clauseEnumSetClass");
const auto &Directives = Records.getAllDerivedDefinitions("Directive");
const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
+ EmitDirectivesFlangImpl(Directives, OS, LanguageName, ClauseEnumSetClass,
+ DirectivePrefix, ClausePrefix, CppNamespace);
+}
+
+// Generate the implemenation for the enumeration in the directive
+// language. This code can be included in library.
+void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
+
+ const auto &DirectiveLanguages =
+ Records.getAllDerivedDefinitions("DirectiveLanguage");
+
+ if (DirectiveLanguages.size() != 1) {
+ PrintError("A single definition of DirectiveLanguage is needed.");
+ return;
+ }
+
+ const auto &DirectiveLanguage = DirectiveLanguages[0];
+ StringRef DirectivePrefix =
+ DirectiveLanguage->getValueAsString("directivePrefix");
+ StringRef LanguageName = DirectiveLanguage->getValueAsString("name");
+ StringRef ClausePrefix = DirectiveLanguage->getValueAsString("clausePrefix");
+ StringRef CppNamespace = DirectiveLanguage->getValueAsString("cppNamespace");
+ const auto &Directives = Records.getAllDerivedDefinitions("Directive");
+ const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
+
+ StringRef IncludeHeader =
+ DirectiveLanguage->getValueAsString("includeHeader");
+
if (!IncludeHeader.empty())
OS << "#include \"" << IncludeHeader << "\"\n\n";
@@ -323,6 +516,7 @@ void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
GenerateGetName(Clauses, OS, "Clause", ClausePrefix, LanguageName,
CppNamespace);
+ // isAllowedClauseForDirective(Directive D, Clause C, unsigned Version)
GenerateIsAllowedClause(Directives, OS, LanguageName, DirectivePrefix,
ClausePrefix, CppNamespace);
}
diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp
index 7438749a1243..8015a58471ca 100644
--- a/llvm/utils/TableGen/TableGen.cpp
+++ b/llvm/utils/TableGen/TableGen.cpp
@@ -56,6 +56,7 @@ enum ActionType {
GenAutomata,
GenDirectivesEnumDecl,
GenDirectivesEnumImpl,
+ GenDirectivesEnumGen,
};
namespace llvm {
@@ -132,9 +133,11 @@ cl::opt<ActionType> Action(
"Generate llvm-exegesis tables"),
clEnumValN(GenAutomata, "gen-automata", "Generate generic automata"),
clEnumValN(GenDirectivesEnumDecl, "gen-directive-decl",
- "Generate directive related declaration code"),
+ "Generate directive related declaration code (header file)"),
clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl",
- "Generate directive related implementation code")));
+ "Generate directive related implementation code"),
+ clEnumValN(GenDirectivesEnumGen, "gen-directive-gen",
+ "Generate directive related implementation code part")));
cl::OptionCategory PrintEnumsCat("Options for -print-enums");
cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"),
@@ -265,6 +268,9 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenDirectivesEnumImpl:
EmitDirectivesImpl(Records, OS);
break;
+ case GenDirectivesEnumGen:
+ EmitDirectivesGen(Records, OS);
+ break;
}
return false;
diff --git a/llvm/utils/TableGen/TableGenBackends.h b/llvm/utils/TableGen/TableGenBackends.h
index 9e6171abcabf..92204f39f8fa 100644
--- a/llvm/utils/TableGen/TableGenBackends.h
+++ b/llvm/utils/TableGen/TableGenBackends.h
@@ -92,6 +92,7 @@ void EmitExegesis(RecordKeeper &RK, raw_ostream &OS);
void EmitAutomata(RecordKeeper &RK, raw_ostream &OS);
void EmitDirectivesDecl(RecordKeeper &RK, raw_ostream &OS);
void EmitDirectivesImpl(RecordKeeper &RK, raw_ostream &OS);
+void EmitDirectivesGen(RecordKeeper &RK, raw_ostream &OS);
} // End llvm namespace
More information about the flang-commits
mailing list