[Flang][OpenMP] Move char box bounds generation for Maps to DirectiveCommons.h (#165918)

Currently we generate these bounds in the MapInfoFinalization.cpp pass
as it seems there's a missing case for character strings/arrays (length
parameter) in the DirectiveCommons bounds generation functionality
OpenMP uses for it's map operations.

This PR tries to add this case to the DirectiveCommons function and
remove the need for the bounds generation in the MapInfoFinalization
pass, so that we are generating the bounds in the same place most other
bounds are generated.
This commit is contained in:
agozillon 2025-11-10 19:57:53 +01:00 committed by GitHub
parent b7423af8da
commit 08222caf28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 34 deletions

View File

@ -512,11 +512,19 @@ fir::factory::AddrAndBoundsInfo gatherDataOperandAddrAndBounds(
}
bool dataExvIsAssumedSize =
Fortran::semantics::IsAssumedSizeArray(symRef->get().GetUltimate());
if (genDefaultBounds &&
mlir::isa<fir::SequenceType>(fir::unwrapRefType(info.addr.getType())))
if (genDefaultBounds && mlir::isa<fir::SequenceType>(
fir::unwrapRefType(info.addr.getType()))) {
bounds = fir::factory::genBaseBoundsOps<BoundsOp, BoundsType>(
builder, operandLocation, dataExv, dataExvIsAssumedSize,
strideIncludeLowerExtent);
}
if (genDefaultBounds && fir::characterWithDynamicLen(
fir::unwrapRefType(info.addr.getType())) ||
mlir::isa<fir::BoxCharType>(
fir::unwrapRefType(info.addr.getType()))) {
bounds = {fir::factory::genBoundsOpFromBoxChar<BoundsOp, BoundsType>(
builder, operandLocation, dataExv, info)};
}
asFortran << symRef->get().name().ToString();
} else { // Unsupported
llvm::report_fatal_error("Unsupported type of OpenACC operand");

View File

@ -943,38 +943,6 @@ class MapInfoFinalizationPass
localBoxAllocas.clear();
deferrableDesc.clear();
// First, walk `omp.map.info` ops to see if any of them have varPtrs
// with an underlying type of fir.char<k, ?>, i.e a character
// with dynamic length. If so, check if they need bounds added.
func->walk([&](mlir::omp::MapInfoOp op) {
if (!op.getBounds().empty())
return;
mlir::Value varPtr = op.getVarPtr();
mlir::Type underlyingVarType = fir::unwrapRefType(varPtr.getType());
if (!fir::characterWithDynamicLen(underlyingVarType))
return;
fir::factory::AddrAndBoundsInfo info =
fir::factory::getDataOperandBaseAddr(
builder, varPtr, /*isOptional=*/false, varPtr.getLoc());
fir::ExtendedValue extendedValue =
hlfir::translateToExtendedValue(varPtr.getLoc(), builder,
hlfir::Entity{info.addr},
/*continguousHint=*/true)
.first;
builder.setInsertionPoint(op);
llvm::SmallVector<mlir::Value> boundsOps =
fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
mlir::omp::MapBoundsType>(
builder, info, extendedValue,
/*dataExvIsAssumedSize=*/false, varPtr.getLoc());
op.getBoundsMutable().append(boundsOps);
});
// Next, walk `omp.map.info` ops to see if any record members should be
// implicitly mapped.
func->walk([&](mlir::omp::MapInfoOp op) {

View File

@ -0,0 +1,19 @@
! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
subroutine TestCharLenBounds(clen)
character(len=*) :: clen
!$omp target map(clen)
!$omp end target
end subroutine TestCharLenBounds
!CHECK: %[[DUMMY:.*]] = fir.dummy_scope : !fir.dscope
!CHECK: %[[UNBOX:.*]]:2 = fir.unboxchar %{{.*}} : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
!CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[UNBOX]]#0 typeparams %2#1 dummy_scope %[[DUMMY]] {uniq_name = "_QFtestcharlenboundsEclen"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
!CHECK: %[[LB_START_IDX:.*]] = arith.constant 0 : index
!CHECK: %[[STRIDE:.*]] = arith.constant 1 : index
!CHECK: %[[EXTENT:.*]]:2 = fir.unboxchar %[[DECLARE]]#0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
!CHECK: %[[UB:.*]] = arith.subi %[[EXTENT]]#1, %[[STRIDE]] : index
!CHECK: %[[BOUNDS:.*]] = omp.map.bounds lower_bound(%[[LB_START_IDX]] : index) upper_bound(%[[UB]] : index) extent(%[[EXTENT]]#1 : index) stride(%[[STRIDE]] : index) start_idx(%[[LB_START_IDX]] : index) {stride_in_bytes = true}
!CHECK: %{{.*}} = omp.map.info {{.*}} bounds(%[[BOUNDS]]) {{.*}}