Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions flang/include/flang/Optimizer/OpenMP/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
#ifndef FORTRAN_OPTIMIZER_OPENMP_UTILS_H
#define FORTRAN_OPTIMIZER_OPENMP_UTILS_H

#include "flang/Optimizer/Builder/BoxValue.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't BoxValue.h move to flang/Optimizer/Support?

#include "flang/Optimizer/Builder/DirectivesCommon.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Dialect/FIRType.h"

#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/IR/Value.h"

#include "llvm/ADT/SmallVector.h"

namespace flangomp {

enum class DoConcurrentMappingKind {
Expand All @@ -21,6 +32,35 @@ enum class DoConcurrentMappingKind {
DCMK_Device ///< Lower to run in parallel on the GPU.
};

/// Return true if the variable has a dynamic size and therefore requires
/// bounds operations to describe its extents.
inline bool needsBoundsOps(mlir::Value var) {
assert(mlir::isa<mlir::omp::PointerLikeType>(var.getType()) &&
"needsBoundsOps can deal only with pointer types");
mlir::Type t = fir::unwrapRefType(var.getType());
if (mlir::Type inner = fir::dyn_cast_ptrOrBoxEleTy(t))
return fir::hasDynamicSize(inner);
return fir::hasDynamicSize(t);
}

/// Generate MapBoundsOp operations for the variable and append them to
/// `boundsOps`.
inline llvm::SmallVector<mlir::Value> genBoundsOps(fir::FirOpBuilder &builder,
mlir::Value var,
bool isAssumedSize = false,
bool isOptional = false) {
mlir::Location loc = var.getLoc();
fir::factory::AddrAndBoundsInfo info =
fir::factory::getDataOperandBaseAddr(builder, var, isOptional, loc);
fir::ExtendedValue exv =
hlfir::translateToExtendedValue(loc, builder, hlfir::Entity{info.addr},
/*contiguousHint=*/true)
.first;
return fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
mlir::omp::MapBoundsType>(
builder, info, exv, isAssumedSize, loc);
}

} // namespace flangomp

#endif // FORTRAN_OPTIMIZER_OPENMP_UTILS_H
11 changes: 5 additions & 6 deletions flang/lib/Lower/OpenMP/OpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/OpenMP/Utils.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree.h"
Expand Down Expand Up @@ -2495,12 +2496,10 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
Fortran::lower::getDataOperandBaseAddr(
converter, firOpBuilder, sym.GetUltimate(),
converter.getCurrentLocation());
llvm::SmallVector<mlir::Value> bounds =
fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
mlir::omp::MapBoundsType>(
firOpBuilder, info, dataExv,
semantics::IsAssumedSizeArray(sym.GetUltimate()),
converter.getCurrentLocation());
llvm::SmallVector<mlir::Value> bounds = flangomp::genBoundsOps(
firOpBuilder, info.rawInput,
semantics::IsAssumedSizeArray(sym.GetUltimate()),
semantics::IsOptional(sym.GetUltimate()));
mlir::Value baseOp = info.rawInput;
mlir::Type eleType = baseOp.getType();
if (auto refType = mlir::dyn_cast<fir::ReferenceType>(baseOp.getType()))
Expand Down
1 change: 0 additions & 1 deletion flang/lib/Optimizer/Builder/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS)

add_flang_library(FIRBuilder
BoxValue.cpp
Character.cpp
Complex.cpp
CUFCommon.cpp
Expand Down
35 changes: 3 additions & 32 deletions flang/lib/Optimizer/OpenMP/AutomapToTargetData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/OpenMP/Utils.h"

#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
Expand All @@ -33,36 +34,6 @@ namespace {
class AutomapToTargetDataPass
: public flangomp::impl::AutomapToTargetDataPassBase<
AutomapToTargetDataPass> {

// Returns true if the variable has a dynamic size and therefore requires
// bounds operations to describe its extents.
inline bool needsBoundsOps(mlir::Value var) {
assert(mlir::isa<mlir::omp::PointerLikeType>(var.getType()) &&
"only pointer like types expected");
mlir::Type t = fir::unwrapRefType(var.getType());
if (mlir::Type inner = fir::dyn_cast_ptrOrBoxEleTy(t))
return fir::hasDynamicSize(inner);
return fir::hasDynamicSize(t);
}

// Generate MapBoundsOp operations for the variable if required.
inline void genBoundsOps(fir::FirOpBuilder &builder, mlir::Value var,
llvm::SmallVectorImpl<mlir::Value> &boundsOps) {
mlir::Location loc = var.getLoc();
fir::factory::AddrAndBoundsInfo info =
fir::factory::getDataOperandBaseAddr(builder, var,
/*isOptional=*/false, loc);
fir::ExtendedValue exv =
hlfir::translateToExtendedValue(loc, builder, hlfir::Entity{info.addr},
/*contiguousHint=*/true)
.first;
llvm::SmallVector<mlir::Value> tmp =
fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
mlir::omp::MapBoundsType>(
builder, info, exv, /*dataExvIsAssumedSize=*/false, loc);
llvm::append_range(boundsOps, tmp);
}

void findRelatedAllocmemFreemem(fir::AddrOfOp addressOfOp,
llvm::DenseSet<fir::StoreOp> &allocmems,
llvm::DenseSet<fir::LoadOp> &freemems) {
Expand Down Expand Up @@ -112,8 +83,8 @@ class AutomapToTargetDataPass
auto addMapInfo = [&](auto globalOp, auto memOp) {
builder.setInsertionPointAfter(memOp);
SmallVector<Value> bounds;
if (needsBoundsOps(memOp.getMemref()))
genBoundsOps(builder, memOp.getMemref(), bounds);
if (flangomp::needsBoundsOps(memOp.getMemref()))
bounds = flangomp::genBoundsOps(builder, memOp.getMemref());

omp::TargetEnterExitUpdateDataOperands clauses;
mlir::omp::MapInfoOp mapInfo = mlir::omp::MapInfoOp::create(
Expand Down
38 changes: 3 additions & 35 deletions flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/OpenMP/Utils.h"

#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
Expand Down Expand Up @@ -106,8 +107,8 @@ class MapsForPrivatizedSymbolsPass
// Figure out the bounds because knowing the bounds will help the subsequent
// MapInfoFinalizationPass map the underlying data of the descriptor.
llvm::SmallVector<mlir::Value> boundsOps;
if (needsBoundsOps(varPtr))
genBoundsOps(builder, varPtr, boundsOps);
if (flangomp::needsBoundsOps(varPtr))
boundsOps = flangomp::genBoundsOps(builder, varPtr);
Comment on lines +110 to +111
Copy link
Preview

Copilot AI Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function call assignment changes the API contract. The old code appended to an existing vector via reference parameter, while the new code returns a new vector. This could impact performance if boundsOps already contains elements, as they would be overwritten rather than appended to.

Copilot uses AI. Check for mistakes.


mlir::omp::VariableCaptureKind captureKind =
mlir::omp::VariableCaptureKind::ByRef;
Expand Down Expand Up @@ -194,38 +195,5 @@ class MapsForPrivatizedSymbolsPass
}
}
}
// As the name suggests, this function examines var to determine if
// it has dynamic size. If true, this pass'll have to extract these
// bounds from descriptor of var and add the bounds to the resultant
// MapInfoOp.
bool needsBoundsOps(mlir::Value var) {
assert(mlir::isa<omp::PointerLikeType>(var.getType()) &&
"needsBoundsOps can deal only with pointer types");
mlir::Type t = fir::unwrapRefType(var.getType());
// t could be a box, so look inside the box
auto innerType = fir::dyn_cast_ptrOrBoxEleTy(t);
if (innerType)
return fir::hasDynamicSize(innerType);
return fir::hasDynamicSize(t);
}

void genBoundsOps(fir::FirOpBuilder &builder, mlir::Value var,
llvm::SmallVector<mlir::Value> &boundsOps) {
mlir::Location loc = var.getLoc();
fir::factory::AddrAndBoundsInfo info =
fir::factory::getDataOperandBaseAddr(builder, var,
/*isOptional=*/false, loc);
fir::ExtendedValue extendedValue =
hlfir::translateToExtendedValue(loc, builder, hlfir::Entity{info.addr},
/*continguousHint=*/true)
.first;
llvm::SmallVector<mlir::Value> boundsOpsVec =
fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
mlir::omp::MapBoundsType>(
builder, info, extendedValue,
/*dataExvIsAssumedSize=*/false, loc);
for (auto bounds : boundsOpsVec)
boundsOps.push_back(bounds);
}
};
} // namespace
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//

#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "mlir/IR/BuiltinTypes.h"
#include "llvm/Support/Debug.h"
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Optimizer/Support/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_flang_library(FIRSupport
BoxValue.cpp
DataLayout.cpp
InitFIR.cpp
InternalNames.cpp
Expand Down
Loading