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,7 @@ NODE(parser, OmpProcBindClause) NODE_ENUM(OmpProcBindClause, Type) NODE(parser, OmpReductionClause) + NODE(parser, OmpInReductionClause) NODE(parser, OmpReductionCombiner) NODE(OmpReductionCombiner, FunctionCombiner) NODE(parser, OmpReductionInitializerClause) 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 @@ -3434,6 +3434,13 @@ std::tuple t; }; +// OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier: +// variable-name-list) +struct OmpInReductionClause { + TUPLE_CLASS_BOILERPLATE(OmpInReductionClause); + std::tuple t; +}; + // OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list) struct OmpAllocateClause { TUPLE_CLASS_BOILERPLATE(OmpAllocateClause); 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 @@ -122,6 +122,10 @@ TYPE_PARSER(construct( Parser{} / ":", Parser{})) +// OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list) +TYPE_PARSER(construct( + Parser{} / ":", Parser{})) + // OMP 5.0 2.11.4 ALLOCATE ([allocator:] variable-name-list) TYPE_PARSER(construct( maybe(construct(scalarIntExpr) / ":"), @@ -242,6 +246,8 @@ parenthesized(Parser{}))) || "REDUCTION" >> construct(construct( parenthesized(Parser{}))) || + "IN_REDUCTION" >> construct(construct( + parenthesized(Parser{}))) || "TASK_REDUCTION" >> construct(construct( parenthesized(Parser{}))) || 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 @@ -2025,6 +2025,11 @@ Put(":"); Walk(std::get(x.t)); } + void Unparse(const OmpInReductionClause &x) { + Walk(std::get(x.t)); + Put(":"); + Walk(std::get(x.t)); + } void Unparse(const OmpAllocateClause &x) { Walk(std::get>(x.t)); Put(":"); diff --git a/flang/test/Examples/omp-in-reduction-clause.f90 b/flang/test/Examples/omp-in-reduction-clause.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Examples/omp-in-reduction-clause.f90 @@ -0,0 +1,63 @@ +! REQUIRES: plugins, examples, shell + +! RUN: %flang_fc1 -load %llvmshlibdir/flangOmpReport.so -plugin flang-omp-report -fopenmp %s -o - | FileCheck %s + +! Check for IN_REDUCTION() clause on OpenMP constructs + +subroutine omp_in_reduction_taskgroup() + integer :: z, i + !$omp taskgroup task_reduction(+:z) + !$omp task in_reduction(+:z) + z = z + 5 + !$omp end task + + !$omp taskloop in_reduction(+:z) + do i=1,10 + z = z * 5 + end do + !$omp end taskloop + !$omp end taskgroup +end subroutine omp_in_reduction_taskgroup + +!CHECK: - file: {{.*}} +!CHECK: line: 10 +!CHECK: construct: task +!CHECK: clauses: +!CHECK: - clause: in_reduction +!CHECK: details: '+:z' +!CHECK: - file: {{.*}} +!CHECK: line: 14 +!CHECK: construct: taskloop +!CHECK: clauses: +!CHECK: - clause: in_reduction +!CHECK: details: '+:z' +!CHECK: - file: {{.*}} +!CHECK: line: 9 +!CHECK: construct: taskgroup +!CHECK: clauses: +!CHECK: - clause: task_reduction +!CHECK: details: '+:z' + +subroutine omp_in_reduction_parallel() + integer :: z + !$omp parallel reduction(+:z) + !$omp taskloop simd in_reduction(+:z) + do i=1,10 + z = z * 5 + end do + !$omp end taskloop simd + !$omp end parallel +end subroutine omp_in_reduction_parallel + +!CHECK: - file: {{.*}} +!CHECK: line: 44 +!CHECK: construct: taskloop simd +!CHECK: clauses: +!CHECK: - clause: in_reduction +!CHECK: details: '+:z' +!CHECK: - file: {{.*}} +!CHECK: line: 43 +!CHECK: construct: parallel +!CHECK: clauses: +!CHECK: - clause: reduction +!CHECK: details: '+:z' diff --git a/flang/test/Parser/omp-in-reduction-clause.f90 b/flang/test/Parser/omp-in-reduction-clause.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-in-reduction-clause.f90 @@ -0,0 +1,79 @@ +! 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 IN_REDUCTION() clause on OpenMP constructs + +subroutine omp_in_reduction_taskgroup() + integer :: z, i + !CHECK: !$OMP TASKGROUP TASK_REDUCTION(+:z) + !$omp taskgroup task_reduction(+:z) + !CHECK-NEXT: !$OMP TASK IN_REDUCTION(+:z) + !$omp task in_reduction(+:z) + !CHECK-NEXT: z=z+5_4 + z = z + 5 + !CHECK-NEXT: !$OMP END TASK + !$omp end task + + !CHECK-NEXT: !$OMP TASKLOOP IN_REDUCTION(+:z) + !$omp taskloop in_reduction(+:z) + !CHECK-NEXT: DO i=1_4,10_4 + do i=1,10 + !CHECK-NEXT: z=5_4*z + z = z * 5 + !CHECK-NEXT: END DO + end do + !CHECK-NEXT: !$OMP END TASKLOOP + !$omp end taskloop + !CHECK-NEXT: !$OMP END TASKGROUP + !$omp end taskgroup +end subroutine omp_in_reduction_taskgroup + +!PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct +!PARSE-TREE-NEXT: OmpBeginBlockDirective +!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = taskgroup +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> TaskReduction -> OmpReductionClause + +!PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct +!PARSE-TREE-NEXT: OmpBeginBlockDirective +!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = task +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause +!PARSE-TREE-NEXT: OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z' + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause +!PARSE-TREE-NEXT: OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z' + +subroutine omp_in_reduction_parallel() + integer :: z + !CHECK: !$OMP PARALLEL REDUCTION(+:z) + !$omp parallel reduction(+:z) + !CHECK-NEXT: !$OMP TASKLOOP SIMD IN_REDUCTION(+:z) + !$omp taskloop simd in_reduction(+:z) + !CHECK-NEXT: DO i=1_4,10_4 + do i=1,10 + !CHECK-NEXT: z=5_4*z + z = z * 5 + !CHECK-NEXT: END DO + end do + !CHECK-NEXT: !$OMP END TASKLOOP SIMD + !$omp end taskloop simd + !CHECK-NEXT: !$OMP END PARALLEL + !$omp end parallel +end subroutine omp_in_reduction_parallel + +!PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct +!PARSE-TREE-NEXT: OmpBeginBlockDirective +!PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = parallel +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE-NEXT: OmpBeginLoopDirective +!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = taskloop simd +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> InReduction -> OmpInReductionClause +!PARSE-TREE-NEXT: OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Add +!PASRE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'z' + 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 @@ -283,6 +283,7 @@ } def OMPC_InReduction : Clause<"in_reduction"> { let clangClass = "OMPInReductionClause"; + let flangClass = "OmpInReductionClause"; } def OMPC_UnifiedAddress : Clause<"unified_address"> { let clangClass = "OMPUnifiedAddressClause";