Skip to content

[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

Merged
merged 5 commits into from
Jul 9, 2025

Conversation

kparzysz
Copy link
Contributor

@kparzysz kparzysz commented Jul 9, 2025

Parse OpenMP 6.0 spellings for directives that don't use OmpDirectiveNameParser.

kparzysz added 2 commits July 9, 2025 07:53
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.
@kparzysz kparzysz requested review from tblah and Stylie777 July 9, 2025 13:18
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:openmp flang:parser labels Jul 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 9, 2025

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-parser

Author: Krzysztof Parzyszek (kparzysz)

Changes

Parse 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:

  • (modified) flang/lib/Parser/openmp-parsers.cpp (+11-6)
  • (added) flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 (+252)
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

@kparzysz
Copy link
Contributor Author

kparzysz commented Jul 9, 2025

Copy link

github-actions bot commented Jul 9, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks!

Base automatically changed from users/kparzysz/spr/v04-parse-flang to main July 9, 2025 21:02
@kparzysz kparzysz merged commit 2546c6d into main Jul 9, 2025
9 checks passed
@kparzysz kparzysz deleted the users/kparzysz/spr/v05-omp6-spellings branch July 9, 2025 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:openmp flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants