This patch modifies the representation of `OpenMP_Clause` to allow definitions to incorporate both required and optional arguments while still allowing operations including them and overriding the `assemblyFormat` to take advantage of automatically-populated format strings. The proposed approach is to split the `assemblyFormat` clause property into `reqAssemblyFormat` and `optAssemblyFormat`, and remove the `isRequired` template and associated `required` property. The `OpenMP_Op` class, in turn, populates the new `clausesReqAssemblyFormat` and `clausesOptAssemblyFormat` properties in addition to `clausesAssemblyFormat`. These properties can be used by clause-based OpenMP operation definitions to reconstruct parts of the clause-inherited format string in a more flexible way when overriding it. Clause definitions are updated to follow this new approach and some operation definitions overriding the `assemblyFormat` are simplified by taking advantage of the improved flexibility, reducing code duplication. The `verify-openmp-ops` tablegen pass is updated for the new `OpenMP_Clause` representation. Some MLIR and Flang unit tests had to be updated due to changes to the default printing order of clauses on updated operations.
82 lines
3.5 KiB
Fortran
82 lines
3.5 KiB
Fortran
! This test checks lowering of OpenMP DO Directive (Worksharing).
|
|
|
|
! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck %s
|
|
|
|
!CHECK-LABEL: func @_QPsimple_loop()
|
|
subroutine simple_loop
|
|
integer :: i
|
|
! CHECK: omp.parallel
|
|
!$OMP PARALLEL
|
|
! CHECK: %[[ALLOCA_IV:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}}
|
|
! CHECK: %[[IV_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_IV]] {uniq_name = "_QFsimple_loopEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
|
! CHECK: %[[WS_LB:.*]] = arith.constant 1 : i32
|
|
! CHECK: %[[WS_UB:.*]] = arith.constant 9 : i32
|
|
! CHECK: %[[WS_STEP:.*]] = arith.constant 1 : i32
|
|
! CHECK: omp.wsloop {
|
|
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB]]) to (%[[WS_UB]]) inclusive step (%[[WS_STEP]]) {
|
|
!$OMP DO
|
|
do i=1, 9
|
|
! CHECK: fir.store %[[I]] to %[[IV_DECL:.*]]#1 : !fir.ref<i32>
|
|
! CHECK: %[[LOAD_IV:.*]] = fir.load %[[IV_DECL]]#0 : !fir.ref<i32>
|
|
! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LOAD_IV]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
|
|
print*, i
|
|
end do
|
|
! CHECK: omp.yield
|
|
! CHECK: omp.terminator
|
|
!$OMP END DO
|
|
! CHECK: omp.terminator
|
|
!$OMP END PARALLEL
|
|
end subroutine
|
|
|
|
!CHECK-LABEL: func @_QPsimple_loop_with_step()
|
|
subroutine simple_loop_with_step
|
|
integer :: i
|
|
! CHECK: omp.parallel
|
|
!$OMP PARALLEL
|
|
! CHECK: %[[ALLOCA_IV:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}}
|
|
! CHECK: %[[IV_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_IV]] {uniq_name = "_QFsimple_loop_with_stepEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
|
! CHECK: %[[WS_LB:.*]] = arith.constant 1 : i32
|
|
! CHECK: %[[WS_UB:.*]] = arith.constant 9 : i32
|
|
! CHECK: %[[WS_STEP:.*]] = arith.constant 2 : i32
|
|
! CHECK: omp.wsloop {
|
|
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB]]) to (%[[WS_UB]]) inclusive step (%[[WS_STEP]]) {
|
|
! CHECK: fir.store %[[I]] to %[[IV_DECL]]#1 : !fir.ref<i32>
|
|
! CHECK: %[[LOAD_IV:.*]] = fir.load %[[IV_DECL]]#0 : !fir.ref<i32>
|
|
!$OMP DO
|
|
do i=1, 9, 2
|
|
! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LOAD_IV]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
|
|
print*, i
|
|
end do
|
|
! CHECK: omp.yield
|
|
! CHECK: omp.terminator
|
|
!$OMP END DO
|
|
! CHECK: omp.terminator
|
|
!$OMP END PARALLEL
|
|
end subroutine
|
|
|
|
!CHECK-LABEL: func @_QPloop_with_schedule_nowait()
|
|
subroutine loop_with_schedule_nowait
|
|
integer :: i
|
|
! CHECK: omp.parallel
|
|
!$OMP PARALLEL
|
|
! CHECK: %[[ALLOCA_IV:.*]] = fir.alloca i32 {{{.*}}, pinned, {{.*}}}
|
|
! CHECK: %[[IV_DECL:.*]]:2 = hlfir.declare %[[ALLOCA_IV]] {uniq_name = "_QFloop_with_schedule_nowaitEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
|
! CHECK: %[[WS_LB:.*]] = arith.constant 1 : i32
|
|
! CHECK: %[[WS_UB:.*]] = arith.constant 9 : i32
|
|
! CHECK: %[[WS_STEP:.*]] = arith.constant 1 : i32
|
|
! CHECK: omp.wsloop nowait schedule(runtime) {
|
|
! CHECK-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[WS_LB]]) to (%[[WS_UB]]) inclusive step (%[[WS_STEP]]) {
|
|
!$OMP DO SCHEDULE(runtime)
|
|
do i=1, 9
|
|
! CHECK: fir.store %[[I]] to %[[IV_DECL]]#1 : !fir.ref<i32>
|
|
! CHECK: %[[LOAD_IV:.*]] = fir.load %[[IV_DECL]]#0 : !fir.ref<i32>
|
|
! CHECK: fir.call @_FortranAioOutputInteger32({{.*}}, %[[LOAD_IV]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
|
|
print*, i
|
|
end do
|
|
! CHECK: omp.yield
|
|
! CHECK: omp.terminator
|
|
!$OMP END DO NOWAIT
|
|
! CHECK: omp.terminator
|
|
!$OMP END PARALLEL
|
|
end subroutine
|