https://github.com/kparzysz updated https://github.com/llvm/llvm-project/pull/130122
>From bf56b8c80a0f1a7e06dcd3e898172c27e5afabf5 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 5 Mar 2025 08:24:30 -0600 Subject: [PATCH 1/2] [flang][OpenMP] Accept old FLUSH syntax in METADIRECTIVE Accommodate it in OmpDirectiveSpecification, which may become the primary component of the actual FLUSH construct in the future. --- flang/include/flang/Parser/dump-parse-tree.h | 1 + flang/include/flang/Parser/parse-tree.h | 6 ++- flang/lib/Parser/openmp-parsers.cpp | 32 +++++++++-- flang/lib/Parser/unparse.cpp | 28 +++++++--- .../Parser/OpenMP/metadirective-flush.f90 | 54 +++++++++++++++++++ 5 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 flang/test/Parser/OpenMP/metadirective-flush.f90 diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index a154794e41e9d..fcd902d25fa40 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -491,6 +491,7 @@ class ParseTreeDumper { NODE(OmpWhenClause, Modifier) NODE(parser, OmpDirectiveName) NODE(parser, OmpDirectiveSpecification) + NODE_ENUM(OmpDirectiveSpecification, Flags) NODE(parser, OmpTraitPropertyName) NODE(parser, OmpTraitScore) NODE(parser, OmpTraitPropertyExtension) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 346299b8e5215..a197249ebae91 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4503,13 +4503,15 @@ struct OmpClauseList { // --- Directives and constructs struct OmpDirectiveSpecification { - CharBlock source; + ENUM_CLASS(Flags, None, DeprecatedSyntax); TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification); llvm::omp::Directive DirId() const { // return std::get<OmpDirectiveName>(t).v; } + + CharBlock source; std::tuple<OmpDirectiveName, std::optional<std::list<OmpArgument>>, - std::optional<OmpClauseList>> + std::optional<OmpClauseList>, Flags> t; }; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index b3e76d70c8064..0de7690b90262 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -995,10 +995,34 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>( // --- Parsers for directives and constructs -------------------------- -TYPE_PARSER(sourced(construct<OmpDirectiveSpecification>( // - sourced(OmpDirectiveNameParser{}), - maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))), - maybe(Parser<OmpClauseList>{})))) +OmpDirectiveSpecification static makeFlushFromOldSyntax1( + Verbatim &&text, std::optional<OmpClauseList> &&clauses, + std::optional<std::list<OmpArgument>> &&args, + OmpDirectiveSpecification::Flags &&flags) { + return OmpDirectiveSpecification{OmpDirectiveName(text), std::move(args), + std::move(clauses), std::move(flags)}; +} + +TYPE_PARSER(sourced( + // Parse the old syntax: FLUSH [clauses] [(objects)] + construct<OmpDirectiveSpecification>( // + // Force this old-syntax parser to fail for FLUSH followed by '('. + // Otherwise it could succeed on the new syntax but have one of + // lists absent in the parsed result. + // E.g. for FLUSH(x) SEQ_CST it would find no clauses following + // the directive name, parse the argument list "(x)" and stop. + applyFunction(makeFlushFromOldSyntax1, + verbatim("FLUSH"_tok) / !lookAhead("("_tok), + maybe(Parser<OmpClauseList>{}), + maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))), + pure(OmpDirectiveSpecification::Flags::DeprecatedSyntax))) || + // Parse the standard syntax: directive [(arguments)] [clauses] + construct<OmpDirectiveSpecification>( // + sourced(OmpDirectiveNameParser{}), + maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))), + maybe(Parser<OmpClauseList>{}), + pure(OmpDirectiveSpecification::Flags::None)) +)) TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok))) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 4f5c05dc2aa25..262077e62441b 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2094,14 +2094,30 @@ class UnparseVisitor { Word(llvm::omp::getOpenMPDirectiveName(x).str()); } void Unparse(const OmpDirectiveSpecification &x) { - using ArgList = std::list<parser::OmpArgument>; + auto unparseArgs{[&]() { + using ArgList = std::list<parser::OmpArgument>; + if (auto &args{std::get<std::optional<ArgList>>(x.t)}) { + Put("("); + Walk(*args); + Put(")"); + } + }}; + auto unparseClauses{[&]() { + Walk(std::get<std::optional<OmpClauseList>>(x.t)); + }}; + Walk(std::get<OmpDirectiveName>(x.t)); - if (auto &args{std::get<std::optional<ArgList>>(x.t)}) { - Put("("); - Walk(*args); - Put(")"); + auto flags{std::get<OmpDirectiveSpecification::Flags>(x.t)}; + if (flags == OmpDirectiveSpecification::Flags::DeprecatedSyntax) { + if (x.DirId() == llvm::omp::Directive::OMPD_flush) { + // FLUSH clause arglist + unparseClauses(); + unparseArgs(); + } + } else { + unparseArgs(); + unparseClauses(); } - Walk(std::get<std::optional<OmpClauseList>>(x.t)); } void Unparse(const OmpTraitScore &x) { Word("SCORE("); diff --git a/flang/test/Parser/OpenMP/metadirective-flush.f90 b/flang/test/Parser/OpenMP/metadirective-flush.f90 new file mode 100644 index 0000000000000..8403663200f93 --- /dev/null +++ b/flang/test/Parser/OpenMP/metadirective-flush.f90 @@ -0,0 +1,54 @@ +!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=52 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=52 %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine f00() + integer :: x + !$omp metadirective when(user={condition(.true.)}: flush seq_cst (x)) +end + +!UNPARSE: SUBROUTINE f00 +!UNPARSE: INTEGER x +!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH SEQ_CST(x)) +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpMetadirectiveDirective +!PARSE-TREE: | OmpClauseList -> OmpClause -> When -> OmpWhenClause +!PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector +!PARSE-TREE: | | | OmpTraitSetSelectorName -> Value = User +!PARSE-TREE: | | | OmpTraitSelector +!PARSE-TREE: | | | | OmpTraitSelectorName -> Value = Condition +!PARSE-TREE: | | | | Properties +!PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4' +!PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant +!PARSE-TREE: | | | | | | | bool = 'true' +!PARSE-TREE: | | OmpDirectiveSpecification +!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush +!PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | | OmpClauseList -> OmpClause -> SeqCst +!PARSE-TREE: | | | Flags = DeprecatedSyntax + +subroutine f01() + integer :: x + !$omp metadirective when(user={condition(.true.)}: flush(x) seq_cst) +end + +!UNPARSE: SUBROUTINE f01 +!UNPARSE: INTEGER x +!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH(x) SEQ_CST) +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpMetadirectiveDirective +!PARSE-TREE: | OmpClauseList -> OmpClause -> When -> OmpWhenClause +!PARSE-TREE: | | Modifier -> OmpContextSelectorSpecification -> OmpTraitSetSelector +!PARSE-TREE: | | | OmpTraitSetSelectorName -> Value = User +!PARSE-TREE: | | | OmpTraitSelector +!PARSE-TREE: | | | | OmpTraitSelectorName -> Value = Condition +!PARSE-TREE: | | | | Properties +!PARSE-TREE: | | | | | OmpTraitProperty -> Scalar -> Expr = '.true._4' +!PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant +!PARSE-TREE: | | | | | | | bool = 'true' +!PARSE-TREE: | | OmpDirectiveSpecification +!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush +!PARSE-TREE: | | | OmpArgument -> OmpLocator -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | | OmpClauseList -> OmpClause -> SeqCst +!PARSE-TREE: | | | Flags = None >From 00e6f062b3420d1edd0776262905c874e3267d53 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Thu, 6 Mar 2025 09:50:57 -0600 Subject: [PATCH 2/2] format --- flang/lib/Parser/openmp-parsers.cpp | 11 +++++------ flang/lib/Parser/unparse.cpp | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 0de7690b90262..80831db0e7d50 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -995,17 +995,17 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>( // --- Parsers for directives and constructs -------------------------- -OmpDirectiveSpecification static makeFlushFromOldSyntax1( - Verbatim &&text, std::optional<OmpClauseList> &&clauses, +OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text, + std::optional<OmpClauseList> &&clauses, std::optional<std::list<OmpArgument>> &&args, OmpDirectiveSpecification::Flags &&flags) { return OmpDirectiveSpecification{OmpDirectiveName(text), std::move(args), - std::move(clauses), std::move(flags)}; + std::move(clauses), std::move(flags)}; } TYPE_PARSER(sourced( // Parse the old syntax: FLUSH [clauses] [(objects)] - construct<OmpDirectiveSpecification>( // + construct<OmpDirectiveSpecification>( // Force this old-syntax parser to fail for FLUSH followed by '('. // Otherwise it could succeed on the new syntax but have one of // lists absent in the parsed result. @@ -1021,8 +1021,7 @@ TYPE_PARSER(sourced( sourced(OmpDirectiveNameParser{}), maybe(parenthesized(nonemptyList(Parser<OmpArgument>{}))), maybe(Parser<OmpClauseList>{}), - pure(OmpDirectiveSpecification::Flags::None)) -)) + pure(OmpDirectiveSpecification::Flags::None)))) TYPE_PARSER(sourced(construct<OmpNothingDirective>("NOTHING" >> ok))) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 262077e62441b..12d86653a2b95 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2102,7 +2102,7 @@ class UnparseVisitor { Put(")"); } }}; - auto unparseClauses{[&]() { + auto unparseClauses{[&]() { // Walk(std::get<std::optional<OmpClauseList>>(x.t)); }}; _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits