diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -514,6 +514,8 @@ } NODE(parser, OmpObject) NODE(parser, OmpObjectList) + NODE(parser, OmpOrderClause) + NODE_ENUM(OmpOrderClause, Type) NODE(parser, OmpProcBindClause) NODE_ENUM(OmpProcBindClause, Type) NODE(parser, OmpReductionClause) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3411,6 +3411,12 @@ std::tuple, std::optional> t; }; +// 2.9.5 order-clause -> ORDER (CONCURRENT) +struct OmpOrderClause { + ENUM_CLASS(Type, Concurrent) + WRAPPER_CLASS_BOILERPLATE(OmpOrderClause, Type); +}; + // 2.15.3.7 linear-modifier -> REF | VAL | UVAL struct OmpLinearModifier { ENUM_CLASS(Type, Ref, Val, Uval) diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -179,6 +179,10 @@ TYPE_PARSER(construct( nonemptyList(name), maybe(":" >> scalarIntConstantExpr))) +// 2.9.5 ORDER (CONCURRENT) +TYPE_PARSER(construct( + "CONCURRENT" >> pure(OmpOrderClause::Type::Concurrent))) + TYPE_PARSER( construct(designator) || construct("/" >> name / "/")) @@ -250,6 +254,8 @@ parenthesized(scalarIntExpr))) || "NUM_THREADS" >> construct(construct( parenthesized(scalarIntExpr))) || + "ORDER" >> construct(construct( + parenthesized(Parser{}))) || "ORDERED" >> construct(construct( maybe(parenthesized(scalarIntConstantExpr)))) || "PARTIAL" >> construct(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2618,6 +2618,7 @@ WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type + WALK_NESTED_ENUM(OmpOrderClause, Type) // OMP ORDER #undef WALK_NESTED_ENUM void Done() const { CHECK(indent_ == 0); } diff --git a/flang/test/Examples/omp-order-clause.f90 b/flang/test/Examples/omp-order-clause.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Examples/omp-order-clause.f90 @@ -0,0 +1,37 @@ +! REQUIRES: plugins, examples, shell + +! RUN: %flang_fc1 -load %llvmshlibdir/flangOmpReport.so -plugin flang-omp-report -fopenmp %s -o - | FileCheck %s + +! Check for ORDER(CONCURRENT) clause on OpenMP constructs + +subroutine test_one() + integer :: i, j = 1 + !$omp do order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end do +end subroutine + +!CHECK: - file: {{.*}} +!CHECK: line: 8 +!CHECK: construct: do +!CHECK: clauses: +!CHECK: - clause: order +!CHECK: details: concurrent + +subroutine test_two() + integer :: i, j = 1 + !$omp simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end simd +end subroutine + +!CHECK: - file: {{.*}} +!CHECK: line: 24 +!CHECK: construct: simd +!CHECK: clauses: +!CHECK: - clause: order +!CHECK: details: concurrent diff --git a/flang/test/Parser/omp-order-clause01.f90 b/flang/test/Parser/omp-order-clause01.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-order-clause01.f90 @@ -0,0 +1,229 @@ +! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s +! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s + +! Check for ORDER(CONCURRENT) clause on OpenMP constructs + +subroutine test_one() + integer :: i, j = 1 + !CHECK: !$omp do order(concurrent) + !$omp do order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end do +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_two() + integer :: i, j = 1 + !CHECK: !$omp simd order(concurrent) + !$omp simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_three() + integer :: i, j = 1 + !CHECK: !$omp do simd order(concurrent) + !$omp do simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end do simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = do simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_four() + integer :: i, j = 1 + !CHECK: !$omp parallel do order(concurrent) + !$omp parallel do order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end parallel do +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_five() + integer :: i, j = 1 + !CHECK: !$omp parallel do simd order(concurrent) + !$omp parallel do simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end parallel do simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = parallel do simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_six() + integer :: i, j = 1 + !CHECK: !$omp target simd order(concurrent) + !$omp target simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end target simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_seven() + integer :: i, j = 1 + !CHECK: !$omp target parallel do order(concurrent) + !$omp target parallel do order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end target parallel do +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_eight() + integer :: i, j = 1 + !CHECK: !$omp target parallel do simd order(concurrent) + !$omp target parallel do simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end target parallel do simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target parallel do simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_nine() + integer :: i, j = 1 + !CHECK: !$omp teams distribute simd order(concurrent) + !$omp teams distribute simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end teams distribute simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_ten() + integer :: i, j = 1 + !CHECK: !$omp teams distribute parallel do order(concurrent) + !$omp teams distribute parallel do order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end teams distribute parallel do +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_eleven() + integer :: i, j = 1 + !CHECK: !$omp teams distribute parallel do simd order(concurrent) + !$omp teams distribute parallel do simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end teams distribute parallel do simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = teams distribute parallel do simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_twelve() + integer :: i, j = 1 + !CHECK: !$omp target teams distribute simd order(concurrent) + !$omp target teams distribute simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end target teams distribute simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_thirteen() + integer :: i, j = 1 + !CHECK: !$omp target teams distribute parallel do order(concurrent) + !$omp target teams distribute parallel do order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end target teams distribute parallel do +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_fourteen() + integer :: i, j = 1 + !CHECK: !$omp target teams distribute parallel do simd order(concurrent) + !$omp target teams distribute parallel do simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end target teams distribute parallel do simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = target teams distribute parallel do simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent + +subroutine test_fifteen() + integer :: i, j = 1 + !CHECK: !$omp taskloop simd order(concurrent) + !$omp taskloop simd order(concurrent) + do i=1,10 + j = j + 1 + end do + !$omp end taskloop simd +end subroutine + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Order -> OmpOrderClause -> Type = Concurrent diff --git a/flang/test/Parser/omp-order-clause02.f90 b/flang/test/Parser/omp-order-clause02.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-order-clause02.f90 @@ -0,0 +1,10 @@ +! RUN: not %flang_fc1 -fopenmp %s 2>&1 | FileCheck %s + +subroutine omp_order() + integer :: i, j = 1 + ! CHECK: error: At most one ORDER clause can appear on the SIMD directive + !$omp simd order(concurrent) order(concurrent) + do i=1,10 + j = j + 1 + end do +end subroutine omp_order diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -352,6 +352,7 @@ def OMP_ORDER_unknown : ClauseVal<"unknown",2,0> { let isDefault = 1; } def OMPC_Order : Clause<"order"> { let clangClass = "OMPOrderClause"; + let flangClass = "OmpOrderClause"; let enumClauseValue = "OrderKind"; let allowedClauseValues = [ OMP_ORDER_unknown, @@ -491,13 +492,13 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause ]; let allowedOnceClauses = [ VersionedClause, VersionedClause, VersionedClause, VersionedClause, + VersionedClause ]; } def OMP_Tile : Directive<"tile"> { @@ -538,7 +539,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_Sections : Directive<"sections"> { @@ -789,7 +791,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause @@ -803,7 +804,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_TargetUpdate : Directive<"target update"> { @@ -855,7 +857,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_ParallelForSimd : Directive<"parallel for simd"> { @@ -895,7 +898,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause ]; let allowedOnceClauses = [ VersionedClause, @@ -905,7 +907,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_ParallelMaster : Directive<"parallel master"> { @@ -971,7 +974,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause ]; } def OMP_DoSimd : Directive<"do simd"> { @@ -989,7 +992,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_CancellationPoint : Directive<"cancellation point"> {} @@ -1050,7 +1054,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1062,7 +1065,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; let allowedExclusiveClauses = [ VersionedClause, @@ -1122,7 +1126,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1136,7 +1139,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> { @@ -1184,7 +1188,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause ]; } def OMP_DistributeSimd : Directive<"distribute simd"> { @@ -1197,7 +1201,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause ]; @@ -1210,7 +1213,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } @@ -1275,7 +1279,7 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, + VersionedClause, VersionedClause ]; } @@ -1292,7 +1296,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1309,6 +1312,7 @@ VersionedClause, VersionedClause, VersionedClause, + VersionedClause ]; } def OMP_TeamsDistribute : Directive<"teams distribute"> { @@ -1334,7 +1338,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause @@ -1347,7 +1350,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } @@ -1387,7 +1391,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause ]; @@ -1403,6 +1406,7 @@ VersionedClause, VersionedClause, VersionedClause, + VersionedClause ]; } def OMP_TeamsDistributeParallelFor : @@ -1446,11 +1450,11 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_TargetTeams : Directive<"target teams"> { @@ -1556,7 +1560,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause ]; let allowedOnceClauses = [ VersionedClause, @@ -1570,6 +1573,7 @@ VersionedClause, VersionedClause, VersionedClause, + VersionedClause ]; } def OMP_TargetTeamsDistributeParallelForSimd : @@ -1626,7 +1630,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause ]; @@ -1644,7 +1647,8 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause + VersionedClause, + VersionedClause ]; } def OMP_TargetTeamsDistributeSimd : @@ -1661,7 +1665,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1678,6 +1681,7 @@ VersionedClause, VersionedClause, VersionedClause, + VersionedClause ]; } def OMP_Allocate : Directive<"allocate"> { @@ -1996,7 +2000,7 @@ let allowedOnceClauses = [ VersionedClause, VersionedClause, - VersionedClause, + VersionedClause ]; } def OMP_teams_loop : Directive<"teams loop"> {