[flang-commits] [flang] [llvm] [FLANG][OpenMP]Add frontend support for ASSUME and ASSUMES (PR #120770)
Mats Petersson via flang-commits
flang-commits at lists.llvm.org
Tue Dec 24 03:54:43 PST 2024
https://github.com/Leporacanthicus updated https://github.com/llvm/llvm-project/pull/120770
>From 8bc17fac5b91cfc30f4072d8cf8cdcbfbdc3f945 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Fri, 20 Dec 2024 16:04:59 +0000
Subject: [PATCH 1/2] [FLANG][OpenMP]Add frontend support for ASSUME and
ASSUMES
Enough suport to parse correctly formed directives of !$OMP ASSUME
and !$OMP ASSUMES with teh related clauses that go with them:
ABSENT, CONTAINS, NO_OPENPP, NO_OPENMP_ROUTINES, NO_PARALLELISM
and HOLDS.
Tests added for unparsing and dump parse-tree.
Semantics support is very minimal and no specific tests added.
The lowering will hit a TODO, and there are tests in Lower/OpenMP/Todo
to make it clear that this is currently expected behaviour.
---
.../FlangOmpReport/FlangOmpReportVisitor.cpp | 4 +
flang/include/flang/Parser/dump-parse-tree.h | 12 +++
flang/include/flang/Parser/parse-tree.h | 85 ++++++++++++++++++-
flang/lib/Lower/OpenMP/OpenMP.cpp | 18 ++++
flang/lib/Parser/openmp-parsers.cpp | 38 ++++++++-
flang/lib/Parser/unparse.cpp | 20 ++++-
flang/lib/Semantics/check-omp-structure.cpp | 17 ++++
flang/lib/Semantics/check-omp-structure.h | 4 +
flang/test/Lower/OpenMP/Todo/assume.f90 | 6 ++
flang/test/Lower/OpenMP/Todo/assumes.f90 | 9 ++
flang/test/Parser/OpenMP/assumption.f90 | 66 ++++++++++++++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 19 +++++
12 files changed, 295 insertions(+), 3 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/Todo/assume.f90
create mode 100644 flang/test/Lower/OpenMP/Todo/assumes.f90
create mode 100644 flang/test/Parser/OpenMP/assumption.f90
diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
index 665b92be008986..498cd2d7e33b24 100644
--- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
+++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
@@ -129,6 +129,10 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
const CharBlock &source{std::get<0>(c.t).source};
return normalize_construct_name(source.ToString());
},
+ [&](const OpenMPAssumeConstruct &c) -> std::string {
+ const CharBlock &source{std::get<0>(c.t).source};
+ return normalize_construct_name(source.ToString());
+ },
[&](const OpenMPAllocatorsConstruct &c) -> std::string {
const CharBlock &source{std::get<0>(c.t).source};
return normalize_construct_name(source.ToString());
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 940caaeea9c3b7..4c88b9583c25f9 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -483,6 +483,7 @@ class ParseTreeDumper {
NODE_ENUM(OmpMapTypeModifier, Value)
NODE(parser, OmpIteratorSpecifier)
NODE(parser, OmpIterator)
+ NODE(parser, OmpAbsentClause)
NODE(parser, OmpAffinityClause)
NODE(OmpAffinityClause, Modifier)
NODE(parser, OmpAlignment)
@@ -516,6 +517,7 @@ class ParseTreeDumper {
#include "llvm/Frontend/OpenMP/OMP.inc"
NODE(parser, OmpClauseList)
NODE(parser, OmpCriticalDirective)
+ NODE(parser, OmpContainsClause)
NODE(parser, OmpDeclareTargetSpecifier)
NODE(parser, OmpDeclareTargetWithClause)
NODE(parser, OmpDeclareTargetWithList)
@@ -555,6 +557,8 @@ class ParseTreeDumper {
NODE(parser, OmpExpectation)
NODE_ENUM(OmpExpectation, Value)
NODE(parser, OmpDirectiveNameModifier)
+ NODE(parser, OmpDirectiveNameEntry)
+ NODE(parser, OmpHoldsClause)
NODE(parser, OmpIfClause)
NODE(OmpIfClause, Modifier)
NODE(parser, OmpLastprivateClause)
@@ -578,6 +582,9 @@ class ParseTreeDumper {
}
NODE(parser, OmpObject)
NODE(parser, OmpObjectList)
+ NODE(parser, OmpNoOpenMPClause)
+ NODE(parser, OmpNoOpenMPRoutinesClause)
+ NODE(parser, OmpNoParallelismClause)
NODE(parser, OmpOrderClause)
NODE(OmpOrderClause, Modifier)
NODE_ENUM(OmpOrderClause, Ordering)
@@ -643,6 +650,11 @@ class ParseTreeDumper {
NODE(parser, OpenACCStandaloneDeclarativeConstruct)
NODE(parser, OpenACCStandaloneConstruct)
NODE(parser, OpenACCWaitConstruct)
+ NODE(parser, OpenMPAssumeConstruct)
+ NODE(parser, OpenMPAssumesConstruct)
+ NODE(parser, OpenMPAssumesPartConstruct)
+ NODE(parser, OmpAssumesDirective)
+ NODE(parser, OmpEndAssumesDirective)
NODE(parser, OpenMPAtomicConstruct)
NODE(parser, OpenMPBlockConstruct)
NODE(parser, OpenMPCancelConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 1d97126d17dbc4..a89938036d9c3f 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3740,6 +3740,19 @@ struct OmpVariableCategory {
// --- Clauses
+struct OmpDirectiveNameEntry {
+ WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameEntry, llvm::omp::Directive);
+};
+using OmpDirectiveList = std::list<OmpDirectiveNameEntry>;
+
+// Ref: [5.2:214]
+//
+// absent-clause ->
+// ABSENT(directive-name[, directive-name])
+struct OmpAbsentClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpAbsentClause, OmpDirectiveList);
+};
+
// Ref: [5.0:135-140], [5.1:161-166], [5.2:264-265]
//
// affinity-clause ->
@@ -3808,6 +3821,14 @@ struct OmpBindClause {
WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Binding);
};
+// Ref: [5.2:214]
+//
+// contains-clause ->
+// CONTAINS(directive-name[, directive-name])
+struct OmpContainsClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpContainsClause, OmpDirectiveList);
+};
+
// Ref: [4.5:46-50], [5.0:74-78], [5.1:92-96], [5.2:109]
//
// default-clause ->
@@ -3971,6 +3992,15 @@ struct OmpGrainsizeClause {
std::tuple<MODIFIERS(), ScalarIntExpr> t;
};
+// Ref: [5.2: 214]
+//
+// holds-clause ->
+// HOLDS(expr[, expr])
+struct OmpHoldsClause {
+ using ExprList = std::list<common::Indirection<Expr>>;
+ WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, ExprList);
+};
+
// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
// that allow the IF clause.
//
@@ -4042,6 +4072,21 @@ struct OmpMessageClause {
WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr);
};
+// Ref: [5.2: 214]
+//
+// no_openmp_clause -> NO_OPENMP
+EMPTY_CLASS(OmpNoOpenMPClause);
+
+// Ref: [5.2: 214]
+//
+// no_openmp_routines_clause -> NO_OPENMP_ROUTINES
+EMPTY_CLASS(OmpNoOpenMPRoutinesClause);
+
+// Ref: [5.2: 214]
+//
+// no_parallelism_clause -> NO_PARALELISM
+EMPTY_CLASS(OmpNoParallelismClause);
+
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
//
// num-tasks-clause ->
@@ -4174,6 +4219,44 @@ struct OmpClauseList {
// --- Directives and constructs
+// Ref: [5.2: 213-216]
+//
+// assume-construct ->
+// ASSUME absent-clause | contains-clause | holds-clause | no-openmp-clause |
+// no-openmp-routines-clause | no-parallelism-clause
+struct OpenMPAssumeConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPAssumeConstruct);
+ std::tuple<Verbatim, OmpClauseList> t;
+ CharBlock source;
+};
+
+struct OmpAssumesDirective {
+ TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
+ std::tuple<Verbatim, OmpClauseList> t;
+ CharBlock source;
+};
+
+struct OmpEndAssumesDirective {
+ TUPLE_CLASS_BOILERPLATE(OmpEndAssumesDirective);
+ std::tuple<Verbatim> t;
+ CharBlock source;
+};
+
+// structured-block
+// ...
+struct OpenMPAssumesPartConstruct {
+ WRAPPER_CLASS_BOILERPLATE(OpenMPAssumesPartConstruct, Block);
+ CharBlock source;
+};
+
+struct OpenMPAssumesConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
+ std::tuple<OmpAssumesDirective, OpenMPAssumesPartConstruct,
+ OmpEndAssumesDirective>
+ t;
+ CharBlock source;
+};
+
// 2.7.2 SECTIONS
// 2.11.2 PARALLEL SECTIONS
struct OmpSectionsDirective {
@@ -4580,7 +4663,7 @@ struct OpenMPConstruct {
OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPErrorConstruct,
OpenMPExecutableAllocate, OpenMPAllocatorsConstruct,
- OpenMPCriticalConstruct>
+ OpenMPAssumeConstruct, OpenMPAssumesConstruct, OpenMPCriticalConstruct>
u;
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index c61ab67d95a957..cc3cd95f69d77e 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2893,6 +2893,24 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue.begin());
}
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ const parser::OpenMPAssumeConstruct &assumeConstruct) {
+ const auto &verbatim = std::get<parser::Verbatim>(assumeConstruct.t);
+ mlir::Location clauseLocation = converter.genLocation(verbatim.source);
+ TODO(clauseLocation, "OpenMP ASSUME construct");
+}
+
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ const parser::OpenMPAssumesConstruct &assumesConstruct) {
+ mlir::Location clauseLocation =
+ converter.genLocation(assumesConstruct.source);
+ TODO(clauseLocation, "OpenMP ASSUMES construct");
+}
+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 67385c03f66c80..a9b995bbf5e2bb 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -577,7 +577,14 @@ TYPE_PARSER(construct<OmpSeverityClause>(
TYPE_PARSER(construct<OmpMessageClause>(expr))
-TYPE_PARSER(
+TYPE_PARSER(construct<OmpHoldsClause>(many(maybe(","_tok) >> indirect(expr))))
+TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
+ construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
+ construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+
+TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
+ parenthesized(Parser<OmpAbsentClause>{}))) ||
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
"AFFINITY" >> construct<OmpClause>(construct<OmpClause::Affinity>(
@@ -597,6 +604,8 @@ TYPE_PARSER(
parenthesized(Parser<OmpBindClause>{}))) ||
"COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
parenthesized(scalarIntConstantExpr))) ||
+ "CONTAINS" >> construct<OmpClause>(construct<OmpClause::Contains>(
+ parenthesized(Parser<OmpContainsClause>{}))) ||
"COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
parenthesized(Parser<OmpObjectList>{}))) ||
"COPYPRIVATE" >> construct<OmpClause>(construct<OmpClause::Copyprivate>(
@@ -641,6 +650,8 @@ TYPE_PARSER(
parenthesized(Parser<OmpObjectList>{}))) ||
"HINT" >> construct<OmpClause>(
construct<OmpClause::Hint>(parenthesized(constantExpr))) ||
+ "HOLDS" >> construct<OmpClause>(construct<OmpClause::Holds>(
+ parenthesized(Parser<OmpHoldsClause>{}))) ||
"IF" >> construct<OmpClause>(construct<OmpClause::If>(
parenthesized(Parser<OmpIfClause>{}))) ||
"INBRANCH" >> construct<OmpClause>(construct<OmpClause::Inbranch>()) ||
@@ -665,6 +676,11 @@ TYPE_PARSER(
"NOTINBRANCH" >>
construct<OmpClause>(construct<OmpClause::Notinbranch>()) ||
"NOWAIT" >> construct<OmpClause>(construct<OmpClause::Nowait>()) ||
+ "NO_OPENMP"_id >> construct<OmpClause>(construct<OmpClause::NoOpenmp>()) ||
+ "NO_OPENMP_ROUTINES" >>
+ construct<OmpClause>(construct<OmpClause::NoOpenmpRoutines>()) ||
+ "NO_PARALLELISM" >>
+ construct<OmpClause>(construct<OmpClause::NoParallelism>()) ||
"NUM_TASKS" >> construct<OmpClause>(construct<OmpClause::NumTasks>(
parenthesized(Parser<OmpNumTasksClause>{}))) ||
"NUM_TEAMS" >> construct<OmpClause>(construct<OmpClause::NumTeams>(
@@ -1085,6 +1101,24 @@ TYPE_PARSER(startOmpLine >>
Parser<OpenMPThreadprivate>{})) /
endOmpLine))
+// Assume Construct
+TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
+ verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
+ endOmpLine))
+// Assumes Construct
+TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
+ verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+
+TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
+ verbatim(startOmpLine >> "END ASSUMES"_tok))))
+
+TYPE_PARSER(construct<OpenMPAssumesPartConstruct>(block))
+
+TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
+ maybe("BEGIN"_tok) >> Parser<OmpAssumesDirective>{} / endOmpLine,
+ Parser<OpenMPAssumesPartConstruct>{},
+ Parser<OmpEndAssumesDirective>{} / endOmpLine)))
+
// Block Construct
TYPE_PARSER(construct<OpenMPBlockConstruct>(
Parser<OmpBeginBlockDirective>{} / endOmpLine, block,
@@ -1131,6 +1165,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
+ construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
+ construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
// END OMP Block directives
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 0a6af7435b4a22..a3887cd42cd850 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2077,6 +2077,9 @@ class UnparseVisitor {
void Unparse(const OmpDirectiveNameModifier &x) {
Word(llvm::omp::getOpenMPDirectiveName(x.v));
}
+ void Unparse(const OmpDirectiveNameEntry &x) {
+ Word(llvm::omp::getOpenMPDirectiveName(x.v));
+ }
void Unparse(const OmpIteratorSpecifier &x) {
Walk(std::get<TypeDeclarationStmt>(x.t));
Put(" = ");
@@ -2113,6 +2116,8 @@ class UnparseVisitor {
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<ScalarIntExpr>(x.t));
}
+ void Unparse(const OmpAbsentClause &x) { Walk("", x.v, ","); }
+ void Unparse(const OmpContainsClause &x) { Walk("", x.v, ","); }
void Unparse(const OmpAffinityClause &x) {
using Modifier = OmpAffinityClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
@@ -2590,6 +2595,13 @@ class UnparseVisitor {
Walk(*end);
}
}
+ void Unparse(const OpenMPAssumeConstruct &x) {
+ BeginOpenMP();
+ Word("!$OMP ASSUME");
+ Walk(std::get<OmpClauseList>(x.t), ", ");
+ Put("\n");
+ EndOpenMP();
+ }
void Unparse(const OmpCriticalDirective &x) {
BeginOpenMP();
Word("!$OMP CRITICAL");
@@ -2806,7 +2818,9 @@ class UnparseVisitor {
Put("\n");
EndOpenMP();
}
- void Unparse(const OmpClauseList &x) { Walk(" ", x.v, " "); }
+ void Unparse(const OmpClauseList &x, const char *sep = " ") {
+ Walk(" ", x.v, sep);
+ }
void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
BeginOpenMP();
Word("!$OMP ");
@@ -3065,6 +3079,10 @@ class UnparseVisitor {
return Walk("", list, comma, suffix);
}
+ void Walk(const OmpClauseList &x, const char *sep = " ") {
+ return Walk(" ", x.v, sep);
+ }
+
// Traverse a std::tuple<>, with an optional separator.
template <std::size_t J = 0, typename T>
void WalkTupleElements(const T &tuple, const char *separator) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 414753305a6e37..775b6bcfb76fdc 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1185,6 +1185,23 @@ void OmpStructureChecker::CheckMasterNesting(
}
}
+void OmpStructureChecker::Enter(const parser::OpenMPAssumeConstruct &x) {
+ const auto &dir{std::get<parser::Verbatim>(x.t)};
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_assume);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPAssumeConstruct &) {
+ dirContext_.pop_back();
+}
+
+void OmpStructureChecker::Enter(const parser::OpenMPAssumesConstruct &x) {
+ PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
if (GetDirectiveNest(TargetBlockOnlyTeams)) {
ExitDirectiveNest(TargetBlockOnlyTeams);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 346a7bed9138f0..ffd36e9cd3324c 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -78,6 +78,10 @@ class OmpStructureChecker
void Enter(const parser::OmpEndLoopDirective &);
void Leave(const parser::OmpEndLoopDirective &);
+ void Enter(const parser::OpenMPAssumeConstruct &);
+ void Leave(const parser::OpenMPAssumeConstruct &);
+ void Enter(const parser::OpenMPAssumesConstruct &);
+ void Leave(const parser::OpenMPAssumesConstruct &);
void Enter(const parser::OpenMPBlockConstruct &);
void Leave(const parser::OpenMPBlockConstruct &);
void Leave(const parser::OmpBeginBlockDirective &);
diff --git a/flang/test/Lower/OpenMP/Todo/assume.f90 b/flang/test/Lower/OpenMP/Todo/assume.f90
new file mode 100644
index 00000000000000..6942c7774663ed
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/assume.f90
@@ -0,0 +1,6 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMP ASSUME construct
+program p
+ !$omp assume no_openmp
+end program p
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
new file mode 100644
index 00000000000000..73ad1526e83cc4
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -0,0 +1,9 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMP ASSUMES construct
+program p
+ integer r
+ !$omp assumes no_openmp
+ print *,r
+ !$omp end assumes
+end program p
diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90
new file mode 100644
index 00000000000000..74c10126a76c61
--- /dev/null
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -0,0 +1,66 @@
+! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
+!!! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE"
+
+subroutine sub1
+ integer :: r
+!CHECK: !$OMP ASSUME NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
+ !$omp assume no_openmp
+!CHECK: !$OMP ASSUME NO_PARALLELISM
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoParallelism
+ !$omp assume no_parallelism
+!CHECK: !$OMP ASSUME NO_OPENMP_ROUTINES
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmpRoutines
+ !$omp assume no_openmp_routines
+!CHECK: !$OMP ASSUME ABSENT(ALLOCATE), CONTAINS(WORKSHARE,TASK)
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = allocate
+!PARSE-TREE: OmpClause -> Contains -> OmpContainsClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = workshare
+!PARSE-TREE: OmpDirectiveNameEntry -> llvm::omp::Directive = task
+ !$omp assume absent(allocate), contains(workshare, task)
+!CHECK: !$OMP ASSUME HOLDS(1==1)
+ !$omp assume holds(1.eq.1)
+ print *, r
+end subroutine sub1
+
+subroutine sub2
+ integer :: r
+!CHECK !$OMP ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
+!PARSE-TREE: OmpAssumesDirective
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
+!PARSE-TREE: Expr -> Add
+!PARSE-TREE: OmpEndAssumesDirective
+ !$omp assumes no_openmp
+ r = r + 1
+!CHECK !$OMP END ASSUMES
+ !$omp end assumes
+end subroutine sub2
+
+subroutine sub3
+ integer :: r
+!CHECK !$OMP ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
+!PARSE-TREE: OmpAssumesDirective
+!PARSE-TREE: Verbatim
+!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
+!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
+!PARSE-TREE: Expr -> Add
+!PARSE-TREE: OmpEndAssumesDirective
+ !$omp begin assumes no_openmp
+ r = r + 1
+!CHECK !$OMP END ASSUMES
+ !$omp end assumes
+end subroutine sub3
+
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index e36eb77cefe7e3..01d073d5db09ab 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -34,6 +34,7 @@ def OpenMP : DirectiveLanguage {
def OMPC_Absent : Clause<"absent"> {
let clangClass = "OMPAbsentClause";
+ let flangClass = "OmpAbsentClause";
}
def OMPC_Acquire : Clause<"acquire"> {
let clangClass = "OMPAcquireClause";
@@ -106,6 +107,7 @@ def OMPC_CancellationConstructType : Clause<"cancellation_construct_type"> {
}
def OMPC_Contains : Clause<"contains"> {
let clangClass = "OMPContainsClause";
+ let flangClass = "OmpContainsClause";
}
def OMPC_Capture : Clause<"capture"> {
let clangClass = "OMPCaptureClause";
@@ -224,6 +226,7 @@ def OMPC_Hint : Clause<"hint"> {
}
def OMPC_Holds : Clause<"holds"> {
let clangClass = "OMPHoldsClause";
+ let flangClass = "OmpHoldsClause";
}
def OMPC_If : Clause<"if"> {
let clangClass = "OMPIfClause";
@@ -552,6 +555,14 @@ def OMP_Allocators : Directive<"allocators"> {
def OMP_Assumes : Directive<"assumes"> {
let association = AS_None;
let category = CA_Informational;
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Absent, 51>,
+ VersionedClause<OMPC_Contains, 51>,
+ VersionedClause<OMPC_Holds, 51>,
+ VersionedClause<OMPC_NoOpenMP, 51>,
+ VersionedClause<OMPC_NoOpenMPRoutines, 51>,
+ VersionedClause<OMPC_NoParallelism, 51>,
+ ];
}
def OMP_EndAssumes : Directive<"end assumes"> {
let association = AS_Delimited;
@@ -597,6 +608,14 @@ def OMP_Barrier : Directive<"barrier"> {
def OMP_BeginAssumes : Directive<"begin assumes"> {
let association = AS_Delimited;
let category = CA_Informational;
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Absent, 51>,
+ VersionedClause<OMPC_Contains, 51>,
+ VersionedClause<OMPC_Holds, 51>,
+ VersionedClause<OMPC_NoOpenMP, 51>,
+ VersionedClause<OMPC_NoOpenMPRoutines, 51>,
+ VersionedClause<OMPC_NoParallelism, 51>,
+ ];
}
def OMP_BeginDeclareTarget : Directive<"begin declare target"> {
let allowedClauses = [
>From 3e63e24fe38daf32fd9b94fb4ef9f65e7bddd536 Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Tue, 24 Dec 2024 11:51:20 +0000
Subject: [PATCH 2/2] Review comments
---
flang/include/flang/Parser/dump-parse-tree.h | 4 +-
flang/include/flang/Parser/parse-tree.h | 40 +++++++------
flang/lib/Lower/OpenMP/OpenMP.cpp | 19 ++++--
flang/lib/Parser/openmp-parsers.cpp | 59 +++++++++++--------
flang/lib/Parser/unparse.cpp | 25 +++++++-
flang/lib/Semantics/check-omp-structure.cpp | 8 +++
flang/lib/Semantics/check-omp-structure.h | 2 +
flang/test/Lower/OpenMP/Todo/assumes.f90 | 5 +-
.../test/Lower/OpenMP/Todo/begin-assumes.f90 | 9 +++
flang/test/Parser/OpenMP/assumption.f90 | 35 ++++-------
10 files changed, 125 insertions(+), 81 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/Todo/begin-assumes.f90
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 4c88b9583c25f9..9bf087290464ee 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -557,7 +557,6 @@ class ParseTreeDumper {
NODE(parser, OmpExpectation)
NODE_ENUM(OmpExpectation, Value)
NODE(parser, OmpDirectiveNameModifier)
- NODE(parser, OmpDirectiveNameEntry)
NODE(parser, OmpHoldsClause)
NODE(parser, OmpIfClause)
NODE(OmpIfClause, Modifier)
@@ -653,7 +652,8 @@ class ParseTreeDumper {
NODE(parser, OpenMPAssumeConstruct)
NODE(parser, OpenMPAssumesConstruct)
NODE(parser, OpenMPAssumesPartConstruct)
- NODE(parser, OmpAssumesDirective)
+ NODE(parser, OmpBeginAssumesDirective)
+ NODE(parser, OpenMPBeginAssumesConstruct)
NODE(parser, OmpEndAssumesDirective)
NODE(parser, OpenMPAtomicConstruct)
NODE(parser, OpenMPBlockConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index a89938036d9c3f..8446c71fe06f5e 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3740,10 +3740,7 @@ struct OmpVariableCategory {
// --- Clauses
-struct OmpDirectiveNameEntry {
- WRAPPER_CLASS_BOILERPLATE(OmpDirectiveNameEntry, llvm::omp::Directive);
-};
-using OmpDirectiveList = std::list<OmpDirectiveNameEntry>;
+using OmpDirectiveList = std::list<llvm::omp::Directive>;
// Ref: [5.2:214]
//
@@ -3995,10 +3992,9 @@ struct OmpGrainsizeClause {
// Ref: [5.2: 214]
//
// holds-clause ->
-// HOLDS(expr[, expr])
+// HOLDS(expr)
struct OmpHoldsClause {
- using ExprList = std::list<common::Indirection<Expr>>;
- WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, ExprList);
+ WRAPPER_CLASS_BOILERPLATE(OmpHoldsClause, common::Indirection<Expr>);
};
// Ref: [5.2:72-73], in 4.5-5.1 it's scattered over individual directives
@@ -4230,15 +4226,20 @@ struct OpenMPAssumeConstruct {
CharBlock source;
};
-struct OmpAssumesDirective {
- TUPLE_CLASS_BOILERPLATE(OmpAssumesDirective);
+struct OpenMPAssumesConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
+ std::tuple<Verbatim, OmpClauseList> t;
+ CharBlock source;
+};
+
+struct OmpBeginAssumesDirective {
+ TUPLE_CLASS_BOILERPLATE(OmpBeginAssumesDirective);
std::tuple<Verbatim, OmpClauseList> t;
CharBlock source;
};
struct OmpEndAssumesDirective {
- TUPLE_CLASS_BOILERPLATE(OmpEndAssumesDirective);
- std::tuple<Verbatim> t;
+ WRAPPER_CLASS_BOILERPLATE(OmpEndAssumesDirective, Verbatim);
CharBlock source;
};
@@ -4249,9 +4250,9 @@ struct OpenMPAssumesPartConstruct {
CharBlock source;
};
-struct OpenMPAssumesConstruct {
- TUPLE_CLASS_BOILERPLATE(OpenMPAssumesConstruct);
- std::tuple<OmpAssumesDirective, OpenMPAssumesPartConstruct,
+struct OpenMPBeginAssumesConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPBeginAssumesConstruct);
+ std::tuple<OmpBeginAssumesDirective, OpenMPAssumesPartConstruct,
OmpEndAssumesDirective>
t;
CharBlock source;
@@ -4390,10 +4391,10 @@ struct OpenMPDeclarativeAllocate {
struct OpenMPDeclarativeConstruct {
UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
CharBlock source;
- std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareMapperConstruct,
- OpenMPDeclareReductionConstruct, OpenMPDeclareSimdConstruct,
- OpenMPDeclareTargetConstruct, OpenMPThreadprivate,
- OpenMPRequiresConstruct>
+ std::variant<OpenMPDeclarativeAllocate, OpenMPAssumesConstruct,
+ OpenMPDeclareMapperConstruct, OpenMPDeclareReductionConstruct,
+ OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
+ OpenMPThreadprivate, OpenMPRequiresConstruct>
u;
};
@@ -4663,7 +4664,8 @@ struct OpenMPConstruct {
OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPErrorConstruct,
OpenMPExecutableAllocate, OpenMPAllocatorsConstruct,
- OpenMPAssumeConstruct, OpenMPAssumesConstruct, OpenMPCriticalConstruct>
+ OpenMPAssumeConstruct, OpenMPBeginAssumesConstruct,
+ OpenMPCriticalConstruct>
u;
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index cc3cd95f69d77e..2af896bac5d196 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2601,6 +2601,13 @@ genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
TODO(converter.getCurrentLocation(), "OpenMPDeclarativeAllocate");
}
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ const parser::OpenMPAssumesConstruct &assumesConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMP ASSUMES declaration");
+}
+
static void genOMP(
lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -2902,13 +2909,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
TODO(clauseLocation, "OpenMP ASSUME construct");
}
-static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx,
- lower::pft::Evaluation &eval,
- const parser::OpenMPAssumesConstruct &assumesConstruct) {
+static void
+genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+ const parser::OpenMPBeginAssumesConstruct &beginAssumesConstruct) {
mlir::Location clauseLocation =
- converter.genLocation(assumesConstruct.source);
- TODO(clauseLocation, "OpenMP ASSUMES construct");
+ converter.genLocation(beginAssumesConstruct.source);
+ TODO(clauseLocation, "OpenMP BEGIN ASSUMES construct");
}
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index a9b995bbf5e2bb..40fbddb8e4866a 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -577,11 +577,11 @@ TYPE_PARSER(construct<OmpSeverityClause>(
TYPE_PARSER(construct<OmpMessageClause>(expr))
-TYPE_PARSER(construct<OmpHoldsClause>(many(maybe(","_tok) >> indirect(expr))))
+TYPE_PARSER(construct<OmpHoldsClause>(indirect(expr)))
TYPE_PARSER(construct<OmpAbsentClause>(many(maybe(","_tok) >>
- construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+ construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
TYPE_PARSER(construct<OmpContainsClause>(many(maybe(","_tok) >>
- construct<OmpDirectiveNameEntry>(OmpDirectiveNameParser{}))))
+ construct<llvm::omp::Directive>(OmpDirectiveNameParser{}))))
TYPE_PARSER("ABSENT" >> construct<OmpClause>(construct<OmpClause::Absent>(
parenthesized(Parser<OmpAbsentClause>{}))) ||
@@ -1082,40 +1082,46 @@ TYPE_PARSER(
parenthesized(Parser<OmpObjectList>{}), Parser<OmpClauseList>{})) /
lookAhead(endOmpLine / !statement(allocateStmt)))
+// Assumes Construct
+TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
+ verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+
// Declarative constructs
-TYPE_PARSER(startOmpLine >>
- withMessage("expected OpenMP construct"_err_en_US,
- sourced(construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPDeclareReductionConstruct>{}) ||
- construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPDeclareMapperConstruct>{}) ||
- construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPDeclareSimdConstruct>{}) ||
- construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPDeclareTargetConstruct>{}) ||
- construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPDeclarativeAllocate>{}) ||
- construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPRequiresConstruct>{}) ||
- construct<OpenMPDeclarativeConstruct>(
- Parser<OpenMPThreadprivate>{})) /
- endOmpLine))
+TYPE_PARSER(
+ startOmpLine >> withMessage("expected OpenMP construct"_err_en_US,
+ sourced(construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPAssumesConstruct>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareReductionConstruct>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareMapperConstruct>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareSimdConstruct>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclareTargetConstruct>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPDeclarativeAllocate>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPRequiresConstruct>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPThreadprivate>{})) /
+ endOmpLine))
// Assume Construct
TYPE_PARSER(sourced(construct<OpenMPAssumeConstruct>(
verbatim("ASSUME"_tok), Parser<OmpClauseList>{}) /
endOmpLine))
-// Assumes Construct
-TYPE_PARSER(sourced(construct<OmpAssumesDirective>(
- verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
+
+TYPE_PARSER(sourced(construct<OmpBeginAssumesDirective>(
+ "BEGIN"_tok >> verbatim("ASSUMES"_tok), Parser<OmpClauseList>{})))
TYPE_PARSER(sourced(construct<OmpEndAssumesDirective>(
verbatim(startOmpLine >> "END ASSUMES"_tok))))
TYPE_PARSER(construct<OpenMPAssumesPartConstruct>(block))
-TYPE_PARSER(sourced(construct<OpenMPAssumesConstruct>(
- maybe("BEGIN"_tok) >> Parser<OmpAssumesDirective>{} / endOmpLine,
+TYPE_PARSER(sourced(construct<OpenMPBeginAssumesConstruct>(
+ Parser<OmpBeginAssumesDirective>{} / endOmpLine,
Parser<OpenMPAssumesPartConstruct>{},
Parser<OmpEndAssumesDirective>{} / endOmpLine)))
@@ -1165,7 +1171,8 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
- construct<OpenMPConstruct>(Parser<OpenMPAssumesConstruct>{}),
+ construct<OpenMPConstruct>(
+ Parser<OpenMPBeginAssumesConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index a3887cd42cd850..42d9de399af7d1 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2074,10 +2074,10 @@ class UnparseVisitor {
},
x.u);
}
- void Unparse(const OmpDirectiveNameModifier &x) {
- Word(llvm::omp::getOpenMPDirectiveName(x.v));
+ void Unparse(const llvm::omp::Directive &x) {
+ Word(llvm::omp::getOpenMPDirectiveName(x));
}
- void Unparse(const OmpDirectiveNameEntry &x) {
+ void Unparse(const OmpDirectiveNameModifier &x) {
Word(llvm::omp::getOpenMPDirectiveName(x.v));
}
void Unparse(const OmpIteratorSpecifier &x) {
@@ -2602,6 +2602,18 @@ class UnparseVisitor {
Put("\n");
EndOpenMP();
}
+ void Unparse(const OmpBeginAssumesDirective &x) {
+ BeginOpenMP();
+ Word("!$OMP BEGIN ASSUMES");
+ Walk(std::get<OmpClauseList>(x.t), ", ");
+ Put("\n");
+ EndOpenMP();
+ }
+ void Unparse(const OmpEndAssumesDirective &x) {
+ BeginOpenMP();
+ Word("!$OMP END ASSUMES\n");
+ EndOpenMP();
+ }
void Unparse(const OmpCriticalDirective &x) {
BeginOpenMP();
Word("!$OMP CRITICAL");
@@ -2655,6 +2667,13 @@ class UnparseVisitor {
Word("!$OMP ");
return common::visit(
common::visitors{
+ [&](const OpenMPAssumesConstruct &z) {
+ Word("ASSUMES ");
+ Walk(std::get<OmpClauseList>(z.t));
+ Put("\n");
+ EndOpenMP();
+ return false;
+ },
[&](const OpenMPDeclarativeAllocate &z) {
Word("ALLOCATE (");
Walk(std::get<OmpObjectList>(z.t));
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 775b6bcfb76fdc..d6ee862ec2cc4e 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1202,6 +1202,14 @@ void OmpStructureChecker::Leave(const parser::OpenMPAssumesConstruct &) {
dirContext_.pop_back();
}
+void OmpStructureChecker::Enter(const parser::OpenMPBeginAssumesConstruct &x) {
+ PushContextAndClauseSets(x.source, llvm::omp::Directive::OMPD_assumes);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPBeginAssumesConstruct &) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) {
if (GetDirectiveNest(TargetBlockOnlyTeams)) {
ExitDirectiveNest(TargetBlockOnlyTeams);
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index ffd36e9cd3324c..87675800d5f5bb 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -82,6 +82,8 @@ class OmpStructureChecker
void Leave(const parser::OpenMPAssumeConstruct &);
void Enter(const parser::OpenMPAssumesConstruct &);
void Leave(const parser::OpenMPAssumesConstruct &);
+ void Enter(const parser::OpenMPBeginAssumesConstruct &);
+ void Leave(const parser::OpenMPBeginAssumesConstruct &);
void Enter(const parser::OpenMPBlockConstruct &);
void Leave(const parser::OpenMPBlockConstruct &);
void Leave(const parser::OmpBeginBlockDirective &);
diff --git a/flang/test/Lower/OpenMP/Todo/assumes.f90 b/flang/test/Lower/OpenMP/Todo/assumes.f90
index 73ad1526e83cc4..3ef4bd857612fd 100644
--- a/flang/test/Lower/OpenMP/Todo/assumes.f90
+++ b/flang/test/Lower/OpenMP/Todo/assumes.f90
@@ -1,9 +1,8 @@
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
-! CHECK: not yet implemented: OpenMP ASSUMES construct
+! CHECK: not yet implemented: OpenMP ASSUMES declaration
program p
+!$omp assumes no_openmp
integer r
- !$omp assumes no_openmp
print *,r
- !$omp end assumes
end program p
diff --git a/flang/test/Lower/OpenMP/Todo/begin-assumes.f90 b/flang/test/Lower/OpenMP/Todo/begin-assumes.f90
new file mode 100644
index 00000000000000..5aad8be417a35b
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/begin-assumes.f90
@@ -0,0 +1,9 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMP BEGIN ASSUMES construct
+program p
+ integer r
+!$omp begin assumes no_parallelism
+ print *,r
+!$omp end assumes
+end program p
diff --git a/flang/test/Parser/OpenMP/assumption.f90 b/flang/test/Parser/OpenMP/assumption.f90
index 74c10126a76c61..80c15cbf6c3109 100644
--- a/flang/test/Parser/OpenMP/assumption.f90
+++ b/flang/test/Parser/OpenMP/assumption.f90
@@ -1,6 +1,5 @@
! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
!!! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE"
-
subroutine sub1
integer :: r
!CHECK: !$OMP ASSUME NO_OPENMP
@@ -21,9 +20,9 @@ subroutine sub1
!CHECK: !$OMP ASSUME ABSENT(ALLOCATE), CONTAINS(WORKSHARE,TASK)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumeConstruct
!PARSE-TREE: Verbatim
-!PARSE-TREE: OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = allocate
-!PARSE-TREE: OmpClause -> Contains -> OmpContainsClause -> OmpDirectiveNameEntry -> llvm::omp::Directive = workshare
-!PARSE-TREE: OmpDirectiveNameEntry -> llvm::omp::Directive = task
+!PARSE-TREE: OmpClauseList -> OmpClause -> Absent -> OmpAbsentClause -> llvm::omp::Directive = allocate
+!PARSE-TREE: OmpClause -> Contains -> OmpContainsClause -> llvm::omp::Directive = workshare
+!PARSE-TREE: llvm::omp::Directive = task
!$omp assume absent(allocate), contains(workshare, task)
!CHECK: !$OMP ASSUME HOLDS(1==1)
!$omp assume holds(1.eq.1)
@@ -32,35 +31,27 @@ end subroutine sub1
subroutine sub2
integer :: r
-!CHECK !$OMP ASSUMES NO_OPENMP
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
-!PARSE-TREE: OmpAssumesDirective
+!CHECK !$OMP BEGIN ASSUMES NO_OPENMP
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBeginAssumesConstruct
+!PARSE-TREE: OmpBeginAssumesDirective
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
!PARSE-TREE: Expr -> Add
!PARSE-TREE: OmpEndAssumesDirective
- !$omp assumes no_openmp
+ !$omp begin assumes no_openmp
r = r + 1
!CHECK !$OMP END ASSUMES
!$omp end assumes
end subroutine sub2
-
-subroutine sub3
- integer :: r
+
+program p
!CHECK !$OMP ASSUMES NO_OPENMP
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAssumesConstruct
-!PARSE-TREE: OmpAssumesDirective
+!PARSE-TREE: SpecificationPart
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPAssumesConstruct
!PARSE-TREE: Verbatim
!PARSE-TREE: OmpClauseList -> OmpClause -> NoOpenmp
-!PARSE-TREE: OpenMPAssumesPartConstruct -> Block
-!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt
-!PARSE-TREE: Expr -> Add
-!PARSE-TREE: OmpEndAssumesDirective
- !$omp begin assumes no_openmp
- r = r + 1
-!CHECK !$OMP END ASSUMES
- !$omp end assumes
-end subroutine sub3
+ !$omp assumes no_openmp
+end program p
More information about the flang-commits
mailing list