[flang-commits] [flang] [llvm] [flang][OpenMP]Add support for OpenMP ERROR directive (PR #119582)
Mats Petersson via flang-commits
flang-commits at lists.llvm.org
Thu Dec 12 04:54:49 PST 2024
https://github.com/Leporacanthicus updated https://github.com/llvm/llvm-project/pull/119582
>From 744b13155581654f7caf72c8bfabbedd38ff27db Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Fri, 6 Dec 2024 17:37:35 +0000
Subject: [PATCH 1/2] [flang][OpenMP]Add support for OpenMP ERROR directive
Lowering leads to a TODO, with a test to confirm.
Also testing unparse.
---
flang/include/flang/Parser/dump-parse-tree.h | 6 ++++
flang/include/flang/Parser/parse-tree.h | 32 +++++++++++++++++++-
flang/lib/Lower/OpenMP/OpenMP.cpp | 7 +++++
flang/lib/Parser/openmp-parsers.cpp | 20 ++++++++++++
flang/lib/Parser/unparse.cpp | 13 ++++++++
flang/lib/Semantics/check-omp-structure.cpp | 9 ++++++
flang/lib/Semantics/check-omp-structure.h | 2 ++
flang/test/Lower/OpenMP/Todo/error.f90 | 7 +++++
flang/test/Parser/OpenMP/error-unparse.f90 | 5 +++
llvm/include/llvm/Frontend/OpenMP/OMP.td | 3 ++
10 files changed, 103 insertions(+), 1 deletion(-)
create mode 100644 flang/test/Lower/OpenMP/Todo/error.f90
create mode 100644 flang/test/Parser/OpenMP/error-unparse.f90
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index c6f35a07d81ea5..f535f67767ae70 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -488,6 +488,9 @@ class ParseTreeDumper {
NODE(parser, OmpAlignment)
NODE(parser, OmpAlignedClause)
NODE(OmpAlignedClause, Modifier)
+ NODE(parser, OmpAtClause)
+ NODE(OmpAtClause, ActionTime)
+ NODE(OmpSeverityClause, Severity)
NODE(parser, OmpAtomic)
NODE(parser, OmpAtomicCapture)
NODE(OmpAtomicCapture, Stmt1)
@@ -564,6 +567,7 @@ class ParseTreeDumper {
NODE_ENUM(OmpLinearModifier, Value)
NODE(parser, OmpLoopDirective)
NODE(parser, OmpMapClause)
+ NODE(parser, OmpMessageClause)
NODE(OmpMapClause, Modifier)
static std::string GetNodeName(const llvm::omp::Clause &x) {
return llvm::Twine(
@@ -604,6 +608,7 @@ class ParseTreeDumper {
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
+ NODE(parser, OmpSeverityClause)
NODE(parser, OmpDeviceClause)
NODE(OmpDeviceClause, Modifier)
NODE(parser, OmpDeviceModifier)
@@ -652,6 +657,7 @@ class ParseTreeDumper {
NODE(parser, OmpAtomicDefaultMemOrderClause)
NODE_ENUM(common, OmpAtomicDefaultMemOrderType)
NODE(parser, OpenMPDepobjConstruct)
+ NODE(parser, OpenMPErrorConstruct)
NODE(parser, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 8160b095f06dd9..0001afc3a0efc2 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3761,6 +3761,13 @@ struct OmpAllocateClause {
std::tuple<MODIFIERS(), OmpObjectList> t;
};
+// Ref: [5.2:216-217 (sort of, as it's only mentioned in passing)
+// AT(compilation|execution)
+struct OmpAtClause {
+ ENUM_CLASS(ActionTime, Compilation, Execution);
+ WRAPPER_CLASS_BOILERPLATE(OmpAtClause, ActionTime);
+};
+
// Ref: [5.0:60-63], [5.1:83-86], [5.2:210-213]
//
// atomic-default-mem-order-clause ->
@@ -4008,6 +4015,13 @@ struct OmpMapClause {
std::tuple<MODIFIERS(), OmpObjectList, bool> t;
};
+// Ref: [5.2:217-218]
+// message-clause ->
+// MESSAGE("message-text")
+struct OmpMessageClause {
+ WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, std::string);
+};
+
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
//
// num-tasks-clause ->
@@ -4070,6 +4084,14 @@ struct OmpScheduleClause {
std::tuple<MODIFIERS(), Kind, std::optional<ScalarIntExpr>> t;
};
+// REF: [5.2:217]
+// severity-clause ->
+// SEVERITY(warning|fatal)
+struct OmpSeverityClause {
+ ENUM_CLASS(Severity, Fatal, Warning);
+ WRAPPER_CLASS_BOILERPLATE(OmpSeverityClause, Severity);
+};
+
// Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168]
//
// to-clause (in DECLARE TARGET) ->
@@ -4445,6 +4467,14 @@ struct OpenMPDepobjConstruct {
std::tuple<Verbatim, OmpObject, OmpClause> t;
};
+// Ref: OpenMP [5.2:216-218]
+// ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str)
+struct OpenMPErrorConstruct {
+ TUPLE_CLASS_BOILERPLATE(OpenMPErrorConstruct);
+ CharBlock source;
+ std::tuple<Verbatim, OmpClauseList> t;
+};
+
// 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)]
struct OpenMPFlushConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct);
@@ -4517,7 +4547,7 @@ struct OpenMPConstruct {
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,
OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
- OpenMPAtomicConstruct, OpenMPDeclarativeAllocate,
+ OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPErrorConstruct,
OpenMPExecutableAllocate, OpenMPAllocatorsConstruct,
OpenMPCriticalConstruct>
u;
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index cd30bbb89ce470..c1bfd8900cf1c0 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2905,6 +2905,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue.begin(), name);
}
+static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval,
+ const parser::OpenMPErrorConstruct &) {
+ TODO(converter.getCurrentLocation(), "OpenMPErrorConstruct");
+}
+
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 86d475c1a15422..0a102db09d6320 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -507,6 +507,16 @@ TYPE_PARSER(construct<OmpBindClause>(
"TEAMS" >> pure(OmpBindClause::Binding::Teams) ||
"THREAD" >> pure(OmpBindClause::Binding::Thread)))
+TYPE_PARSER(construct<OmpAtClause>(
+ "EXECUTION" >> pure(OmpAtClause::ActionTime::Execution) ||
+ "COMPILATION" >> pure(OmpAtClause::ActionTime::Compilation)))
+
+TYPE_PARSER(construct<OmpSeverityClause>(
+ "FATAL" >> pure(OmpSeverityClause::Severity::Fatal) ||
+ "WARNING" >> pure(OmpSeverityClause::Severity::Warning)))
+
+TYPE_PARSER(construct<OmpMessageClause>(charLiteralConstantWithoutKind))
+
TYPE_PARSER(
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
@@ -518,6 +528,8 @@ TYPE_PARSER(
parenthesized(Parser<OmpAllocateClause>{}))) ||
"ALLOCATOR" >> construct<OmpClause>(construct<OmpClause::Allocator>(
parenthesized(scalarIntExpr))) ||
+ "AT" >> construct<OmpClause>(construct<OmpClause::At>(
+ parenthesized(Parser<OmpAtClause>{}))) ||
"ATOMIC_DEFAULT_MEM_ORDER" >>
construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
@@ -585,6 +597,8 @@ TYPE_PARSER(
"MAP" >> construct<OmpClause>(construct<OmpClause::Map>(
parenthesized(Parser<OmpMapClause>{}))) ||
"MERGEABLE" >> construct<OmpClause>(construct<OmpClause::Mergeable>()) ||
+ "MESSAGE" >> construct<OmpClause>(construct<OmpClause::Message>(
+ parenthesized(Parser<OmpMessageClause>{}))) ||
"NOGROUP" >> construct<OmpClause>(construct<OmpClause::Nogroup>()) ||
"NONTEMPORAL" >> construct<OmpClause>(construct<OmpClause::Nontemporal>(
parenthesized(nonemptyList(name)))) ||
@@ -627,6 +641,8 @@ TYPE_PARSER(
"SCHEDULE" >> construct<OmpClause>(construct<OmpClause::Schedule>(
parenthesized(Parser<OmpScheduleClause>{}))) ||
"SEQ_CST" >> construct<OmpClause>(construct<OmpClause::SeqCst>()) ||
+ "SEVERITY" >> construct<OmpClause>(construct<OmpClause::Severity>(
+ parenthesized(Parser<OmpSeverityClause>{}))) ||
"SHARED" >> construct<OmpClause>(construct<OmpClause::Shared>(
parenthesized(Parser<OmpObjectList>{}))) ||
"SIMD"_id >> construct<OmpClause>(construct<OmpClause::Simd>()) ||
@@ -946,6 +962,9 @@ TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok),
TYPE_PARSER(construct<OpenMPCriticalConstruct>(
Parser<OmpCriticalDirective>{}, block, Parser<OmpEndCriticalDirective>{}))
+TYPE_PARSER(sourced(construct<OpenMPErrorConstruct>(
+ verbatim("ERROR"_tok), Parser<OmpClauseList>{})))
+
// 2.11.3 Executable Allocate directive
TYPE_PARSER(
sourced(construct<OpenMPExecutableAllocate>(verbatim("ALLOCATE"_tok),
@@ -1043,6 +1062,7 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
// OpenMPStandaloneConstruct to resolve !$OMP ORDERED
construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}),
+ construct<OpenMPConstruct>(Parser<OpenMPErrorConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 4782cc1f2d7d7d..5847d690db744a 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2651,6 +2651,17 @@ class UnparseVisitor {
Put(")\n");
EndOpenMP();
}
+ bool Pre(const OmpMessageClause &x) {
+ Word("\"");
+ Walk(x.v);
+ Put("\"");
+ return false;
+ }
+ void Unparse(const OpenMPErrorConstruct &x) {
+ Word("!$OMP ERROR ");
+ Walk(x.t);
+ Put("\n");
+ }
void Unparse(const OmpSectionsDirective &x) {
switch (x.v) {
case llvm::omp::Directive::OMPD_sections:
@@ -2835,6 +2846,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(InquireSpec::LogVar, Kind)
WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506
WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410
+ WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at
WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind
WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind
WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default
@@ -2846,6 +2858,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier
WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type
WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind
+ WALK_NESTED_ENUM(OmpSeverityClause, Severity) // OMP severity
WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier
WALK_NESTED_ENUM(
OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 27e2b946732abc..09c7b5e1e85d07 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1662,6 +1662,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
dirContext_.pop_back();
}
+void OmpStructureChecker::Enter(const parser::OpenMPErrorConstruct &x) {
+ const auto &dir{std::get<parser::Verbatim>(x.t)};
+ PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_error);
+}
+
+void OmpStructureChecker::Leave(const parser::OpenMPErrorConstruct &x) {
+ dirContext_.pop_back();
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &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 1411a9271d4665..76eb605a53f08c 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -102,6 +102,8 @@ class OmpStructureChecker
void Enter(const parser::OmpDeclareTargetWithList &);
void Enter(const parser::OmpDeclareTargetWithClause &);
void Leave(const parser::OmpDeclareTargetWithClause &);
+ void Enter(const parser::OpenMPErrorConstruct &);
+ void Leave(const parser::OpenMPErrorConstruct &);
void Enter(const parser::OpenMPExecutableAllocate &);
void Leave(const parser::OpenMPExecutableAllocate &);
void Enter(const parser::OpenMPAllocatorsConstruct &);
diff --git a/flang/test/Lower/OpenMP/Todo/error.f90 b/flang/test/Lower/OpenMP/Todo/error.f90
new file mode 100644
index 00000000000000..b97e2c20a0cdfd
--- /dev/null
+++ b/flang/test/Lower/OpenMP/Todo/error.f90
@@ -0,0 +1,7 @@
+! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
+
+! CHECK: not yet implemented: OpenMPErrorConstruct
+program p
+ integer, allocatable :: x
+ !$omp error at(compilation) severity(warning) message("an error")
+end program p
diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90
new file mode 100644
index 00000000000000..e6e8d9aad27316
--- /dev/null
+++ b/flang/test/Parser/OpenMP/error-unparse.f90
@@ -0,0 +1,5 @@
+! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
+program main
+ !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here")
+ !$omp error at(compilation) severity(warning) message("some message here")
+end program main
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index bd7fb2361aaeb1..96280322cf8e3b 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -66,6 +66,7 @@ def OMPC_AppendArgs : Clause<"append_args"> {
}
def OMPC_At : Clause<"at"> {
let clangClass = "OMPAtClause";
+ let flangClass = "OmpAtClause";
}
def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
let clangClass = "OMPAtomicDefaultMemOrderClause";
@@ -287,6 +288,7 @@ def OMPC_Mergeable : Clause<"mergeable"> {
}
def OMPC_Message : Clause<"message"> {
let clangClass = "OMPMessageClause";
+ let flangClass = "OmpMessageClause";
}
def OMPC_NoOpenMP : Clause<"no_openmp"> {
let clangClass = "OMPNoOpenMPClause";
@@ -444,6 +446,7 @@ def OMPC_SeqCst : Clause<"seq_cst"> {
}
def OMPC_Severity : Clause<"severity"> {
let clangClass = "OMPSeverityClause";
+ let flangClass = "OmpSeverityClause";
}
def OMPC_Shared : Clause<"shared"> {
let clangClass = "OMPSharedClause";
>From 0dd8e14e499a22e0f5c5a39bb6182702c49ee9db Mon Sep 17 00:00:00 2001
From: Mats Petersson <mats.petersson at arm.com>
Date: Thu, 12 Dec 2024 12:54:02 +0000
Subject: [PATCH 2/2] Allow any expression as message
---
flang/include/flang/Parser/parse-tree.h | 2 +-
flang/lib/Parser/openmp-parsers.cpp | 2 +-
flang/lib/Parser/unparse.cpp | 2 --
flang/test/Parser/OpenMP/error-unparse.f90 | 5 +++++
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 0001afc3a0efc2..9f6290b251fe9b 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4019,7 +4019,7 @@ struct OmpMapClause {
// message-clause ->
// MESSAGE("message-text")
struct OmpMessageClause {
- WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, std::string);
+ WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr);
};
// Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270]
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 0a102db09d6320..e4494ecc2641ea 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -515,7 +515,7 @@ TYPE_PARSER(construct<OmpSeverityClause>(
"FATAL" >> pure(OmpSeverityClause::Severity::Fatal) ||
"WARNING" >> pure(OmpSeverityClause::Severity::Warning)))
-TYPE_PARSER(construct<OmpMessageClause>(charLiteralConstantWithoutKind))
+TYPE_PARSER(construct<OmpMessageClause>(expr))
TYPE_PARSER(
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 5847d690db744a..c4deca78a975ac 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2652,9 +2652,7 @@ class UnparseVisitor {
EndOpenMP();
}
bool Pre(const OmpMessageClause &x) {
- Word("\"");
Walk(x.v);
- Put("\"");
return false;
}
void Unparse(const OpenMPErrorConstruct &x) {
diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90
index e6e8d9aad27316..27b2cd09776a9a 100644
--- a/flang/test/Parser/OpenMP/error-unparse.f90
+++ b/flang/test/Parser/OpenMP/error-unparse.f90
@@ -1,5 +1,10 @@
! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s
program main
+ character(*), parameter :: message = "This is an error"
!CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here")
!$omp error at(compilation) severity(warning) message("some message here")
+ !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message)
+ !$omp error at(compilation) severity(fatal) message(message)
+ !CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message)
+ !$omp error at(EXECUTION) severity(fatal) message(message)
end program main
More information about the flang-commits
mailing list