This patch changes two things:
1. We do not need to use the loop counter's last value
for regular do-loops in Lowering.
2. The loop counter's increment is implied by fir.do_loop
operation, so there is no need to increment it explicitly.
The last point has been especially confusing to me, because it was
unclear why we have an explicit increment if it is implied.
It looks like CFGConversion somehow still makes the final code
correct, i.e. the counter is not incremented twice.
Anyway, the new lowering should look more concise.
121 lines
4.2 KiB
Fortran
121 lines
4.2 KiB
Fortran
! RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
|
|
! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
|
|
|
|
! --- Check that with shared(i) the variable outside the parallel section
|
|
! --- is updated.
|
|
! CHECK-LABEL: func.func @_QPomploop()
|
|
! CHECK: %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploopEi"}
|
|
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploopEi"} :
|
|
! CHECK: omp.parallel {
|
|
! CHECK: omp.sections {
|
|
! CHECK: omp.section {
|
|
! CHECK: %[[RES:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
|
|
! CHECK: fir.store %[[ARG1]] to %[[DECL_I]]#0
|
|
! CHECK: hlfir.assign
|
|
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_I]]#0
|
|
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
|
|
! CHECK: fir.result %[[RES_I]]
|
|
! CHECK: }
|
|
! CHECK: fir.store %[[RES]] to %[[DECL_I]]#0
|
|
! CHECK: omp.terminator
|
|
! CHECK: }
|
|
! CHECK: omp.terminator
|
|
! CHECK: }
|
|
! CHECK: return
|
|
! CHECK: }
|
|
subroutine omploop
|
|
implicit none
|
|
integer :: i, j
|
|
i = 1
|
|
j = 0
|
|
!$omp parallel shared(i)
|
|
!$omp sections
|
|
do i=1,10
|
|
j = j + i
|
|
end do
|
|
!$omp end sections
|
|
!$omp end parallel
|
|
end subroutine
|
|
|
|
! --- Check that with default(shared) the variable outside the parallel section
|
|
! --- is NOT updated (i is private to the omp.parallel code)
|
|
! CHECK-LABEL: func.func @_QPomploop2()
|
|
! CHECK: %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploop2Ei"}
|
|
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploop2Ei"} :
|
|
! CHECK: omp.parallel {
|
|
! CHECK: %[[ALLOC_PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned}
|
|
! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
|
|
! CHECK: omp.sections {
|
|
! CHECK: omp.section {
|
|
! CHECK: %[[RES:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
|
|
! CHECK-NOT: fir.store %[[ARG1]] to %[[DECL_I]]#1
|
|
! CHECK: fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#0
|
|
! CHECK: hlfir.assign
|
|
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#0
|
|
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
|
|
! CHECK: fir.result %[[RES_I]]
|
|
! CHECK: }
|
|
! CHECK: fir.store %[[RES]] to %[[DECL_PRIV_I]]#0
|
|
! CHECK: omp.terminator
|
|
! CHECK: }
|
|
! CHECK: omp.terminator
|
|
! CHECK: }
|
|
! CHECK: return
|
|
! CHECK: }
|
|
subroutine omploop2
|
|
implicit none
|
|
integer :: i, j
|
|
i = 1
|
|
j = 0
|
|
!$omp parallel default(shared)
|
|
!$omp sections
|
|
do i=1,10
|
|
j = j + i
|
|
end do
|
|
!$omp end sections
|
|
!$omp end parallel
|
|
end subroutine
|
|
|
|
|
|
! --- Check that with no data-sharing the variable outside the parallel section
|
|
! --- is NOT updated (i is private to the omp.parallel code)
|
|
! CHECK-LABEL: func.func @_QPomploop3()
|
|
! CHECK: %[[ALLOC_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomploop3Ei"}
|
|
! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOC_I]] {uniq_name = "_QFomploop3Ei"} :
|
|
! CHECK: omp.parallel {
|
|
! CHECK: %[[ALLOC_PRIV_I:.*]] = fir.alloca i32 {bindc_name = "i", pinned}
|
|
! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
|
|
! CHECK: omp.sections {
|
|
! CHECK: omp.section {
|
|
! CHECK: %[[RES:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
|
|
! CHECK-NOT: fir.store %[[ARG1]] to %[[DECL_I]]#1
|
|
! CHECK: fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#0
|
|
! CHECK: hlfir.assign
|
|
! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#0
|
|
! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
|
|
! CHECK: fir.result %[[RES_I]]
|
|
! CHECK: }
|
|
! CHECK: fir.store %[[RES]] to %[[DECL_PRIV_I]]#0
|
|
! CHECK: omp.terminator
|
|
! CHECK: }
|
|
! CHECK: omp.terminator
|
|
! CHECK: }
|
|
! CHECK: return
|
|
! CHECK: }
|
|
subroutine omploop3
|
|
implicit none
|
|
integer :: i, j
|
|
i = 1
|
|
j = 0
|
|
!$omp parallel
|
|
!$omp sections
|
|
do i=1,10
|
|
j = j + i
|
|
end do
|
|
!$omp end sections
|
|
!$omp end parallel
|
|
end subroutine
|
|
|
|
|
|
|