OpenMP 5.0 adds a new clause `in_reduction` on OpenMP directives.
This patch adds parser support for the same.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D124156
NODE(parser, OmpProcBindClause)
NODE_ENUM(OmpProcBindClause, Type)
NODE(parser, OmpReductionClause)
+ NODE(parser, OmpInReductionClause)
NODE(parser, OmpReductionCombiner)
NODE(OmpReductionCombiner, FunctionCombiner)
NODE(parser, OmpReductionInitializerClause)
std::tuple<OmpReductionOperator, OmpObjectList> 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<OmpReductionOperator, OmpObjectList> t;
+};
+
// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list)
struct OmpAllocateClause {
TUPLE_CLASS_BOILERPLATE(OmpAllocateClause);
TYPE_PARSER(construct<OmpReductionClause>(
Parser<OmpReductionOperator>{} / ":", Parser<OmpObjectList>{}))
+// OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list)
+TYPE_PARSER(construct<OmpInReductionClause>(
+ Parser<OmpReductionOperator>{} / ":", Parser<OmpObjectList>{}))
+
// OMP 5.0 2.11.4 ALLOCATE ([allocator:] variable-name-list)
TYPE_PARSER(construct<OmpAllocateClause>(
maybe(construct<OmpAllocateClause::Allocator>(scalarIntExpr) / ":"),
parenthesized(Parser<OmpProcBindClause>{}))) ||
"REDUCTION" >> construct<OmpClause>(construct<OmpClause::Reduction>(
parenthesized(Parser<OmpReductionClause>{}))) ||
+ "IN_REDUCTION" >> construct<OmpClause>(construct<OmpClause::InReduction>(
+ parenthesized(Parser<OmpInReductionClause>{}))) ||
"TASK_REDUCTION" >>
construct<OmpClause>(construct<OmpClause::TaskReduction>(
parenthesized(Parser<OmpReductionClause>{}))) ||
Put(":");
Walk(std::get<OmpObjectList>(x.t));
}
+ void Unparse(const OmpInReductionClause &x) {
+ Walk(std::get<OmpReductionOperator>(x.t));
+ Put(":");
+ Walk(std::get<OmpObjectList>(x.t));
+ }
void Unparse(const OmpAllocateClause &x) {
Walk(std::get<std::optional<OmpAllocateClause::Allocator>>(x.t));
Put(":");
--- /dev/null
+! 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'
--- /dev/null
+! 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'
+
}
def OMPC_InReduction : Clause<"in_reduction"> {
let clangClass = "OMPInReductionClause";
+ let flangClass = "OmpInReductionClause";
}
def OMPC_UnifiedAddress : Clause<"unified_address"> {
let clangClass = "OMPUnifiedAddressClause";