[flang-commits] [flang] [OpenMP]Update use_device_clause lowering (PR #101703)
Sergio Afonso via flang-commits
flang-commits at lists.llvm.org
Wed Aug 21 06:35:16 PDT 2024
================
@@ -692,53 +692,102 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info,
marker->erase();
}
+void mapBodySymbols(lower::AbstractConverter &converter, mlir::Region ®ion,
+ mlir::Block *regionBlock,
+ llvm::ArrayRef<const semantics::Symbol *> mapSyms) {
+ // Clones the `bounds` placing them inside the target region and returns them.
+ auto cloneBound = [&](mlir::Value bound) {
+ if (mlir::isMemoryEffectFree(bound.getDefiningOp())) {
+ mlir::Operation *clonedOp = bound.getDefiningOp()->clone();
+ regionBlock->push_back(clonedOp);
+ return clonedOp->getResult(0);
+ }
+ TODO(converter.getCurrentLocation(),
+ "target map clause operand unsupported bound type");
+ };
+
+ auto cloneBounds = [cloneBound](llvm::ArrayRef<mlir::Value> bounds) {
+ llvm::SmallVector<mlir::Value> clonedBounds;
+ for (mlir::Value bound : bounds)
+ clonedBounds.emplace_back(cloneBound(bound));
+ return clonedBounds;
+ };
+
+ // Bind the symbols to their corresponding block arguments.
+ for (auto [argIndex, argSymbol] : llvm::enumerate(mapSyms)) {
+ const mlir::BlockArgument &arg = region.getArgument(argIndex);
+ // Avoid capture of a reference to a structured binding.
+ const semantics::Symbol *sym = argSymbol;
+ // Structure component symbols don't have bindings.
+ if (sym->owner().IsDerivedType())
+ continue;
+ fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*sym);
+ auto refType = mlir::dyn_cast<fir::ReferenceType>(arg.getType());
+ if (refType && fir::isa_builtin_cptr_type(refType.getElementType())) {
+ converter.bindSymbol(*argSymbol, arg);
+ } else {
+ extVal.match(
+ [&](const fir::BoxValue &v) {
+ converter.bindSymbol(*sym,
+ fir::BoxValue(arg, cloneBounds(v.getLBounds()),
+ v.getExplicitParameters(),
+ v.getExplicitExtents()));
+ },
+ [&](const fir::MutableBoxValue &v) {
+ converter.bindSymbol(
+ *sym, fir::MutableBoxValue(arg, cloneBounds(v.getLBounds()),
+ v.getMutableProperties()));
+ },
+ [&](const fir::ArrayBoxValue &v) {
+ converter.bindSymbol(
+ *sym, fir::ArrayBoxValue(arg, cloneBounds(v.getExtents()),
+ cloneBounds(v.getLBounds()),
+ v.getSourceBox()));
+ },
+ [&](const fir::CharArrayBoxValue &v) {
+ converter.bindSymbol(
+ *sym, fir::CharArrayBoxValue(arg, cloneBound(v.getLen()),
+ cloneBounds(v.getExtents()),
+ cloneBounds(v.getLBounds())));
+ },
+ [&](const fir::CharBoxValue &v) {
+ converter.bindSymbol(
+ *sym, fir::CharBoxValue(arg, cloneBound(v.getLen())));
+ },
+ [&](const fir::UnboxedValue &v) { converter.bindSymbol(*sym, arg); },
+ [&](const auto &) {
+ TODO(converter.getCurrentLocation(),
+ "target map clause operand unsupported type");
+ });
+ }
+ }
+}
+
static void genBodyOfTargetDataOp(
lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
- mlir::omp::TargetDataOp &dataOp, llvm::ArrayRef<mlir::Type> useDeviceTypes,
- llvm::ArrayRef<mlir::Location> useDeviceLocs,
+ mlir::omp::TargetDataOp &dataOp,
llvm::ArrayRef<const semantics::Symbol *> useDeviceSymbols,
+ llvm::ArrayRef<mlir::Location> useDeviceLocs,
+ llvm::ArrayRef<mlir::Type> useDeviceTypes,
const mlir::Location ¤tLocation, const ConstructQueue &queue,
ConstructQueue::const_iterator item) {
+ assert(useDeviceTypes.size() == useDeviceLocs.size());
+
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::Region ®ion = dataOp.getRegion();
+ mlir::Block *regionBlock = nullptr;
+ regionBlock =
+ firOpBuilder.createBlock(®ion, {}, useDeviceTypes, useDeviceLocs);
- firOpBuilder.createBlock(®ion, {}, useDeviceTypes, useDeviceLocs);
-
- for (auto [argIndex, argSymbol] : llvm::enumerate(useDeviceSymbols)) {
- const mlir::BlockArgument &arg = region.front().getArgument(argIndex);
- fir::ExtendedValue extVal = converter.getSymbolExtendedValue(*argSymbol);
- if (auto refType = mlir::dyn_cast<fir::ReferenceType>(arg.getType())) {
- if (fir::isa_builtin_cptr_type(refType.getElementType())) {
- converter.bindSymbol(*argSymbol, arg);
- } else {
- // Avoid capture of a reference to a structured binding.
- const semantics::Symbol *sym = argSymbol;
- extVal.match(
- [&](const fir::MutableBoxValue &mbv) {
- converter.bindSymbol(
- *sym,
- fir::MutableBoxValue(
- arg, fir::factory::getNonDeferredLenParams(extVal), {}));
- },
- [&](const auto &) {
- TODO(converter.getCurrentLocation(),
- "use_device clause operand unsupported type");
- });
- }
- } else {
- TODO(converter.getCurrentLocation(),
- "use_device clause operand unsupported type");
- }
- }
+ mapBodySymbols(converter, region, regionBlock, useDeviceSymbols);
----------------
skatrak wrote:
Would it be correct for a bound cloned into the `omp.target_data` region to take an outside value as an argument? For `omp.target` this is disallowed due to the `IsolatedFromAbove` trait, so there's some additional post-processing to handle them. Here we don't have the same restriction, but I wonder if we would produce valid code if we don't map these too.
https://github.com/llvm/llvm-project/pull/101703
More information about the flang-commits
mailing list