[flang-commits] [flang] d5fb596 - [flang][OpenMP] Add parser support for Requires directive
Sergio Afonso via flang-commits
flang-commits at lists.llvm.org
Thu Nov 10 03:40:22 PST 2022
Author: Sergio Afonso
Date: 2022-11-10T05:38:31-06:00
New Revision: d5fb5960d0df23509a501cfa5a133927bb266d4d
URL: https://github.com/llvm/llvm-project/commit/d5fb5960d0df23509a501cfa5a133927bb266d4d
DIFF: https://github.com/llvm/llvm-project/commit/d5fb5960d0df23509a501cfa5a133927bb266d4d.diff
LOG: [flang][OpenMP] Add parser support for Requires directive
OpenMP 5.0 adds support for the "requires" directive. This patch adds parser support for it in flang.
Differential revision: https://reviews.llvm.org/D136867
Added:
Modified:
flang/docs/OpenMP-semantics.md
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Lower/OpenMP.cpp
flang/lib/Parser/openmp-parsers.cpp
flang/lib/Parser/unparse.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-omp-structure.h
flang/lib/Semantics/resolve-directives.cpp
flang/test/Semantics/OpenMP/omp-declarative-directive.f90
llvm/include/llvm/Frontend/OpenMP/OMP.td
Removed:
################################################################################
diff --git a/flang/docs/OpenMP-semantics.md b/flang/docs/OpenMP-semantics.md
index 1511bc9e7b3b5..46dc189456f99 100644
--- a/flang/docs/OpenMP-semantics.md
+++ b/flang/docs/OpenMP-semantics.md
@@ -48,6 +48,7 @@ List of existing ones:
* declare target
* threadprivate
* declare reduction
+* requires
There is a parser node for each of these directives and
the parser node saves information associated with the directive,
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 2d9cfaf91f93f..66ab5dd6d0237 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -562,9 +562,12 @@ class ParseTreeDumper {
NODE(parser, OmpMemoryOrderClause)
NODE(parser, OmpAtomicClause)
NODE(parser, OmpAtomicClauseList)
+ NODE(parser, OmpAtomicDefaultMemOrderClause)
+ NODE_ENUM(OmpAtomicDefaultMemOrderClause, Type)
NODE(parser, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)
+ NODE(parser, OpenMPRequiresConstruct)
NODE(parser, OpenMPSimpleStandaloneConstruct)
NODE(parser, OpenMPStandaloneConstruct)
NODE(parser, OpenMPSectionConstruct)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 16987fb9660a3..39156c63c7cfe 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3494,6 +3494,14 @@ struct OmpDependClause {
std::variant<Source, Sink, InOut> u;
};
+// OMP 5.0 2.4 atomic-default-mem-order-clause ->
+// ATOMIC_DEFAULT_MEM_ORDER (SEQ_CST | ACQ_REL |
+// RELAXED)
+struct OmpAtomicDefaultMemOrderClause {
+ ENUM_CLASS(Type, SeqCst, AcqRel, Relaxed)
+ WRAPPER_CLASS_BOILERPLATE(OmpAtomicDefaultMemOrderClause, Type);
+};
+
// OpenMP Clauses
struct OmpClause {
UNION_CLASS_BOILERPLATE(OmpClause);
@@ -3611,6 +3619,13 @@ struct OpenMPDeclareSimdConstruct {
std::tuple<Verbatim, std::optional<Name>, OmpClauseList> t;
};
+// 2.4 requires -> REQUIRES requires-clause[ [ [,] requires-clause]...]
+struct OpenMPRequiresConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPRequiresConstruct);
+ CharBlock source;
+ std::tuple<Verbatim, OmpClauseList> t;
+};
+
// 2.15.2 threadprivate -> THREADPRIVATE (variable-name-list)
struct OpenMPThreadprivate {
TUPLE_CLASS_BOILERPLATE(OpenMPThreadprivate);
@@ -3630,7 +3645,7 @@ struct OpenMPDeclarativeConstruct {
CharBlock source;
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclareReductionConstruct,
OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
- OpenMPThreadprivate>
+ OpenMPThreadprivate, OpenMPRequiresConstruct>
u;
};
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 4d47b95e00eed..d487fdf29b9fc 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -1815,6 +1815,10 @@ void Fortran::lower::genOpenMPDeclarativeConstruct(
TODO(converter.getCurrentLocation(),
"OpenMPDeclareTargetConstruct");
},
+ [&](const Fortran::parser::OpenMPRequiresConstruct
+ &requiresConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMPRequiresConstruct");
+ },
[&](const Fortran::parser::OpenMPThreadprivate &threadprivate) {
// The directive is lowered when instantiating the variable to
// support the case of threadprivate variable declared in module.
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 9f2e152236089..0e9f742954218 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -191,6 +191,9 @@ TYPE_PARSER(
parenthesized(Parser<OmpAllocateClause>{}))) ||
"ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>(
parenthesized(scalarIntExpr))) ||
+ "ATOMIC_DEFAULT_MEM_ORDER" >>
+ construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
+ parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
"COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
parenthesized(scalarIntConstantExpr))) ||
"COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
@@ -208,6 +211,8 @@ TYPE_PARSER(
"DIST_SCHEDULE" >>
construct<OmpClause>(construct<OmpClause::DistSchedule>(
parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) ||
+ "DYNAMIC_ALLOCATORS" >>
+ construct<OmpClause>(construct<OmpClause::DynamicAllocators>()) ||
"FINAL" >> construct<OmpClause>(construct<OmpClause::Final>(
parenthesized(scalarLogicalExpr))) ||
"FIRSTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Firstprivate>(
@@ -261,6 +266,8 @@ TYPE_PARSER(
parenthesized(Parser<OmpReductionClause>{}))) ||
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>()) ||
"RELEASE" >> construct<OmpClause>(construct<OmpClause::Release>()) ||
+ "REVERSE_OFFLOAD" >>
+ construct<OmpClause>(construct<OmpClause::ReverseOffload>()) ||
"SAFELEN" >> construct<OmpClause>(construct<OmpClause::Safelen>(
parenthesized(scalarIntConstantExpr))) ||
"SCHEDULE" >> construct<OmpClause>(construct<OmpClause::Schedule>(
@@ -278,6 +285,10 @@ TYPE_PARSER(
parenthesized(Parser<OmpObjectList>{}))) ||
"USE_DEVICE_PTR" >> construct<OmpClause>(construct<OmpClause::UseDevicePtr>(
parenthesized(nonemptyList(name)))) ||
+ "UNIFIED_ADDRESS" >>
+ construct<OmpClause>(construct<OmpClause::UnifiedAddress>()) ||
+ "UNIFIED_SHARED_MEMORY" >>
+ construct<OmpClause>(construct<OmpClause::UnifiedSharedMemory>()) ||
"UNIFORM" >> construct<OmpClause>(construct<OmpClause::Uniform>(
parenthesized(nonemptyList(name)))) ||
"UNTIED" >> construct<OmpClause>(construct<OmpClause::Untied>()))
@@ -357,6 +368,16 @@ TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>(
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
"RELAXED" >> construct<OmpClause>(construct<OmpClause::Relaxed>())))))
+// 2.4 Requires construct [OpenMP 5.0]
+// atomic-default-mem-order-clause ->
+// seq_cst
+// acq_rel
+// relaxed
+TYPE_PARSER(construct<OmpAtomicDefaultMemOrderClause>(
+ "SEQ_CST" >> pure(OmpAtomicDefaultMemOrderClause::Type::SeqCst) ||
+ "ACQ_REL" >> pure(OmpAtomicDefaultMemOrderClause::Type::AcqRel) ||
+ "RELAXED" >> pure(OmpAtomicDefaultMemOrderClause::Type::Relaxed)))
+
// 2.17.7 Atomic construct
// atomic-clause -> memory-order-clause | HINT(hint-expression)
TYPE_PARSER(sourced(construct<OmpAtomicClause>(
@@ -519,6 +540,10 @@ TYPE_PARSER(
sourced(construct<OpenMPDeclareSimdConstruct>(verbatim("DECLARE SIMD"_tok),
maybe(parenthesized(name)), Parser<OmpClauseList>{})))
+// 2.4 Requires construct
+TYPE_PARSER(sourced(construct<OpenMPRequiresConstruct>(
+ verbatim("REQUIRES"_tok), some(Parser<OmpClause>{} / maybe(","_tok)))))
+
// 2.15.2 Threadprivate directive
TYPE_PARSER(sourced(construct<OpenMPThreadprivate>(
verbatim("THREADPRIVATE"_tok), parenthesized(Parser<OmpObjectList>{}))))
@@ -539,6 +564,8 @@ TYPE_PARSER(startOmpLine >>
Parser<OpenMPDeclareTargetConstruct>{}) ||
construct<OpenMPDeclarativeConstruct>(
Parser<OpenMPDeclarativeAllocate>{}) ||
+ construct<OpenMPDeclarativeConstruct>(
+ Parser<OpenMPRequiresConstruct>{}) ||
construct<OpenMPDeclarativeConstruct>(Parser<OpenMPThreadprivate>{})) /
endOmpLine)
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 534738d19b1d8..9c7990845350f 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2229,6 +2229,21 @@ class UnparseVisitor {
break;
}
}
+
+ void Unparse(const OmpAtomicDefaultMemOrderClause &x) {
+ switch (x.v) {
+ case OmpAtomicDefaultMemOrderClause::Type::SeqCst:
+ Word("SEQ_CST");
+ break;
+ case OmpAtomicDefaultMemOrderClause::Type::AcqRel:
+ Word("ACQ_REL");
+ break;
+ case OmpAtomicDefaultMemOrderClause::Type::Relaxed:
+ Word("RELAXED");
+ break;
+ }
+ }
+
void Unparse(const OmpAtomicClauseList &x) { Walk(" ", x.v, " "); }
void Unparse(const OmpAtomic &x) {
@@ -2393,6 +2408,13 @@ class UnparseVisitor {
Word("DECLARE TARGET ");
return true;
},
+ [&](const OpenMPRequiresConstruct &y) {
+ Word("REQUIRES ");
+ Walk(std::get<OmpClauseList>(y.t));
+ Put("\n");
+ EndOpenMP();
+ return false;
+ },
[&](const OpenMPThreadprivate &) {
Word("THREADPRIVATE (");
return true;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index bb983564acb54..0c11a97c3e8e1 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1060,6 +1060,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareSimdConstruct &) {
dirContext_.pop_back();
}
+void OmpStructureChecker::Enter(const parser::OpenMPRequiresConstruct &x) {
+ const auto &dir{std::get<parser::Verbatim>(x.t)};
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_requires);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
isPredefinedAllocator = true;
const auto &dir{std::get<parser::Verbatim>(x.t)};
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 0ff0b90bbe690..2751cdd6fbe98 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -152,6 +152,8 @@ class OmpStructureChecker
void Leave(const parser::OpenMPDeclareTargetConstruct &);
void Enter(const parser::OpenMPExecutableAllocate &);
void Leave(const parser::OpenMPExecutableAllocate &);
+ void Enter(const parser::OpenMPRequiresConstruct &);
+ void Leave(const parser::OpenMPRequiresConstruct &);
void Enter(const parser::OpenMPThreadprivate &);
void Leave(const parser::OpenMPThreadprivate &);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 16eacc5dff0a4..82623acf13c6c 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -323,6 +323,13 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
return true;
}
void Post(const parser::OpenMPDeclareSimdConstruct &) { PopContext(); }
+
+ bool Pre(const parser::OpenMPRequiresConstruct &x) {
+ PushContext(x.source, llvm::omp::Directive::OMPD_requires);
+ return true;
+ }
+ void Post(const parser::OpenMPRequiresConstruct &) { PopContext(); }
+
bool Pre(const parser::OpenMPThreadprivate &);
void Post(const parser::OpenMPThreadprivate &) { PopContext(); }
diff --git a/flang/test/Semantics/OpenMP/omp-declarative-directive.f90 b/flang/test/Semantics/OpenMP/omp-declarative-directive.f90
index 23ed8d5e0b555..e48a682288583 100644
--- a/flang/test/Semantics/OpenMP/omp-declarative-directive.f90
+++ b/flang/test/Semantics/OpenMP/omp-declarative-directive.f90
@@ -5,6 +5,20 @@
!TODO: all internal errors
! enable declare-reduction example after name resolution
+! 2.4 requires
+
+subroutine requires_1(a)
+ real(8), intent(inout) :: a
+ !$omp requires reverse_offload, unified_shared_memory, atomic_default_mem_order(relaxed)
+ a = a + 0.01
+end subroutine requires_1
+
+subroutine requires_2(a)
+ real(8), intent(inout) :: a
+ !$omp requires unified_address
+ a = a + 0.01
+end subroutine requires_2
+
! 2.8.2 declare-simd
subroutine declare_simd_1(a, b)
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 6de8a3ea93f1e..4e1865a99beda 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -299,6 +299,7 @@ def OMPC_DynamicAllocators : Clause<"dynamic_allocators"> {
}
def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
let clangClass = "OMPAtomicDefaultMemOrderClause";
+ let flangClass = "OmpAtomicDefaultMemOrderClause";
}
def OMPC_Allocate : Clause<"allocate"> {
let clangClass = "OMPAllocateClause";
@@ -614,7 +615,7 @@ def OMP_Cancel : Directive<"cancel"> {
];
}
def OMP_Requires : Directive<"requires"> {
- let allowedClauses = [
+ let allowedOnceClauses = [
VersionedClause<OMPC_UnifiedAddress>,
VersionedClause<OMPC_UnifiedSharedMemory>,
// OpenMP 5.2 Spec: If an implementation is not supporting a requirement
More information about the flang-commits
mailing list