From 3cfa870104837b604b198ed9005ad82e03d79e81 Mon Sep 17 00:00:00 2001 From: ergawy Date: Wed, 4 Jun 2025 08:51:46 -0500 Subject: [PATCH 1/2] [flang][OpenMP] Extend locality spec to OMP claues (`init` and `dealloc` regions) Extends support for locality specifier to OpenMP translation by adding supprot for transling localizers that have `init` and `dealloc` regions. --- .../OpenMP/DoConcurrentConversion.cpp | 29 +++++++++-- .../locality_specifiers_init_dealloc.mlir | 51 +++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir diff --git a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp index 283c3052c166c..28f6c8bf02813 100644 --- a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp +++ b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp @@ -326,16 +326,37 @@ class DoConcurrentConversion TODO(localizer.getLoc(), "local_init conversion is not supported yet"); - if (!localizer.getInitRegion().empty()) - TODO(localizer.getLoc(), - "non-empty `init` regions are not supported yet"); - auto oldIP = rewriter.saveInsertionPoint(); rewriter.setInsertionPointAfter(localizer); auto privatizer = rewriter.create( localizer.getLoc(), sym.getLeafReference().str() + ".omp", localizer.getTypeAttr().getValue(), mlir::omp::DataSharingClauseType::Private); + + if (!localizer.getInitRegion().empty()) { + rewriter.cloneRegionBefore(localizer.getInitRegion(), + privatizer.getInitRegion(), + privatizer.getInitRegion().begin()); + auto firYield = mlir::cast( + privatizer.getInitRegion().back().getTerminator()); + rewriter.setInsertionPoint(firYield); + rewriter.create(firYield.getLoc(), + firYield.getOperands()); + rewriter.eraseOp(firYield); + } + + if (!localizer.getDeallocRegion().empty()) { + rewriter.cloneRegionBefore(localizer.getDeallocRegion(), + privatizer.getDeallocRegion(), + privatizer.getDeallocRegion().begin()); + auto firYield = mlir::cast( + privatizer.getDeallocRegion().back().getTerminator()); + rewriter.setInsertionPoint(firYield); + rewriter.create(firYield.getLoc(), + firYield.getOperands()); + rewriter.eraseOp(firYield); + } + rewriter.restoreInsertionPoint(oldIP); wsloopClauseOps.privateVars.push_back(op); diff --git a/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir b/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir new file mode 100644 index 0000000000000..a82d8d1715f56 --- /dev/null +++ b/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir @@ -0,0 +1,51 @@ +// Tests mapping `local` locality specifier to `private` clauses for non-empty +// `init` and `dealloc` regions. + +// RUN: fir-opt --omp-do-concurrent-conversion="map-to=host" %s | FileCheck %s + +func.func @my_allocator() { + return +} + +func.func @my_deallocator() { + return +} + +fir.local {type = local} @_QFlocal_assocEaa_private_box_10xf32 : !fir.box> init { +^bb0(%arg0: !fir.ref>>, %arg1: !fir.ref>>): + fir.call @my_allocator() : () -> () + fir.yield(%arg1 : !fir.ref>>) +} dealloc { +^bb0(%arg0: !fir.ref>>): + fir.call @my_deallocator() : () -> () + fir.yield +} + +func.func @_QPlocal_assoc() { + %0 = fir.alloca !fir.box> + %c1 = arith.constant 1 : index + + fir.do_concurrent { + %9 = fir.alloca i32 {bindc_name = "i"} + %10:2 = hlfir.declare %9 {uniq_name = "_QFlocal_assocEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) + fir.do_concurrent.loop (%arg0) = (%c1) to (%c1) step (%c1) local(@_QFlocal_assocEaa_private_box_10xf32 %0 -> %arg1 : !fir.ref>>) { + %11 = fir.convert %arg0 : (index) -> i32 + fir.store %11 to %10#0 : !fir.ref + } + } + + return +} + +// CHECK: omp.private {type = private} @[[PRIVATIZER:.*]] : !fir.box> init { +// CHECK-NEXT: ^bb0(%{{.*}}: !{{.*}}, %{{.*}}: !{{.*}}): +// CHECK-NEXT: fir.call @my_allocator() : () -> () +// CHECK-NEXT: omp.yield(%{{.*}}) +// CHECK-NEXT: } dealloc { +// CHECK-NEXT: ^bb0(%{{.*}}: !{{.*}}): +// CHECK-NEXT: fir.call @my_deallocator() : () -> () +// CHECK-NEXT: omp.yield +// CHECK-NEXT: } + +// CHECK: %[[LOCAL_ALLOC:.*]] = fir.alloca !fir.box> +// CHECK: omp.wsloop private(@[[PRIVATIZER]] %[[LOCAL_ALLOC]] -> %{{.*}} : !{{.*}}) From c818146e251545a620b863cf9085bf568bba81a6 Mon Sep 17 00:00:00 2001 From: ergawy Date: Wed, 11 Jun 2025 04:17:20 -0500 Subject: [PATCH 2/2] review comment, add more test details --- .../locality_specifiers_init_dealloc.mlir | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir b/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir index a82d8d1715f56..1659c7bdf6d3e 100644 --- a/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir +++ b/flang/test/Transforms/DoConcurrent/locality_specifiers_init_dealloc.mlir @@ -3,21 +3,21 @@ // RUN: fir-opt --omp-do-concurrent-conversion="map-to=host" %s | FileCheck %s -func.func @my_allocator() { +func.func @my_allocator(%arg0: !fir.ref>>, %arg1: !fir.ref>>) { return } -func.func @my_deallocator() { +func.func @my_deallocator(%arg0: !fir.ref>>) { return } fir.local {type = local} @_QFlocal_assocEaa_private_box_10xf32 : !fir.box> init { ^bb0(%arg0: !fir.ref>>, %arg1: !fir.ref>>): - fir.call @my_allocator() : () -> () + fir.call @my_allocator(%arg0, %arg1) : (!fir.ref>>, !fir.ref>>) -> () fir.yield(%arg1 : !fir.ref>>) } dealloc { ^bb0(%arg0: !fir.ref>>): - fir.call @my_deallocator() : () -> () + fir.call @my_deallocator(%arg0) : (!fir.ref>>) -> () fir.yield } @@ -38,12 +38,12 @@ func.func @_QPlocal_assoc() { } // CHECK: omp.private {type = private} @[[PRIVATIZER:.*]] : !fir.box> init { -// CHECK-NEXT: ^bb0(%{{.*}}: !{{.*}}, %{{.*}}: !{{.*}}): -// CHECK-NEXT: fir.call @my_allocator() : () -> () -// CHECK-NEXT: omp.yield(%{{.*}}) +// CHECK-NEXT: ^bb0(%[[ORIG_ARG:.*]]: !{{.*}}, %[[PRIV_ARG:.*]]: !{{.*}}): +// CHECK-NEXT: fir.call @my_allocator(%[[ORIG_ARG]], %[[PRIV_ARG]]) : ({{.*}}) -> () +// CHECK-NEXT: omp.yield(%[[PRIV_ARG]] : {{.*}}) // CHECK-NEXT: } dealloc { -// CHECK-NEXT: ^bb0(%{{.*}}: !{{.*}}): -// CHECK-NEXT: fir.call @my_deallocator() : () -> () +// CHECK-NEXT: ^bb0(%[[PRIV_ARG:.*]]: !{{.*}}): +// CHECK-NEXT: fir.call @my_deallocator(%[[PRIV_ARG]]) : ({{.*}}) -> () // CHECK-NEXT: omp.yield // CHECK-NEXT: }