diff --git a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp index e823443958714..c63d2f4531a6f 100644 --- a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp +++ b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp @@ -66,10 +66,12 @@ class MapInfoFinalizationPass /// Tracks any intermediate function/subroutine local allocations we /// generate for the descriptors of box type dummy arguments, so that /// we can retrieve it for subsequent reuses within the functions - /// scope - std::map - localBoxAllocas; + /// scope. + /// + /// descriptor defining op + /// | corresponding local alloca + /// | | + std::map localBoxAllocas; /// getMemberUserList gathers all users of a particular MapInfoOp that are /// other MapInfoOp's and places them into the mapMemberUsers list, which @@ -132,6 +134,11 @@ class MapInfoFinalizationPass if (!mlir::isa(descriptor.getType())) return descriptor; + mlir::Value &slot = localBoxAllocas[descriptor.getDefiningOp()]; + if (slot) { + return slot; + } + // The fir::BoxOffsetOp only works with !fir.ref> types, as // allowing it to access non-reference box operations can cause some // problematic SSA IR. However, in the case of assumed shape's the type @@ -147,7 +154,7 @@ class MapInfoFinalizationPass auto alloca = builder.create(loc, descriptor.getType()); builder.restoreInsertionPoint(insPt); builder.create(loc, descriptor, alloca); - return alloca; + return slot = alloca; } /// Function that generates a FIR operation accessing the descriptor's diff --git a/flang/test/Transforms/omp-map-info-finalization.fir b/flang/test/Transforms/omp-map-info-finalization.fir index 19e6dcad068cd..a7254bcddd523 100644 --- a/flang/test/Transforms/omp-map-info-finalization.fir +++ b/flang/test/Transforms/omp-map-info-finalization.fir @@ -296,3 +296,49 @@ func.func @alloca_dtype_map_op_block_add(%arg0 : !fir.ref>>>, !fir.box>>) map_clauses(to) capture(ByRef) -> !fir.ref>>> {{.*}} // CHECK: %[[TOP_PARENT_MAP:.*]] = omp.map.info var_ptr(%0#1 : !fir.ref>, !fir.type<[[REC_TY]]>) map_clauses(exit_release_or_enter_alloc) capture(ByRef) members(%6, %5, %14, %13 : [1], [1, 0], [1, 0, 2], [1, 0, 2, 0] : !fir.ref>>>>, !fir.llvm_ptr>>>, !fir.ref>>>, !fir.llvm_ptr>>) -> !fir.ref> {{{.*}} partial_map = true} // CHECK: omp.target map_entries(%[[TOP_PARENT_MAP]] -> %{{.*}}, %[[DESC_MAP_1]] -> %{{.*}}, %[[BASE_ADDR_MAP_1]] -> %{{.*}}, %[[DESC_MAP_2]] -> %{{.*}}, %[[BASE_ADDR_MAP_2]] -> %{{.*}} : !fir.ref>, !fir.ref>>>>, !fir.llvm_ptr>>>, !fir.ref>>>, !fir.llvm_ptr>>) { + +// ----- + +func.func @_QPreuse_alloca(%arg0: !fir.box> {fir.bindc_name = "a"}) { + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFreuse_allocaEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %c1 = arith.constant 1 : index + %c0 = arith.constant 0 : index + %2:3 = fir.box_dims %1#0, %c0 : (!fir.box>, index) -> (index, index, index) + %c0_0 = arith.constant 0 : index + %3 = arith.subi %2#1, %c1 : index + %4 = omp.map.bounds lower_bound(%c0_0 : index) upper_bound(%3 : index) extent(%2#1 : index) stride(%2#2 : index) start_idx(%c1 : index) {stride_in_bytes = true} + %5 = fir.box_addr %1#1 : (!fir.box>) -> !fir.ref> + %6 = omp.map.info var_ptr(%5 : !fir.ref>, f64) map_clauses(to) capture(ByRef) bounds(%4) -> !fir.ref> {name = "a"} + omp.target_data map_entries(%6 : !fir.ref>) { + %cst = arith.constant 0.000000e+00 : f64 + %c0_1 = arith.constant 0 : index + %7 = hlfir.designate %1#0 (%c0_1) : (!fir.box>, index) -> !fir.ref + hlfir.assign %cst to %7 : f64, !fir.ref + %c1_2 = arith.constant 1 : index + %c0_3 = arith.constant 0 : index + %8:3 = fir.box_dims %1#0, %c0_3 : (!fir.box>, index) -> (index, index, index) + %c0_4 = arith.constant 0 : index + %9 = arith.subi %8#1, %c1_2 : index + %10 = omp.map.bounds lower_bound(%c0_4 : index) upper_bound(%9 : index) extent(%8#1 : index) stride(%8#2 : index) start_idx(%c1_2 : index) {stride_in_bytes = true} + %11 = fir.box_addr %1#1 : (!fir.box>) -> !fir.ref> + %12 = omp.map.info var_ptr(%11 : !fir.ref>, f64) map_clauses(from) capture(ByRef) bounds(%10) -> !fir.ref> {name = "a"} + omp.target_update map_entries(%12 : !fir.ref>) + omp.terminator + } + return +} + +// CHECK-LABEL: @_QPreuse_alloca +// CHECK-NEXT: %[[ALLOCA:[0-9]+]] = fir.alloca !fir.box> +// CHECK-NOT: fir.alloca +// CHECK: %{{[0-9]+}} = omp.map.info var_ptr(%[[ALLOCA]] +// CHECK: %{{[0-9]+}} = omp.map.info var_ptr(%[[ALLOCA]] +// CHECK: omp.target_data map_entries +// CHECK: %{{[0-9]+}} = omp.map.info var_ptr(%[[ALLOCA]] +// CHECK: %{{[0-9]+}} = omp.map.info var_ptr(%[[ALLOCA]] +// CHECK: omp.target_update map_entries +// CHECK: omp.terminator +// CHECK: } +// CHECK: return +