[flang-commits] [flang] b501503 - [Flang][OpenMP] Fix for unstructured regions in OpenMP constructs - 2
Kiran Chandramohan via flang-commits
flang-commits at lists.llvm.org
Tue May 31 02:43:06 PDT 2022
Author: kiranchandramohan
Date: 2022-05-31T09:25:56Z
New Revision: b501503ca0bc5562e5ef4eb736ab718fd29c7bc3
URL: https://github.com/llvm/llvm-project/commit/b501503ca0bc5562e5ef4eb736ab718fd29c7bc3
DIFF: https://github.com/llvm/llvm-project/commit/b501503ca0bc5562e5ef4eb736ab718fd29c7bc3.diff
LOG: [Flang][OpenMP] Fix for unstructured regions in OpenMP constructs - 2
The following changes are made for OpenMP operations with unstructured region,
1. For combined constructs the outer operation is considered a structured
region and the inner one as the unstructured.
2. Added a condition to ensure that we create new blocks only once for nested
unstructured OpenMP constructs.
Tests are added for checking the structure of the CFG.
Note: This is part of upstreaming from the fir-dev branch of
https://github.com/flang-compiler/f18-llvm-project. Code originally reviewed
at https://github.com/flang-compiler/f18-llvm-project/pull/1394.
Reviewed By: vdonaldson, shraiysh, peixin
Differential Revision: https://reviews.llvm.org/D126375
Added:
Modified:
flang/lib/Lower/OpenMP.cpp
flang/test/Lower/OpenMP/omp-unstructured.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 04cd39adbe8b0..85a54ebc412ca 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -156,7 +156,7 @@ void createEmptyRegionBlocks(
"expected terminator op");
}
}
- if (eval.hasNestedEvaluations())
+ if (!eval.isDirective() && eval.hasNestedEvaluations())
createEmptyRegionBlocks(firOpBuilder, eval.getNestedEvaluations());
}
}
@@ -179,7 +179,7 @@ createBodyOfOp(Op &op, Fortran::lower::AbstractConverter &converter,
const Fortran::parser::OmpClauseList *clauses = nullptr,
const SmallVector<const Fortran::semantics::Symbol *> &args = {},
bool outerCombined = false) {
- auto &firOpBuilder = converter.getFirOpBuilder();
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
// If an argument for the region is provided then create the block with that
// argument. Also update the symbol's address with the mlir argument value.
// e.g. For loops the argument is the induction variable. And all further
@@ -205,13 +205,15 @@ createBodyOfOp(Op &op, Fortran::lower::AbstractConverter &converter,
} else {
firOpBuilder.createBlock(&op.getRegion());
}
- auto &block = op.getRegion().back();
- firOpBuilder.setInsertionPointToStart(&block);
+ mlir::Block &block = op.getRegion().back();
+ firOpBuilder.setInsertionPointToEnd(&block);
- if (eval.lowerAsUnstructured())
+ // If it is an unstructured region and is not the outer region of a combined
+ // construct, create empty blocks for all evaluations.
+ if (eval.lowerAsUnstructured() && !outerCombined)
createEmptyRegionBlocks(firOpBuilder, eval.getNestedEvaluations());
- // Ensure the block is well-formed by inserting terminators.
+ // Insert the terminator.
if constexpr (std::is_same_v<Op, omp::WsLoopOp>) {
mlir::ValueRange results;
firOpBuilder.create<mlir::omp::YieldOp>(loc, results);
@@ -221,6 +223,7 @@ createBodyOfOp(Op &op, Fortran::lower::AbstractConverter &converter,
// Reset the insertion point to the start of the first block.
firOpBuilder.setInsertionPointToStart(&block);
+
// Handle privatization. Do not privatize if this is the outer operation.
if (clauses && !outerCombined)
privatizeVars(converter, *clauses);
diff --git a/flang/test/Lower/OpenMP/omp-unstructured.f90 b/flang/test/Lower/OpenMP/omp-unstructured.f90
index 68f944b91abea..7272d0206f58f 100644
--- a/flang/test/Lower/OpenMP/omp-unstructured.f90
+++ b/flang/test/Lower/OpenMP/omp-unstructured.f90
@@ -105,9 +105,209 @@ subroutine ss3(n) ! nested unstructured OpenMP constructs
!$omp end parallel
end
+! CHECK-LABEL: func @_QPss4{{.*}} {
+! CHECK: omp.parallel {
+! CHECK: omp.wsloop for (%[[ARG:.*]]) : {{.*}} {
+! CHECK: cond_br %{{.*}}, ^bb1, ^bb2
+! CHECK: ^bb1:
+! CHECK: @_FortranAioBeginExternalListOutput
+! CHECK: @_FortranAioOutputInteger32(%{{.*}}, %[[ARG]])
+! CHECK: br ^bb2
+! CHECK: ^bb2:
+! CHECK-NEXT: omp.yield
+! CHECK-NEXT: }
+! CHECK: omp.terminator
+! CHECK-NEXT:}
+subroutine ss4(n) ! CYCLE in OpenMP wsloop constructs
+ !$omp parallel
+ do i = 1, 3
+ !$omp do
+ do j = 1, 3
+ if (j .eq. n) cycle
+ print*, 'ss4', j
+ enddo
+ !$omp end do
+ enddo
+ !$omp end parallel
+end
+
+! CHECK-LABEL: func @_QPss5() {
+! CHECK: omp.parallel {
+! CHECK: omp.wsloop {{.*}} {
+! CHECK: br ^[[BB1:.*]]
+! CHECK: ^[[BB1]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB4:.*]]
+! CHECK: ^[[BB2]]:
+! CHECK: cond_br %{{.*}}, ^[[BB4]], ^[[BB3:.*]]
+! CHECK: ^[[BB3]]:
+! CHECK: br ^[[BB1]]
+! CHECK: ^[[BB4]]:
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+subroutine ss5() ! EXIT inside OpenMP wsloop (inside parallel)
+ integer :: x
+ !$omp parallel private(x)
+ !$omp do
+ do j = 1, 3
+ x = j * i
+ do k = 1, 3
+ if (k .eq. n) exit
+ x = k
+ x = x + k
+ enddo
+ x = j - 222
+ enddo
+ !$omp end do
+ !$omp end parallel
+end
+
+! CHECK-LABEL: func @_QPss6() {
+! CHECK: omp.parallel {
+! CHECK: br ^[[BB1_OUTER:.*]]
+! CHECK: ^[[BB1_OUTER]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]]
+! CHECK: ^[[BB2_OUTER]]:
+! CHECK: omp.wsloop {{.*}} {
+! CHECK: br ^[[BB1:.*]]
+! CHECK: ^[[BB1]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB4:.*]]
+! CHECK: ^[[BB2]]:
+! CHECK: cond_br %{{.*}}, ^[[BB4]], ^[[BB3:.*]]
+! CHECK: ^[[BB3]]:
+! CHECK: br ^[[BB1]]
+! CHECK: ^[[BB4]]:
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: br ^[[BB1_OUTER]]
+! CHECK: ^[[BB3_OUTER]]:
+! CHECK: omp.terminator
+! CHECK: }
+subroutine ss6() ! EXIT inside OpenMP wsloop in a do loop (inside parallel)
+ integer :: x
+ !$omp parallel private(x)
+ do i = 1, 3
+ !$omp do
+ do j = 1, 3
+ x = j * i
+ do k = 1, 3
+ if (k .eq. n) exit
+ x = k
+ x = x + k
+ enddo
+ x = j - 222
+ enddo
+ !$omp end do
+ enddo
+ !$omp end parallel
+end
+
+! CHECK-LABEL: func @_QPss7() {
+! CHECK: br ^[[BB1_OUTER:.*]]
+! CHECK: ^[[BB1_OUTER]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2_OUTER:.*]], ^[[BB3_OUTER:.*]]
+! CHECK-NEXT: ^[[BB2_OUTER:.*]]:
+! CHECK: omp.parallel {
+! CHECK: omp.wsloop {{.*}} {
+! CHECK: br ^[[BB1:.*]]
+! CHECK-NEXT: ^[[BB1]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB4:.*]]
+! CHECK-NEXT: ^[[BB2]]:
+! CHECK: cond_br %{{.*}}, ^[[BB4]], ^[[BB3:.*]]
+! CHECK-NEXT: ^[[BB3]]:
+! CHECK: br ^bb1
+! CHECK-NEXT: ^[[BB4]]:
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+! CHECK: br ^[[BB1_OUTER]]
+! CHECK-NEXT: ^[[BB3_OUTER]]:
+! CHECK-NEXT: return
+subroutine ss7() ! EXIT inside OpenMP parallel do (inside do loop)
+ integer :: x
+ do i = 1, 3
+ !$omp parallel do private(x)
+ do j = 1, 3
+ x = j * i
+ do k = 1, 3
+ if (k .eq. n) exit
+ x = k
+ x = x + k
+ enddo
+ enddo
+ !$omp end parallel do
+ enddo
+end
+
+! CHECK-LABEL: func @_QPss8() {
+! CHECK: omp.parallel {
+! CHECK: omp.wsloop {{.*}} {
+! CHECK: br ^[[BB1:.*]]
+! CHECK: ^[[BB1]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB4:.*]]
+! CHECK: ^[[BB2]]:
+! CHECK: cond_br %{{.*}}, ^[[BB4]], ^[[BB3:.*]]
+! CHECK: ^[[BB3]]:
+! CHECK: br ^[[BB1]]
+! CHECK: ^[[BB4]]:
+! CHECK: omp.yield
+! CHECK: }
+! CHECK: omp.terminator
+! CHECK: }
+subroutine ss8() ! EXIT inside OpenMP parallel do
+ integer :: x
+ !$omp parallel do private(x)
+ do j = 1, 3
+ x = j * i
+ do k = 1, 3
+ if (k .eq. n) exit
+ x = k
+ x = x + k
+ enddo
+ enddo
+ !$omp end parallel do
+end
+
+! CHECK-LABEL: func @_QPss9() {
+! CHECK: omp.parallel {
+! CHECK-NEXT: omp.parallel {
+! CHECK: br ^[[BB1:.*]]
+! CHECK: ^[[BB1]]:
+! CHECK: cond_br %{{.*}}, ^[[BB2:.*]], ^[[BB4:.*]]
+! CHECK-NEXT: ^[[BB2]]:
+! CHECK: cond_br %{{.*}}, ^[[BB4]], ^[[BB3:.*]]
+! CHECK-NEXT: ^[[BB3]]:
+! CHECK: br ^[[BB1]]
+! CHECK-NEXT: ^[[BB4]]:
+! CHECK: omp.terminator
+! CHECK-NEXT: }
+! CHECK: omp.terminator
+! CHECK-NEXT }
+! CHECK: }
+subroutine ss9() ! EXIT inside OpenMP parallel (inside parallel)
+ integer :: x
+ !$omp parallel
+ !$omp parallel private(x)
+ do k = 1, 3
+ if (k .eq. n) exit
+ x = k
+ x = x + k
+ end do
+ !$omp end parallel
+ !$omp end parallel
+end
+
! CHECK-LABEL: func @_QQmain
program p
call ss1(2)
call ss2(2)
call ss3(2)
+ call ss4(2)
+ call ss5()
+ call ss6()
+ call ss7()
+ call ss8()
+ call ss9()
end
More information about the flang-commits
mailing list