-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[flang][OpenMP] Recognize remaining OpenMP 6.0 spellings in parser #147723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Collect all spellings from all supported OpenMP versions before parsing. Break up the list of spellings by the initial letter to speed up parsing a little.
Parse OpenMP 6.0 spellings for directives that don't use OmpDirectiveNameParser.
@llvm/pr-subscribers-flang-openmp @llvm/pr-subscribers-flang-parser Author: Krzysztof Parzyszek (kparzysz) ChangesParse OpenMP 6.0 spellings for directives that don't use OmpDirectiveNameParser. Full diff: https://github.com/llvm/llvm-project/pull/147723.diff 2 Files Affected:
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 29701a616d4b0..b25445b0aaef6 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -1501,7 +1501,7 @@ TYPE_PARSER(
// In this context "TARGET UPDATE" can be parsed as a TARGET directive
// followed by an UPDATE clause. This is the only combination at the
// moment, exclude it explicitly.
- (!"TARGET UPDATE"_sptok) >=
+ (!("TARGET UPDATE"_sptok || "TARGET_UPDATE"_sptok)) >=
construct<OmpBlockDirective>(first(
"MASKED" >> pure(llvm::omp::Directive::OMPD_masked),
"MASTER" >> pure(llvm::omp::Directive::OMPD_master),
@@ -1514,6 +1514,7 @@ TYPE_PARSER(
"SCOPE" >> pure(llvm::omp::Directive::OMPD_scope),
"SINGLE" >> pure(llvm::omp::Directive::OMPD_single),
"TARGET DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
+ "TARGET_DATA" >> pure(llvm::omp::Directive::OMPD_target_data),
"TARGET PARALLEL" >> pure(llvm::omp::Directive::OMPD_target_parallel),
"TARGET TEAMS" >> pure(llvm::omp::Directive::OMPD_target_teams),
"TARGET" >> pure(llvm::omp::Directive::OMPD_target),
@@ -1534,12 +1535,13 @@ TYPE_PARSER(construct<OmpInitializerClause>(
// OpenMP 5.2: 7.5.4 Declare Variant directive
TYPE_PARSER(sourced(
- construct<OmpDeclareVariantDirective>(verbatim("DECLARE VARIANT"_tok),
+ construct<OmpDeclareVariantDirective>(
+ verbatim("DECLARE VARIANT"_tok) || verbatim("DECLARE_VARIANT"_tok),
"(" >> maybe(name / ":"), name / ")", Parser<OmpClauseList>{})))
// 2.16 Declare Reduction Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>(
- verbatim("DECLARE REDUCTION"_tok),
+ verbatim("DECLARE REDUCTION"_tok) || verbatim("DECLARE_REDUCTION"_tok),
"(" >> indirect(Parser<OmpReductionSpecifier>{}) / ")",
maybe(Parser<OmpClauseList>{}))))
@@ -1558,7 +1560,8 @@ TYPE_PARSER(
// 2.10.6 Declare Target Construct
TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>(
- verbatim("DECLARE TARGET"_tok), Parser<OmpDeclareTargetSpecifier>{})))
+ verbatim("DECLARE TARGET"_tok) || verbatim("DECLARE_TARGET"_tok),
+ Parser<OmpDeclareTargetSpecifier>{})))
static OmpMapperSpecifier ConstructOmpMapperSpecifier(
std::optional<Name> &&mapperName, TypeSpec &&typeSpec, Name &&varName) {
@@ -1586,7 +1589,8 @@ TYPE_PARSER(applyFunction<OmpMapperSpecifier>(ConstructOmpMapperSpecifier,
// OpenMP 5.2: 5.8.8 Declare Mapper Construct
TYPE_PARSER(sourced(
- construct<OpenMPDeclareMapperConstruct>(verbatim("DECLARE MAPPER"_tok),
+ construct<OpenMPDeclareMapperConstruct>(
+ verbatim("DECLARE MAPPER"_tok) || verbatim("DECLARE_MAPPER"_tok),
parenthesized(Parser<OmpMapperSpecifier>{}), Parser<OmpClauseList>{})))
TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
@@ -1633,7 +1637,8 @@ TYPE_PARSER(construct<OmpEndAllocators>(startOmpLine >> "END ALLOCATORS"_tok))
// 2.8.2 Declare Simd construct
TYPE_PARSER(
- sourced(construct<OpenMPDeclareSimdConstruct>(verbatim("DECLARE SIMD"_tok),
+ sourced(construct<OpenMPDeclareSimdConstruct>(
+ verbatim("DECLARE SIMD"_tok) || verbatim("DECLARE_SIMD"_tok),
maybe(parenthesized(name)), Parser<OmpClauseList>{})))
// 2.4 Requires construct
diff --git a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90
new file mode 100644
index 0000000000000..6a1d565451220
--- /dev/null
+++ b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90
@@ -0,0 +1,252 @@
+!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s -o - | FileCheck --check-prefix=UNPARSE %s
+!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s -o - | FileCheck --check-prefix=PARSE-TREE %s
+
+! The directives to check:
+! cancellation_point
+! declare_mapper
+! declare_reduction
+! declare_simd
+! declare_target
+! declare_variant
+! target_data
+! target_enter_data
+! target_exit_data
+! target_update
+
+subroutine f00
+ implicit none
+ integer :: i
+
+ !$omp parallel
+ do i = 1, 10
+ !$omp cancellation_point parallel
+ enddo
+ !$omp end parallel
+end
+
+!UNPARSE: SUBROUTINE f00
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER i
+!UNPARSE: !$OMP PARALLEL
+!UNPARSE: DO i=1_4,10_4
+!UNPARSE: !$OMP CANCELLATION_POINT PARALLEL
+!UNPARSE: END DO
+!UNPARSE: !$OMP END PARALLEL
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPCancellationPointConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = cancellation point
+!PARSE-TREE: | OmpClauseList -> OmpClause -> CancellationConstructType -> OmpCancellationConstructTypeClause
+!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel
+!PARSE-TREE: | Flags = None
+
+subroutine f01
+ type :: t
+ integer :: x
+ end type
+ !$omp declare_mapper(t :: v) map(v%x)
+end
+
+!UNPARSE: SUBROUTINE f01
+!UNPARSE: TYPE :: t
+!UNPARSE: INTEGER :: x
+!UNPARSE: END TYPE
+!UNPARSE: !$OMP DECLARE MAPPER (t::v) MAP(v%x)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareMapperConstruct
+!PARSE-TREE: | Verbatim
+!PARSE-TREE: | OmpMapperSpecifier
+!PARSE-TREE: | | string = 't.omp.default.mapper'
+!PARSE-TREE: | | TypeSpec -> DerivedTypeSpec
+!PARSE-TREE: | | | Name = 't'
+!PARSE-TREE: | | Name = 'v'
+!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
+!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> StructureComponent
+!PARSE-TREE: | | | DataRef -> Name = 'v'
+!PARSE-TREE: | | | Name = 'x'
+!PARSE-TREE: | | bool = 'true'
+
+subroutine f02
+ type :: t
+ integer :: x
+ end type
+ !$omp declare_reduction(+ : t : omp_out%x = omp_out%x + omp_in%x)
+end
+
+!UNPARSE: SUBROUTINE f02
+!UNPARSE: TYPE :: t
+!UNPARSE: INTEGER :: x
+!UNPARSE: END TYPE
+!UNPARSE: !$OMP DECLARE REDUCTION (+:t: omp_out%x=omp_out%x+omp_in%x
+!UNPARSE: )
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct
+!PARSE-TREE: | Verbatim
+!PARSE-TREE: | OmpReductionSpecifier
+!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
+!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec
+!PARSE-TREE: | | | Name = 't'
+!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%x=omp_out%x+omp_in%x'
+!PARSE-TREE: | | | Variable = 'omp_out%x'
+!PARSE-TREE: | | | | Designator -> DataRef -> StructureComponent
+!PARSE-TREE: | | | | | DataRef -> Name = 'omp_out'
+!PARSE-TREE: | | | | | Name = 'x'
+!PARSE-TREE: | | | Expr = 'omp_out%x+omp_in%x'
+!PARSE-TREE: | | | | Add
+!PARSE-TREE: | | | | | Expr = 'omp_out%x'
+!PARSE-TREE: | | | | | | Designator -> DataRef -> StructureComponent
+!PARSE-TREE: | | | | | | | DataRef -> Name = 'omp_out'
+!PARSE-TREE: | | | | | | | Name = 'x'
+!PARSE-TREE: | | | | | Expr = 'omp_in%x'
+!PARSE-TREE: | | | | | | Designator -> DataRef -> StructureComponent
+!PARSE-TREE: | | | | | | | DataRef -> Name = 'omp_in'
+!PARSE-TREE: | | | | | | | Name = 'x'
+!PARSE-TREE: | OmpClauseList ->
+
+subroutine f03
+ !$omp declare_simd
+end
+
+!UNPARSE: SUBROUTINE f03
+!UNPARSE: !$OMP DECLARE SIMD
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareSimdConstruct
+!PARSE-TREE: | Verbatim
+!PARSE-TREE: | OmpClauseList ->
+
+subroutine f04
+ !$omp declare_target
+end
+
+!UNPARSE: SUBROUTINE f04
+!UNPARSE: !$OMP DECLARE TARGET
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct
+!PARSE-TREE: | Verbatim
+!PARSE-TREE: | OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList ->
+
+subroutine f05
+ implicit none
+ interface
+ subroutine g05
+ end
+ end interface
+ !$omp declare_variant(g05) match(user={condition(.true.)})
+end
+
+!UNPARSE: SUBROUTINE f05
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTERFACE
+!UNPARSE: SUBROUTINE g05
+!UNPARSE: END SUBROUTINE
+!UNPARSE: END INTERFACE
+!UNPARSE: !$OMP DECLARE VARIANT (g05) MATCH(USER={CONDITION(.true._4)})
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective
+!PARSE-TREE: | Verbatim
+!PARSE-TREE: | Name = 'g05'
+!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> 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'
+
+subroutine f06
+ implicit none
+ integer :: i
+ !$omp target_data map(tofrom: i)
+ i = 0
+ !$omp end target data
+end
+
+!UNPARSE: SUBROUTINE f06
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER i
+!UNPARSE: !$OMP TARGET DATA MAP(TOFROM: i)
+!UNPARSE: i=0_4
+!UNPARSE: !$OMP END TARGET DATA
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPBlockConstruct
+!PARSE-TREE: | OmpBeginBlockDirective
+!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target data
+!PARSE-TREE: | | OmpClauseList -> OmpClause -> Map -> OmpMapClause
+!PARSE-TREE: | | | Modifier -> OmpMapType -> Value = Tofrom
+!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: | | | bool = 'true'
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'i=0_4'
+!PARSE-TREE: | | | Variable = 'i'
+!PARSE-TREE: | | | | Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: | | | Expr = '0_4'
+!PARSE-TREE: | | | | LiteralConstant -> IntLiteralConstant = '0'
+!PARSE-TREE: | OmpEndBlockDirective
+!PARSE-TREE: | | OmpBlockDirective -> llvm::omp::Directive = target data
+!PARSE-TREE: | | OmpClauseList ->
+
+subroutine f07
+ implicit none
+ integer :: i
+ !$omp target_enter_data map(to: i)
+end
+
+!UNPARSE: SUBROUTINE f07
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER i
+!UNPARSE: !$OMP TARGET_ENTER_DATA MAP(TO: i)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target enter data
+!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
+!PARSE-TREE: | | Modifier -> OmpMapType -> Value = To
+!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: | | bool = 'true'
+!PARSE-TREE: | Flags = None
+
+subroutine f08
+ implicit none
+ integer :: i
+ !$omp target_exit_data map(from: i)
+end
+
+!UNPARSE: SUBROUTINE f08
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER i
+!UNPARSE: !$OMP TARGET_EXIT_DATA MAP(FROM: i)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target exit data
+!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
+!PARSE-TREE: | | Modifier -> OmpMapType -> Value = From
+!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: | | bool = 'true'
+!PARSE-TREE: | Flags = None
+
+subroutine f09
+ implicit none
+ integer :: i
+ !$omp target_update to(i)
+end
+
+!UNPARSE: SUBROUTINE f09
+!UNPARSE: IMPLICIT NONE
+!UNPARSE: INTEGER i
+!UNPARSE: !$OMP TARGET_UPDATE TO(i)
+!UNPARSE: END SUBROUTINE
+
+!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
+!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target update
+!PARSE-TREE: | OmpClauseList -> OmpClause -> To -> OmpToClause
+!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
+!PARSE-TREE: | | bool = 'true'
+!PARSE-TREE: | Flags = None
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
Parse OpenMP 6.0 spellings for directives that don't use OmpDirectiveNameParser.