[flang][OpenMP] Frontend support for NOTHING directive (#120606)

Create OpenMPUtilityConstruct and put the two utility directives in it
(error and nothing). Rename OpenMPErrorConstruct to OmpErrorDirective.
This commit is contained in:
Krzysztof Parzyszek 2025-01-03 08:36:34 -06:00 committed by GitHub
parent e576c5bed7
commit df859f90aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 75 additions and 28 deletions

View File

@ -90,6 +90,10 @@ SourcePosition OpenMPCounterVisitor::getLocation(const OpenMPConstruct &c) {
const CharBlock &source{c.source};
return (parsing->allCooked().GetSourcePositionRange(source))->first;
},
[&](const OpenMPUtilityConstruct &c) -> SourcePosition {
const CharBlock &source{c.source};
return (parsing->allCooked().GetSourcePositionRange(source))->first;
},
},
c.u);
}
@ -143,8 +147,8 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
},
c.u);
},
[&](const OpenMPErrorConstruct &c) -> std::string {
const CharBlock &source{std::get<0>(c.t).source};
[&](const OpenMPUtilityConstruct &c) -> std::string {
const CharBlock &source{c.source};
return normalize_construct_name(source.ToString());
},
[&](const OpenMPSectionConstruct &c) -> std::string {

View File

@ -516,6 +516,8 @@ public:
#include "llvm/Frontend/OpenMP/OMP.inc"
NODE(parser, OmpClauseList)
NODE(parser, OmpCriticalDirective)
NODE(parser, OmpErrorDirective)
NODE(parser, OmpNothingDirective)
NODE(parser, OmpDeclareTargetSpecifier)
NODE(parser, OmpDeclareTargetWithClause)
NODE(parser, OmpDeclareTargetWithList)
@ -662,7 +664,7 @@ public:
NODE(parser, OmpAtomicDefaultMemOrderClause)
NODE_ENUM(common, OmpAtomicDefaultMemOrderType)
NODE(parser, OpenMPDepobjConstruct)
NODE(parser, OpenMPErrorConstruct)
NODE(parser, OpenMPUtilityConstruct)
NODE(parser, OpenMPFlushConstruct)
NODE(parser, OpenMPLoopConstruct)
NODE(parser, OpenMPExecutableAllocate)

View File

@ -4182,6 +4182,30 @@ struct OmpClauseList {
// --- Directives and constructs
// Ref: [5.1:89-90], [5.2:216]
//
// nothing-directive ->
// NOTHING // since 5.1
struct OmpNothingDirective {
using EmptyTrait = std::true_type;
COPY_AND_ASSIGN_BOILERPLATE(OmpNothingDirective);
CharBlock source;
};
// Ref: OpenMP [5.2:216-218]
// ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str)
struct OmpErrorDirective {
TUPLE_CLASS_BOILERPLATE(OmpErrorDirective);
CharBlock source;
std::tuple<Verbatim, OmpClauseList> t;
};
struct OpenMPUtilityConstruct {
UNION_CLASS_BOILERPLATE(OpenMPUtilityConstruct);
CharBlock source;
std::variant<OmpErrorDirective, OmpNothingDirective> u;
};
// 2.7.2 SECTIONS
// 2.11.2 PARALLEL SECTIONS
struct OmpSectionsDirective {
@ -4506,14 +4530,6 @@ 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);
@ -4586,7 +4602,7 @@ struct OpenMPConstruct {
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,
OpenMPSectionConstruct, OpenMPLoopConstruct, OpenMPBlockConstruct,
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPErrorConstruct,
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPUtilityConstruct,
OpenMPExecutableAllocate, OpenMPAllocatorsConstruct,
OpenMPCriticalConstruct>
u;

View File

@ -2907,8 +2907,8 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
lower::pft::Evaluation &eval,
const parser::OpenMPErrorConstruct &) {
TODO(converter.getCurrentLocation(), "OpenMPErrorConstruct");
const parser::OpenMPUtilityConstruct &) {
TODO(converter.getCurrentLocation(), "OpenMPUtilityConstruct");
}
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,

View File

@ -737,9 +737,20 @@ TYPE_PARSER(
TYPE_PARSER(sourced(construct<OmpClauseList>(
many(maybe(","_tok) >> sourced(Parser<OmpClause>{})))))
// 2.1 (variable | /common-block | array-sections)
// 2.1 (variable | /common-block/ | array-sections)
TYPE_PARSER(construct<OmpObjectList>(nonemptyList(Parser<OmpObject>{})))
TYPE_PARSER(sourced(construct<OmpErrorDirective>(
verbatim("ERROR"_tok), Parser<OmpClauseList>{})))
TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok)))
TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>(
sourced(construct<OpenMPUtilityConstruct>(
sourced(Parser<OmpErrorDirective>{}))) ||
sourced(construct<OpenMPUtilityConstruct>(
sourced(Parser<OmpNothingDirective>{}))))))
// Omp directives enclosing do loop
TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
"DISTRIBUTE PARALLEL DO SIMD" >>
@ -1027,9 +1038,6 @@ 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),
@ -1127,7 +1135,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<OpenMPUtilityConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),

View File

@ -2710,11 +2710,15 @@ public:
Walk(x.v);
return false;
}
void Unparse(const OpenMPErrorConstruct &x) {
void Unparse(const OmpErrorDirective &x) {
Word("!$OMP ERROR ");
Walk(x.t);
Put("\n");
}
void Unparse(const OmpNothingDirective &x) {
Word("!$OMP NOTHING");
Put("\n");
}
void Unparse(const OmpSectionsDirective &x) {
switch (x.v) {
case llvm::omp::Directive::OMPD_sections:

View File

@ -1688,12 +1688,12 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) {
dirContext_.pop_back();
}
void OmpStructureChecker::Enter(const parser::OpenMPErrorConstruct &x) {
void OmpStructureChecker::Enter(const parser::OmpErrorDirective &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) {
void OmpStructureChecker::Leave(const parser::OmpErrorDirective &x) {
dirContext_.pop_back();
}

View File

@ -102,8 +102,8 @@ public:
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::OmpErrorDirective &);
void Leave(const parser::OmpErrorDirective &);
void Enter(const parser::OpenMPExecutableAllocate &);
void Leave(const parser::OpenMPExecutableAllocate &);
void Enter(const parser::OpenMPAllocatorsConstruct &);

View File

@ -1,6 +1,6 @@
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s
! CHECK: not yet implemented: OpenMPErrorConstruct
! CHECK: not yet implemented: OpenMPUtilityConstruct
program p
integer, allocatable :: x
!$omp error at(compilation) severity(warning) message("an error")

View File

@ -3,19 +3,19 @@
program main
character(*), parameter :: message = "This is an error"
!CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here")
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpErrorDirective
!PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation
!PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Warning
!PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> LiteralConstant -> CharLiteralConstant
!$omp error at(compilation) severity(warning) message("some message here")
!CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpErrorDirective
!PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation
!PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal
!PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message'
!$omp error at(compilation) severity(fatal) message(message)
!CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message)
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpErrorDirective
!PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Execution
!PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal
!PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message'

View File

@ -0,0 +1,13 @@
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=51 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=51 %s | FileCheck --check-prefix="PARSE-TREE" %s
subroutine f00
!$omp nothing
end
!UNPARSE: SUBROUTINE f00
!UNPARSE: !$OMP NOTHING
!UNPARSE: END SUBROUTINE
!PARSE-TREE: ExecutionPart -> Block
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPUtilityConstruct -> OmpNothingDirective