[flang-commits] [flang] [mlir] [flang][OpenMP] - Add `MapInfoOp` instances for target private variables when needed (PR #109862)
Pranav Bhandarkar via flang-commits
flang-commits at lists.llvm.org
Thu Oct 10 13:01:42 PDT 2024
https://github.com/bhandarkar-pranav updated https://github.com/llvm/llvm-project/pull/109862
>From 55753c6518d04a0270b6b38dbf06b9d755c5e6f9 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Wed, 18 Sep 2024 23:50:02 -0500
Subject: [PATCH 01/12] Add MapsForPrivatizedSymbolsPass
---
.../include/flang/Optimizer/OpenMP/Passes.td | 13 ++
flang/lib/Optimizer/OpenMP/CMakeLists.txt | 1 +
.../OpenMP/MapsForPrivatizedSymbols.cpp | 119 ++++++++++++++++++
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 2 +-
4 files changed, 134 insertions(+), 1 deletion(-)
create mode 100644 flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
diff --git a/flang/include/flang/Optimizer/OpenMP/Passes.td b/flang/include/flang/Optimizer/OpenMP/Passes.td
index 1c0ce08f5b4838..de2c561c2d3f37 100644
--- a/flang/include/flang/Optimizer/OpenMP/Passes.td
+++ b/flang/include/flang/Optimizer/OpenMP/Passes.td
@@ -22,6 +22,19 @@ def MapInfoFinalizationPass
let dependentDialects = ["mlir::omp::OpenMPDialect"];
}
+def MapsForPrivatizedSymbolsPass
+ : Pass<"omp-map-for-privatized-symbols", "mlir::func::FuncOp"> {
+ let summary = "Creates MapInfoOp instances for privatized symbols when needed";
+ let description = [{
+ Adds omp.map.info operations for privatized symbols on omp.target ops
+ In certain situations, such as when an allocatable is privatized, its
+ descriptor is needed in the alloc region of the privatizer. This results
+ in the use of the descriptor inside the target region. As such, the
+ descriptor then needs to be mapped. This pass adds such MapInfoOp operations.
+ }];
+ let dependentDialects = ["mlir::omp::OpenMPDialect"];
+}
+
def MarkDeclareTargetPass
: Pass<"omp-mark-declare-target", "mlir::ModuleOp"> {
let summary = "Marks all functions called by an OpenMP declare target function as declare target";
diff --git a/flang/lib/Optimizer/OpenMP/CMakeLists.txt b/flang/lib/Optimizer/OpenMP/CMakeLists.txt
index 92051634f0378b..035d0d5ca46c76 100644
--- a/flang/lib/Optimizer/OpenMP/CMakeLists.txt
+++ b/flang/lib/Optimizer/OpenMP/CMakeLists.txt
@@ -2,6 +2,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
add_flang_library(FlangOpenMPTransforms
FunctionFiltering.cpp
+ MapsForPrivatizedSymbols.cpp
MapInfoFinalization.cpp
MarkDeclareTarget.cpp
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
new file mode 100644
index 00000000000000..44c7a7a9302ee5
--- /dev/null
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -0,0 +1,119 @@
+//===- MapsForPrivatizedSymbols.cpp
+//-----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/OpenMP/Passes.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/SymbolTable.h"
+#include "mlir/Pass/Pass.h"
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include <type_traits>
+
+namespace flangomp {
+#define GEN_PASS_DEF_MAPSFORPRIVATIZEDSYMBOLSPASS
+#include "flang/Optimizer/OpenMP/Passes.h.inc"
+} // namespace flangomp
+using namespace mlir;
+namespace {
+class MapsForPrivatizedSymbolsPass
+ : public flangomp::impl::MapsForPrivatizedSymbolsPassBase<
+ MapsForPrivatizedSymbolsPass> {
+
+ bool privatizerNeedsMap(omp::PrivateClauseOp &privatizer) {
+ Region &allocRegion = privatizer.getAllocRegion();
+ Value blockArg0 = allocRegion.getArgument(0);
+ if (blockArg0.use_empty())
+ return false;
+ return true;
+ }
+ void dumpPrivatizerInfo(omp::PrivateClauseOp &privatizer,
+ mlir::Value privVar) {
+ llvm::errs() << "Found a privatizer:\n";
+ privatizer.dump();
+ llvm::errs() << "\n";
+
+ llvm::errs() << "$type = " << privatizer.getType() << "\n";
+ llvm::errs() << "privVar = ";
+ privVar.dump();
+ llvm::errs() << "\n";
+
+ llvm::errs() << "privVar.getDefiningOp() = ";
+ privVar.getDefiningOp()->dump();
+ llvm::errs() << "\n";
+ llvm::errs() << "\n";
+ }
+ omp::MapInfoOp createMapInfo(mlir::Location loc, mlir::Value var,
+ OpBuilder &builder) {
+ // llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
+ // llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
+ uint64_t mapTypeTo = static_cast<
+ std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
+ return builder.create<omp::MapInfoOp>(
+ loc, var.getType(), var,
+ mlir::TypeAttr::get(fir::unwrapRefType(var.getType())),
+ /*varPtrPtr=*/mlir::Value{},
+ /*members=*/mlir::SmallVector<mlir::Value>{},
+ /*member_index=*/mlir::DenseIntElementsAttr{},
+ /*bounds=*/mlir::ValueRange{},
+ builder.getIntegerAttr(builder.getIntegerType(64, /*isSigned=*/false),
+ mapTypeTo),
+ builder.getAttr<omp::VariableCaptureKindAttr>(
+ omp::VariableCaptureKind::ByRef),
+ mlir::StringAttr(), builder.getBoolAttr(false));
+ }
+ void addMapInfoOp(omp::TargetOp targetOp, omp::MapInfoOp mapInfoOp) {
+ mlir::Location loc = targetOp.getLoc();
+ targetOp.getMapVarsMutable().append(mlir::ValueRange{mapInfoOp});
+ size_t numMapVars = targetOp.getMapVars().size();
+ targetOp.getRegion().insertArgument(numMapVars - 1, mapInfoOp.getType(),
+ loc);
+ }
+ void runOnOperation() override {
+ MLIRContext *context = &getContext();
+ OpBuilder builder(context);
+ getOperation()->walk([&](omp::TargetOp targetOp) {
+ llvm::errs() << "MapsForPrivatizedSymbolsPass::TargetOp is \n";
+ targetOp.dump();
+ llvm::errs() << "\n";
+
+ if (targetOp.getPrivateVars().empty())
+ return;
+
+ OperandRange privVars = targetOp.getPrivateVars();
+ std::optional<ArrayAttr> privSyms = targetOp.getPrivateSyms();
+
+ for (auto [privVar, privSym] : llvm::zip_equal(privVars, *privSyms)) {
+
+ SymbolRefAttr privatizerName = llvm::cast<SymbolRefAttr>(privSym);
+ omp::PrivateClauseOp privatizer =
+ SymbolTable::lookupNearestSymbolFrom<omp::PrivateClauseOp>(
+ targetOp, privatizerName);
+
+ assert(mlir::isa<fir::ReferenceType>(privVar.getType()) &&
+ "Privatized variable should be a reference.");
+ if (!privatizerNeedsMap(privatizer)) {
+ return;
+ }
+ llvm::errs() << "Privatizer NEEDS a map\n";
+ builder.setInsertionPoint(targetOp);
+ dumpPrivatizerInfo(privatizer, privVar);
+
+ mlir::Location loc = targetOp.getLoc();
+ omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
+ addMapInfoOp(targetOp, mapInfoOp);
+ llvm::errs() << __FUNCTION__ << "MapInfoOp is \n";
+ mapInfoOp.dump();
+ llvm::errs() << "\n";
+ }
+ });
+ }
+};
+} // namespace
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 66f63fc02fe2f3..9f5b19d20aa2e5 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -932,7 +932,7 @@ def MapInfoOp : OpenMP_Op<"map.info", [AttrSizedOperandSegments]> {
objects (e.g. derived types or classes), indicates the bounds to be copied
of the variable. When it's an array slice it is in rank order where rank 0
is the inner-most dimension.
- - 'map_clauses': OpenMP map type for this map capture, for example: from, to and
+ - 'map_type': OpenMP map type for this map capture, for example: from, to and
always. It's a bitfield composed of the OpenMP runtime flags stored in
OpenMPOffloadMappingFlags.
- 'map_capture_type': Capture type for the variable e.g. this, byref, byvalue, byvla
>From 905463900fc17977036f7299d1c0c7d826fbdc6f Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Sun, 22 Sep 2024 00:38:21 -0500
Subject: [PATCH 02/12] clean up and add one test
---
.../OpenMP/MapsForPrivatizedSymbols.cpp | 34 ++------
.../omp-maps-for-privatized-symbols.fir | 84 +++++++++++++++++++
2 files changed, 90 insertions(+), 28 deletions(-)
create mode 100644 flang/test/Transforms/omp-maps-for-privatized-symbols.fir
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 44c7a7a9302ee5..494b4ebc6c44fa 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -14,8 +14,11 @@
#include "mlir/IR/SymbolTable.h"
#include "mlir/Pass/Pass.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include "llvm/Support/Debug.h"
#include <type_traits>
+#define DEBUG_TYPE "omp-maps-for-privatized-symbols"
+
namespace flangomp {
#define GEN_PASS_DEF_MAPSFORPRIVATIZEDSYMBOLSPASS
#include "flang/Optimizer/OpenMP/Passes.h.inc"
@@ -33,29 +36,12 @@ class MapsForPrivatizedSymbolsPass
return false;
return true;
}
- void dumpPrivatizerInfo(omp::PrivateClauseOp &privatizer,
- mlir::Value privVar) {
- llvm::errs() << "Found a privatizer:\n";
- privatizer.dump();
- llvm::errs() << "\n";
-
- llvm::errs() << "$type = " << privatizer.getType() << "\n";
- llvm::errs() << "privVar = ";
- privVar.dump();
- llvm::errs() << "\n";
-
- llvm::errs() << "privVar.getDefiningOp() = ";
- privVar.getDefiningOp()->dump();
- llvm::errs() << "\n";
- llvm::errs() << "\n";
- }
omp::MapInfoOp createMapInfo(mlir::Location loc, mlir::Value var,
OpBuilder &builder) {
- // llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
- // llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
uint64_t mapTypeTo = static_cast<
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
+
return builder.create<omp::MapInfoOp>(
loc, var.getType(), var,
mlir::TypeAttr::get(fir::unwrapRefType(var.getType())),
@@ -80,10 +66,6 @@ class MapsForPrivatizedSymbolsPass
MLIRContext *context = &getContext();
OpBuilder builder(context);
getOperation()->walk([&](omp::TargetOp targetOp) {
- llvm::errs() << "MapsForPrivatizedSymbolsPass::TargetOp is \n";
- targetOp.dump();
- llvm::errs() << "\n";
-
if (targetOp.getPrivateVars().empty())
return;
@@ -102,16 +84,12 @@ class MapsForPrivatizedSymbolsPass
if (!privatizerNeedsMap(privatizer)) {
return;
}
- llvm::errs() << "Privatizer NEEDS a map\n";
builder.setInsertionPoint(targetOp);
- dumpPrivatizerInfo(privatizer, privVar);
-
mlir::Location loc = targetOp.getLoc();
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
addMapInfoOp(targetOp, mapInfoOp);
- llvm::errs() << __FUNCTION__ << "MapInfoOp is \n";
- mapInfoOp.dump();
- llvm::errs() << "\n";
+ LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n");
+ LLVM_DEBUG(mapInfoOp.dump());
}
});
}
diff --git a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
new file mode 100644
index 00000000000000..cd7ee2463238ee
--- /dev/null
+++ b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
@@ -0,0 +1,84 @@
+// RUN: fir-opt --split-input-file --omp-maps-for-privatized-symbols %s | FileCheck %s
+module attributes {omp.is_target_device = false} {
+ omp.private {type = private} @_QFtarget_simpleEsimple_var_private_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> alloc {
+ ^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>):
+ %0 = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "simple_var", pinned, uniq_name = "_QFtarget_simpleEsimple_var"}
+ %1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %2 = fir.box_addr %1 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ %3 = fir.convert %2 : (!fir.heap<i32>) -> i64
+ %c0_i64 = arith.constant 0 : i64
+ %4 = arith.cmpi ne, %3, %c0_i64 : i64
+ fir.if %4 {
+ %6 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %7 = fir.box_addr %6 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ %8 = fir.allocmem i32 {fir.must_be_heap = true, uniq_name = "_QFtarget_simpleEsimple_var.alloc"}
+ %9 = fir.embox %8 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+ fir.store %9 to %0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ } else {
+ %6 = fir.zero_bits !fir.heap<i32>
+ %7 = fir.embox %6 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+ fir.store %7 to %0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ }
+ %5:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtarget_simpleEsimple_var"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
+ omp.yield(%5#0 : !fir.ref<!fir.box<!fir.heap<i32>>>)
+ } dealloc {
+ ^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>):
+ %0 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %1 = fir.box_addr %0 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ %2 = fir.convert %1 : (!fir.heap<i32>) -> i64
+ %c0_i64 = arith.constant 0 : i64
+ %3 = arith.cmpi ne, %2, %c0_i64 : i64
+ fir.if %3 {
+ %false = arith.constant false
+ %4 = fir.absent !fir.box<none>
+ %c70 = arith.constant 70 : index
+ %c10_i32 = arith.constant 10 : i32
+ %6 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %7 = fir.box_addr %6 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ fir.freemem %7 : !fir.heap<i32>
+ %8 = fir.zero_bits !fir.heap<i32>
+ %9 = fir.embox %8 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+ fir.store %9 to %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ }
+ omp.yield
+ }
+ func.func @_QPtarget_simple() {
+ %0 = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFtarget_simpleEa"}
+ %1:2 = hlfir.declare %0 {uniq_name = "_QFtarget_simpleEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %2 = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "simple_var", uniq_name = "_QFtarget_simpleEsimple_var"}
+ %3 = fir.zero_bits !fir.heap<i32>
+ %4 = fir.embox %3 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+ fir.store %4 to %2 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %5:2 = hlfir.declare %2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtarget_simpleEsimple_var"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
+ %c2_i32 = arith.constant 2 : i32
+ hlfir.assign %c2_i32 to %1#0 : i32, !fir.ref<i32>
+ %6 = omp.map.info var_ptr(%1#1 : !fir.ref<i32>, i32) map_clauses(to) capture(ByRef) -> !fir.ref<i32> {name = "a"}
+ omp.target map_entries(%6 -> %arg0 : !fir.ref<i32>) private(@_QFtarget_simpleEsimple_var_private_ref_box_heap_i32 %5#0 -> %arg1 : !fir.ref<!fir.box<!fir.heap<i32>>>) {
+ ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>>):
+ %11:2 = hlfir.declare %arg0 {uniq_name = "_QFtarget_simpleEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %12:2 = hlfir.declare %arg1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtarget_simpleEsimple_var"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
+ %c10_i32 = arith.constant 10 : i32
+ %13 = fir.load %11#0 : !fir.ref<i32>
+ %14 = arith.addi %c10_i32, %13 : i32
+ hlfir.assign %14 to %12#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<i32>>>
+ omp.terminator
+ }
+ %7 = fir.load %5#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %8 = fir.box_addr %7 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ %9 = fir.convert %8 : (!fir.heap<i32>) -> i64
+ %c0_i64 = arith.constant 0 : i64
+ %10 = arith.cmpi ne, %9, %c0_i64 : i64
+ fir.if %10 {
+ %11 = fir.load %5#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ %12 = fir.box_addr %11 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+ fir.freemem %12 : !fir.heap<i32>
+ %13 = fir.zero_bits !fir.heap<i32>
+ %14 = fir.embox %13 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+ fir.store %14 to %5#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
+ }
+ return
+ }
+}
+// CHECK: %[[MAP0:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByRef) -> !fir.ref<i32> {name = "a"}
+// CHECK: %[[MAP1:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>) map_clauses(to) capture(ByRef) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+// CHECK: omp.target map_entries(%[[MAP0]] -> %arg0, %[[MAP1]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<i32>>>)
>From 0e16cb4088a21135bdcb3aafcd08d2f9ba0f2ce0 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Mon, 23 Sep 2024 16:59:12 -0500
Subject: [PATCH 03/12] fix failures seen in
target-private-multiple-variables.f90
---
.../OpenMP/MapsForPrivatizedSymbols.cpp | 64 ++++++++++++++++---
1 file changed, 54 insertions(+), 10 deletions(-)
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 494b4ebc6c44fa..d236b3d23d0cb0 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
@@ -41,10 +42,27 @@ class MapsForPrivatizedSymbolsPass
uint64_t mapTypeTo = static_cast<
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
-
+ Operation *definingOp = var.getDefiningOp();
+ auto declOp = llvm::dyn_cast_or_null<hlfir::DeclareOp>(definingOp);
+ assert(declOp &&
+ "Expected defining Op of privatized var to be hlfir.declare");
+ Value varPtr = declOp.getOriginalBase();
+ Value varBase = declOp.getBase();
+ llvm::errs() << "varPtr = ";
+ varPtr.dump();
+ llvm::errs() << " type -> ";
+ varPtr.getType().dump();
+ llvm::errs() << "\n";
+ llvm::errs() << "varBase = ";
+ varBase.dump();
+ llvm::errs() << " type -> ";
+ varBase.getType().dump();
+ llvm::errs() << "\n";
return builder.create<omp::MapInfoOp>(
- loc, var.getType(), var,
- mlir::TypeAttr::get(fir::unwrapRefType(var.getType())),
+ loc, varPtr.getType(), varPtr,
+ mlir::TypeAttr::get(
+ llvm::cast<mlir::omp::PointerLikeType>(varPtr.getType())
+ .getElementType()),
/*varPtrPtr=*/mlir::Value{},
/*members=*/mlir::SmallVector<mlir::Value>{},
/*member_index=*/mlir::DenseIntElementsAttr{},
@@ -57,41 +75,67 @@ class MapsForPrivatizedSymbolsPass
}
void addMapInfoOp(omp::TargetOp targetOp, omp::MapInfoOp mapInfoOp) {
mlir::Location loc = targetOp.getLoc();
+ llvm::errs() << "Adding mapInfoOp -> ";
+ mapInfoOp.dump();
+ llvm::errs() << "\n";
+
targetOp.getMapVarsMutable().append(mlir::ValueRange{mapInfoOp});
size_t numMapVars = targetOp.getMapVars().size();
targetOp.getRegion().insertArgument(numMapVars - 1, mapInfoOp.getType(),
loc);
}
+ void addMapInfoOps(omp::TargetOp targetOp,
+ llvm::SmallVectorImpl<omp::MapInfoOp> &mapInfoOps) {
+ for (auto mapInfoOp : mapInfoOps)
+ addMapInfoOp(targetOp, mapInfoOp);
+ }
void runOnOperation() override {
MLIRContext *context = &getContext();
OpBuilder builder(context);
+ llvm::DenseMap<Operation *, llvm::SmallVector<omp::MapInfoOp, 4>>
+ mapInfoOpsForTarget;
getOperation()->walk([&](omp::TargetOp targetOp) {
if (targetOp.getPrivateVars().empty())
return;
-
+ llvm::errs() << "Func is \n";
+ targetOp.getOperation()->getParentOp()->getParentOp()->dump();
+ llvm::errs() << "\n";
OperandRange privVars = targetOp.getPrivateVars();
std::optional<ArrayAttr> privSyms = targetOp.getPrivateSyms();
-
+ SmallVector<omp::MapInfoOp, 4> mapInfoOps;
for (auto [privVar, privSym] : llvm::zip_equal(privVars, *privSyms)) {
SymbolRefAttr privatizerName = llvm::cast<SymbolRefAttr>(privSym);
omp::PrivateClauseOp privatizer =
SymbolTable::lookupNearestSymbolFrom<omp::PrivateClauseOp>(
targetOp, privatizerName);
-
- assert(mlir::isa<fir::ReferenceType>(privVar.getType()) &&
- "Privatized variable should be a reference.");
+ llvm::errs() << "privVar = ";
+ privVar.dump();
+ llvm::errs() << "\n";
+ llvm::errs() << "privVar.getType() = ";
+ privVar.getType().dump();
+ llvm::errs() << "\n";
+ // assert(mlir::isa<fir::ReferenceType>(privVar.getType()) &&
+ // "Privatized variable should be a reference.");
if (!privatizerNeedsMap(privatizer)) {
- return;
+ continue;
}
builder.setInsertionPoint(targetOp);
mlir::Location loc = targetOp.getLoc();
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
- addMapInfoOp(targetOp, mapInfoOp);
+ mapInfoOps.push_back(mapInfoOp);
LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n");
LLVM_DEBUG(mapInfoOp.dump());
}
+ if (!mapInfoOps.empty()) {
+ mapInfoOpsForTarget.insert({targetOp.getOperation(), mapInfoOps});
+ }
});
+ if (!mapInfoOpsForTarget.empty()) {
+ for (auto &[targetOp, mapInfoOps] : mapInfoOpsForTarget) {
+ addMapInfoOps(static_cast<omp::TargetOp>(targetOp), mapInfoOps);
+ }
+ }
}
};
} // namespace
>From 66b0640594ce92615f43424d1517e8bbb9de1e13 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Tue, 24 Sep 2024 10:20:51 -0500
Subject: [PATCH 04/12] fix flag omp-maps-for-privatized-symbols
---
flang/include/flang/Optimizer/OpenMP/Passes.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/include/flang/Optimizer/OpenMP/Passes.td b/flang/include/flang/Optimizer/OpenMP/Passes.td
index de2c561c2d3f37..c070bc22ff20cc 100644
--- a/flang/include/flang/Optimizer/OpenMP/Passes.td
+++ b/flang/include/flang/Optimizer/OpenMP/Passes.td
@@ -23,7 +23,7 @@ def MapInfoFinalizationPass
}
def MapsForPrivatizedSymbolsPass
- : Pass<"omp-map-for-privatized-symbols", "mlir::func::FuncOp"> {
+ : Pass<"omp-maps-for-privatized-symbols", "mlir::func::FuncOp"> {
let summary = "Creates MapInfoOp instances for privatized symbols when needed";
let description = [{
Adds omp.map.info operations for privatized symbols on omp.target ops
>From 94ada9c6e4fa3077ca81eb39efd5d504989ee99e Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Tue, 24 Sep 2024 15:38:57 -0500
Subject: [PATCH 05/12] clean up MapsForPrivatizedSymbols.cpp
---
.../OpenMP/MapsForPrivatizedSymbols.cpp | 68 ++++++++-----------
1 file changed, 29 insertions(+), 39 deletions(-)
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index d236b3d23d0cb0..4943181e2d3acd 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -6,6 +6,23 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+/// \file
+/// An OpenMP dialect related pass for FIR/HLFIR which creates MapInfoOp
+/// instances for certain privatized symbols.
+/// For example, if an allocatable variable is used in a private clause attached
+/// to a omp.target op, then the allocatable variable's descriptor will be
+/// needed on the device (e.g. GPU). This descriptor needs to be separately
+/// mapped onto the device. This pass creates the necessary omp.map.info ops for
+/// this.
+//===----------------------------------------------------------------------===//
+// TODO:
+// 1. Before adding omp.map.info, check if in case we already have an
+// omp.map.info for the variable in question.
+// 2. Generalize this for more than just omp.target ops.
+//===----------------------------------------------------------------------===//
+
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/OpenMP/Passes.h"
@@ -37,8 +54,7 @@ class MapsForPrivatizedSymbolsPass
return false;
return true;
}
- omp::MapInfoOp createMapInfo(mlir::Location loc, mlir::Value var,
- OpBuilder &builder) {
+ omp::MapInfoOp createMapInfo(Location loc, Value var, OpBuilder &builder) {
uint64_t mapTypeTo = static_cast<
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
@@ -47,39 +63,24 @@ class MapsForPrivatizedSymbolsPass
assert(declOp &&
"Expected defining Op of privatized var to be hlfir.declare");
Value varPtr = declOp.getOriginalBase();
- Value varBase = declOp.getBase();
- llvm::errs() << "varPtr = ";
- varPtr.dump();
- llvm::errs() << " type -> ";
- varPtr.getType().dump();
- llvm::errs() << "\n";
- llvm::errs() << "varBase = ";
- varBase.dump();
- llvm::errs() << " type -> ";
- varBase.getType().dump();
- llvm::errs() << "\n";
+
return builder.create<omp::MapInfoOp>(
loc, varPtr.getType(), varPtr,
- mlir::TypeAttr::get(
- llvm::cast<mlir::omp::PointerLikeType>(varPtr.getType())
- .getElementType()),
- /*varPtrPtr=*/mlir::Value{},
- /*members=*/mlir::SmallVector<mlir::Value>{},
- /*member_index=*/mlir::DenseIntElementsAttr{},
- /*bounds=*/mlir::ValueRange{},
+ TypeAttr::get(llvm::cast<omp::PointerLikeType>(varPtr.getType())
+ .getElementType()),
+ /*varPtrPtr=*/Value{},
+ /*members=*/SmallVector<Value>{},
+ /*member_index=*/DenseIntElementsAttr{},
+ /*bounds=*/ValueRange{},
builder.getIntegerAttr(builder.getIntegerType(64, /*isSigned=*/false),
mapTypeTo),
builder.getAttr<omp::VariableCaptureKindAttr>(
omp::VariableCaptureKind::ByRef),
- mlir::StringAttr(), builder.getBoolAttr(false));
+ StringAttr(), builder.getBoolAttr(false));
}
void addMapInfoOp(omp::TargetOp targetOp, omp::MapInfoOp mapInfoOp) {
- mlir::Location loc = targetOp.getLoc();
- llvm::errs() << "Adding mapInfoOp -> ";
- mapInfoOp.dump();
- llvm::errs() << "\n";
-
- targetOp.getMapVarsMutable().append(mlir::ValueRange{mapInfoOp});
+ Location loc = targetOp.getLoc();
+ targetOp.getMapVarsMutable().append(ValueRange{mapInfoOp});
size_t numMapVars = targetOp.getMapVars().size();
targetOp.getRegion().insertArgument(numMapVars - 1, mapInfoOp.getType(),
loc);
@@ -97,9 +98,6 @@ class MapsForPrivatizedSymbolsPass
getOperation()->walk([&](omp::TargetOp targetOp) {
if (targetOp.getPrivateVars().empty())
return;
- llvm::errs() << "Func is \n";
- targetOp.getOperation()->getParentOp()->getParentOp()->dump();
- llvm::errs() << "\n";
OperandRange privVars = targetOp.getPrivateVars();
std::optional<ArrayAttr> privSyms = targetOp.getPrivateSyms();
SmallVector<omp::MapInfoOp, 4> mapInfoOps;
@@ -109,19 +107,11 @@ class MapsForPrivatizedSymbolsPass
omp::PrivateClauseOp privatizer =
SymbolTable::lookupNearestSymbolFrom<omp::PrivateClauseOp>(
targetOp, privatizerName);
- llvm::errs() << "privVar = ";
- privVar.dump();
- llvm::errs() << "\n";
- llvm::errs() << "privVar.getType() = ";
- privVar.getType().dump();
- llvm::errs() << "\n";
- // assert(mlir::isa<fir::ReferenceType>(privVar.getType()) &&
- // "Privatized variable should be a reference.");
if (!privatizerNeedsMap(privatizer)) {
continue;
}
builder.setInsertionPoint(targetOp);
- mlir::Location loc = targetOp.getLoc();
+ Location loc = targetOp.getLoc();
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
mapInfoOps.push_back(mapInfoOp);
LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n");
>From cc51c02cdc596ab77e74c02e5fcd7ef37dbbb152 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Mon, 30 Sep 2024 16:56:53 -0500
Subject: [PATCH 06/12] Move the addition of MapsForPrivatizedSymbolsPass from
CLOptions.inc to Pipelines.cpp in flang
---
flang/lib/Optimizer/Passes/Pipelines.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 3fa5c54403bd8c..3c139f7e93405c 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -243,6 +243,7 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm,
/// rather than the host device.
void createOpenMPFIRPassPipeline(mlir::PassManager &pm, bool isTargetDevice) {
pm.addPass(flangomp::createMapInfoFinalizationPass());
+ pm.addPass(flangomp::createMapsForPrivatizedSymbolsPass());
pm.addPass(flangomp::createMarkDeclareTargetPass());
if (isTargetDevice)
pm.addPass(flangomp::createFunctionFilteringPass());
>From ada7fb53631d62c4ab2a594289277639df91b13e Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Wed, 2 Oct 2024 11:17:18 -0500
Subject: [PATCH 07/12] Update
flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
---
.../target-private-allocatable.f90 | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
index a27de1152ce17a..92f5ce5f0f21b1 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
@@ -18,22 +18,22 @@ end subroutine target_allocatable
! CHECK-SAME: @[[VAR_PRIVATIZER_SYM:.*]] :
! CHECK-SAME: [[TYPE:!fir.ref<!fir.box<!fir.heap<i32>>>]] alloc {
! CHECK: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
-! CHECK: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "alloc_var", {{.*}}}
+! CHECK: %[[PRIV_ALLOC:.*]] = fir.alloca [[DESC_TYPE:!fir.box<!fir.heap<i32>>]] {bindc_name = "alloc_var", {{.*}}}
-! CHECK-NEXT: %[[PRIV_ARG_VAL:.*]] = fir.load %[[PRIV_ARG]] : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK-NEXT: %[[PRIV_ARG_BOX:.*]] = fir.box_addr %[[PRIV_ARG_VAL]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+! CHECK-NEXT: %[[PRIV_ARG_VAL:.*]] = fir.load %[[PRIV_ARG]] : [[TYPE]]
+! CHECK-NEXT: %[[PRIV_ARG_BOX:.*]] = fir.box_addr %[[PRIV_ARG_VAL]] : ([[DESC_TYPE]]) -> !fir.heap<i32>
! CHECK-NEXT: %[[PRIV_ARG_ADDR:.*]] = fir.convert %[[PRIV_ARG_BOX]] : (!fir.heap<i32>) -> i64
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : i64
! CHECK-NEXT: %[[ALLOC_COND:.*]] = arith.cmpi ne, %[[PRIV_ARG_ADDR]], %[[C0]] : i64
! CHECK-NEXT: fir.if %[[ALLOC_COND]] {
! CHECK: %[[PRIV_ALLOCMEM:.*]] = fir.allocmem i32 {fir.must_be_heap = true, {{.*}}}
-! CHECK-NEXT: %[[PRIV_ALLOCMEM_BOX:.*]] = fir.embox %[[PRIV_ALLOCMEM]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
-! CHECK-NEXT: fir.store %[[PRIV_ALLOCMEM_BOX]] to %[[PRIV_ALLOC]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK-NEXT: %[[PRIV_ALLOCMEM_BOX:.*]] = fir.embox %[[PRIV_ALLOCMEM]] : (!fir.heap<i32>) -> [[DESC_TYPE]]
+! CHECK-NEXT: fir.store %[[PRIV_ALLOCMEM_BOX]] to %[[PRIV_ALLOC]] : [[TYPE]]
! CHECK-NEXT: } else {
! CHECK-NEXT: %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<i32>
-! CHECK-NEXT: %[[ZERO_BOX:.*]] = fir.embox %[[ZERO_BITS]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
-! CHECK-NEXT: fir.store %[[ZERO_BOX]] to %[[PRIV_ALLOC]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK-NEXT: %[[ZERO_BOX:.*]] = fir.embox %[[ZERO_BITS]] : (!fir.heap<i32>) -> [[DESC_TYPE]]
+! CHECK-NEXT: fir.store %[[ZERO_BOX]] to %[[PRIV_ALLOC]] : [[TYPE]]
! CHECK-NEXT: }
! CHECK-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]]
@@ -63,9 +63,11 @@ end subroutine target_allocatable
! CHECK-LABEL: func.func @_QPtarget_allocatable() {
-! CHECK: %[[VAR_ALLOC:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
+! CHECK: %[[VAR_ALLOC:.*]] = fir.alloca [[DESC_TYPE]]
! CHECK-SAME: {bindc_name = "alloc_var", {{.*}}}
! CHECK: %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_ALLOC]]
-! CHECK: omp.target private(
+! CHECK: %[[MAP_VAR:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#1 : [[TYPE]], [[DESC_TYPE]])
+! CHECK-SAME: map_clauses(to) capture(ByRef) -> [[TYPE]]
+! CHECK: omp.target map_entries(%[[MAP_VAR]] -> %arg0 : [[TYPE]]) private(
! CHECK-SAME: @[[VAR_PRIVATIZER_SYM]] %[[VAR_DECL]]#0 -> %{{.*}} : [[TYPE]]) {
>From bc54e003e67228f74668de563aa93e301548f0af Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Wed, 2 Oct 2024 15:52:50 -0500
Subject: [PATCH 08/12] Fix
flang/test/Transforms/omp-maps-for-privatized-symbols.fir for
cdb3ebf1e62df060767863e1e683409d6077ca6e
---
flang/test/Transforms/omp-maps-for-privatized-symbols.fir | 1 -
1 file changed, 1 deletion(-)
diff --git a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
index cd7ee2463238ee..9bd54611893e32 100644
--- a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
+++ b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
@@ -54,7 +54,6 @@ module attributes {omp.is_target_device = false} {
hlfir.assign %c2_i32 to %1#0 : i32, !fir.ref<i32>
%6 = omp.map.info var_ptr(%1#1 : !fir.ref<i32>, i32) map_clauses(to) capture(ByRef) -> !fir.ref<i32> {name = "a"}
omp.target map_entries(%6 -> %arg0 : !fir.ref<i32>) private(@_QFtarget_simpleEsimple_var_private_ref_box_heap_i32 %5#0 -> %arg1 : !fir.ref<!fir.box<!fir.heap<i32>>>) {
- ^bb0(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>>):
%11:2 = hlfir.declare %arg0 {uniq_name = "_QFtarget_simpleEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
%12:2 = hlfir.declare %arg1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtarget_simpleEsimple_var"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
%c10_i32 = arith.constant 10 : i32
>From 7d673dcabe4606e5ba3481abe855217e16fa1ffd Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Thu, 10 Oct 2024 14:08:57 -0500
Subject: [PATCH 09/12] Fix lit tests on the flang/maps_for_privatized_symbols
pass
---
.../OpenMP/MapsForPrivatizedSymbols.cpp | 27 ++++++++++++++++---
.../target-private-allocatable.f90 | 2 +-
.../target-private-multiple-variables.f90 | 24 ++++++++++++++---
3 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 4943181e2d3acd..93cc60ac4dfcc7 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -23,7 +23,9 @@
// 2. Generalize this for more than just omp.target ops.
//===----------------------------------------------------------------------===//
+#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -54,7 +56,8 @@ class MapsForPrivatizedSymbolsPass
return false;
return true;
}
- omp::MapInfoOp createMapInfo(Location loc, Value var, OpBuilder &builder) {
+ omp::MapInfoOp createMapInfo(Location loc, Value var,
+ fir::FirOpBuilder &builder) {
uint64_t mapTypeTo = static_cast<
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
@@ -62,8 +65,20 @@ class MapsForPrivatizedSymbolsPass
auto declOp = llvm::dyn_cast_or_null<hlfir::DeclareOp>(definingOp);
assert(declOp &&
"Expected defining Op of privatized var to be hlfir.declare");
- Value varPtr = declOp.getOriginalBase();
+ Value varPtr = declOp.getBase();
+ if (mlir::isa<fir::BaseBoxType>(varPtr.getType()) ||
+ mlir::isa<fir::BoxCharType>(varPtr.getType())) {
+ llvm::errs() << "Is a basebox type\n";
+ OpBuilder::InsertPoint savedInsPoint = builder.saveInsertionPoint();
+ mlir::Block *allocaBlock = builder.getAllocaBlock();
+ assert(allocaBlock && "No allocablock found for a funcOp");
+ builder.setInsertionPointToStart(allocaBlock);
+ auto alloca = builder.create<fir::AllocaOp>(loc, varPtr.getType());
+ builder.restoreInsertionPoint(savedInsPoint);
+ builder.create<fir::StoreOp>(loc, varPtr, alloca);
+ varPtr = alloca;
+ }
return builder.create<omp::MapInfoOp>(
loc, varPtr.getType(), varPtr,
TypeAttr::get(llvm::cast<omp::PointerLikeType>(varPtr.getType())
@@ -91,10 +106,12 @@ class MapsForPrivatizedSymbolsPass
addMapInfoOp(targetOp, mapInfoOp);
}
void runOnOperation() override {
- MLIRContext *context = &getContext();
- OpBuilder builder(context);
+ ModuleOp module = getOperation()->getParentOfType<ModuleOp>();
+ fir::KindMapping kindMap = fir::getKindMapping(module);
+ fir::FirOpBuilder builder{module, std::move(kindMap)};
llvm::DenseMap<Operation *, llvm::SmallVector<omp::MapInfoOp, 4>>
mapInfoOpsForTarget;
+
getOperation()->walk([&](omp::TargetOp targetOp) {
if (targetOp.getPrivateVars().empty())
return;
@@ -112,7 +129,9 @@ class MapsForPrivatizedSymbolsPass
}
builder.setInsertionPoint(targetOp);
Location loc = targetOp.getLoc();
+ llvm::errs() << "Here\n";
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
+ llvm::errs() << "Here again\n";
mapInfoOps.push_back(mapInfoOp);
LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n");
LLVM_DEBUG(mapInfoOp.dump());
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
index 92f5ce5f0f21b1..e11525c569ffb8 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90
@@ -67,7 +67,7 @@ end subroutine target_allocatable
! CHECK-SAME: {bindc_name = "alloc_var", {{.*}}}
! CHECK: %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_ALLOC]]
-! CHECK: %[[MAP_VAR:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#1 : [[TYPE]], [[DESC_TYPE]])
+! CHECK: %[[MAP_VAR:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]])
! CHECK-SAME: map_clauses(to) capture(ByRef) -> [[TYPE]]
! CHECK: omp.target map_entries(%[[MAP_VAR]] -> %arg0 : [[TYPE]]) private(
! CHECK-SAME: @[[VAR_PRIVATIZER_SYM]] %[[VAR_DECL]]#0 -> %{{.*}} : [[TYPE]]) {
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-multiple-variables.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-multiple-variables.f90
index e3c1dc805d07b6..ce96056692f5e5 100644
--- a/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-multiple-variables.f90
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/target-private-multiple-variables.f90
@@ -147,12 +147,29 @@ end subroutine target_allocatable
! CHECK-NEXT: }
! CHECK: func.func @_QPtarget_allocatable
+! CHECK: %[[CHAR_VAR_DESC_ALLOCA:.*]] = fir.alloca !fir.boxchar<1>
+! CHECK: %[[REAL_ARR_DESC_ALLOCA:.*]] = fir.alloca !fir.box<!fir.array<?xf32>>
+! CHECK: %[[ALLOC_VAR_ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "alloc_var", {{.*}}}
+! CHECK: %[[ALLOC_VAR_DECL:.*]]:2 = hlfir.declare %[[ALLOC_VAR_ALLOCA]]
! CHECK: %[[MAPPED_ALLOC:.*]] = fir.alloca i32 {bindc_name = "mapped_var", {{.*}}}
! CHECK-NEXT: %[[MAPPED_DECL:.*]]:2 = hlfir.declare %[[MAPPED_ALLOC]]
-! CHECK: %[[MAPPED_MI:.*]] = omp.map.info var_ptr(%[[MAPPED_DECL]]#1 : !fir.ref<i32>, i32)
-
+! CHECK: %[[CHAR_VAR_ALLOC:.*]] = fir.alloca !fir.char<1,?>{{.*}} {bindc_name = "char_var", {{.*}}}
+! CHECK: %[[CHAR_VAR_DECL:.*]]:2 = hlfir.declare %[[CHAR_VAR_ALLOC]] typeparams
+! CHECK: %[[REAL_ARR_ALLOC:.*]] = fir.alloca !fir.array<?xf32>, {{.*}} {bindc_name = "real_arr", {{.*}}}
+! CHECK: %[[REAL_ARR_DECL:.*]]:2 = hlfir.declare %[[REAL_ARR_ALLOC]]({{.*}})
+! CHECK: %[[MAPPED_MI0:.*]] = omp.map.info var_ptr(%[[MAPPED_DECL]]#1 : !fir.ref<i32>, i32) {{.*}}
+! CHECK: %[[ALLOC_VAR_MAP:.*]] = omp.map.info var_ptr(%[[ALLOC_VAR_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.box<!fir.heap<i32>>)
+! CHECK: fir.store %[[REAL_ARR_DECL]]#0 to %[[REAL_ARR_DESC_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
+! CHECK: %[[REAL_ARR_DESC_MAP:.*]] = omp.map.info var_ptr(%[[REAL_ARR_DESC_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xf32>>>, !fir.box<!fir.array<?xf32>>)
+! CHECK: fir.store %[[CHAR_VAR_DECL]]#0 to %[[CHAR_VAR_DESC_ALLOCA]] : !fir.ref<!fir.boxchar<1>>
+! CHECK: %[[CHAR_VAR_DESC_MAP:.*]] = omp.map.info var_ptr(%[[CHAR_VAR_DESC_ALLOCA]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>)
! CHECK: omp.target
-! CHECK-SAME: map_entries(%[[MAPPED_MI]] -> %[[MAPPED_ARG:.*]] : !fir.ref<i32>)
+! CHECK-SAME: map_entries(
+! CHECK-SAME: %[[MAPPED_MI0]] -> %[[MAPPED_ARG0:[^,]+]],
+! CHECK-SAME: %[[ALLOC_VAR_MAP]] -> %[[MAPPED_ARG1:[^,]+]]
+! CHECK-SAME %[[REAL_ARR_DESC_MAP]] -> %[[MAPPED_ARG2:[^,]+]]
+! CHECK_SAME %[[CHAR_VAR_DESC_MAP]] -> %[[MAPPED_ARG3:.[^,]+]] :
+! CHECK-SAME !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.array<?xf32>>>, !fir.ref<!fir.boxchar<1>>)
! CHECK-SAME: private(
! CHECK-SAME: @[[ALLOC_PRIVATIZER_SYM]] %{{[^[:space:]]+}}#0 -> %[[ALLOC_ARG:[^,]+]],
! CHECK-SAME: @[[REAL_PRIVATIZER_SYM]] %{{[^[:space:]]+}}#0 -> %[[REAL_ARG:[^,]+]],
@@ -162,7 +179,6 @@ end subroutine target_allocatable
! CHECK-SAME: @[[CHAR_PRIVATIZER_SYM]] %{{[^[:space:]]+}}#0 -> %[[CHAR_ARG:[^,]+]] :
! CHECK-SAME: !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<f32>, !fir.ref<i64>, !fir.box<!fir.array<?xf32>>, !fir.ref<!fir.complex<4>>, !fir.boxchar<1>) {
! CHECK-NOT: fir.alloca
-! CHECK: hlfir.declare %[[MAPPED_ARG]]
! CHECK: hlfir.declare %[[ALLOC_ARG]]
! CHECK: hlfir.declare %[[REAL_ARG]]
! CHECK: hlfir.declare %[[LB_ARG]]
>From 5e859ffbc003e5149c92f5f0dfa168dcffaa2899 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Thu, 10 Oct 2024 14:43:38 -0500
Subject: [PATCH 10/12] Use BlockArgOpenMPOpInterface and remove some debug
prints
---
.../Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 93cc60ac4dfcc7..7f3b00575fa82b 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -69,7 +69,6 @@ class MapsForPrivatizedSymbolsPass
if (mlir::isa<fir::BaseBoxType>(varPtr.getType()) ||
mlir::isa<fir::BoxCharType>(varPtr.getType())) {
- llvm::errs() << "Is a basebox type\n";
OpBuilder::InsertPoint savedInsPoint = builder.saveInsertionPoint();
mlir::Block *allocaBlock = builder.getAllocaBlock();
assert(allocaBlock && "No allocablock found for a funcOp");
@@ -94,11 +93,12 @@ class MapsForPrivatizedSymbolsPass
StringAttr(), builder.getBoolAttr(false));
}
void addMapInfoOp(omp::TargetOp targetOp, omp::MapInfoOp mapInfoOp) {
- Location loc = targetOp.getLoc();
+ auto argIface = llvm::cast<omp::BlockArgOpenMPOpInterface>(*targetOp);
+ unsigned insertIndex =
+ argIface.getMapBlockArgsStart() + argIface.numMapBlockArgs();
targetOp.getMapVarsMutable().append(ValueRange{mapInfoOp});
- size_t numMapVars = targetOp.getMapVars().size();
- targetOp.getRegion().insertArgument(numMapVars - 1, mapInfoOp.getType(),
- loc);
+ targetOp.getRegion().insertArgument(insertIndex, mapInfoOp.getType(),
+ mapInfoOp.getLoc());
}
void addMapInfoOps(omp::TargetOp targetOp,
llvm::SmallVectorImpl<omp::MapInfoOp> &mapInfoOps) {
@@ -129,9 +129,7 @@ class MapsForPrivatizedSymbolsPass
}
builder.setInsertionPoint(targetOp);
Location loc = targetOp.getLoc();
- llvm::errs() << "Here\n";
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
- llvm::errs() << "Here again\n";
mapInfoOps.push_back(mapInfoOp);
LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n");
LLVM_DEBUG(mapInfoOp.dump());
>From 42d030bbaca47e75bb2b1bf437c3767601617df2 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Thu, 10 Oct 2024 14:54:44 -0500
Subject: [PATCH 11/12] Add some helpful comments
---
flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 7f3b00575fa82b..bdfd780a38922c 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -65,8 +65,16 @@ class MapsForPrivatizedSymbolsPass
auto declOp = llvm::dyn_cast_or_null<hlfir::DeclareOp>(definingOp);
assert(declOp &&
"Expected defining Op of privatized var to be hlfir.declare");
+
+ // We want the first result of the hlfir.declare op because our goal
+ // is to map the descriptor (fir.box or fir.boxchar) and the first
+ // result for hlfir.declare is the descriptor if a the symbol being
+ // decalred needs a descriptor.
Value varPtr = declOp.getBase();
+ // If we do not have a reference to descritor, but the descriptor itself
+ // then we need to store that on the stack so that we can map the
+ // address of the descriptor.
if (mlir::isa<fir::BaseBoxType>(varPtr.getType()) ||
mlir::isa<fir::BoxCharType>(varPtr.getType())) {
OpBuilder::InsertPoint savedInsPoint = builder.saveInsertionPoint();
>From 03503184fdfcb8ac91a6fbbf7ba22c2f37d18c21 Mon Sep 17 00:00:00 2001
From: Pranav Bhandarkar <pranav.bhandarkar at amd.com>
Date: Thu, 10 Oct 2024 15:01:21 -0500
Subject: [PATCH 12/12] Reduce test per Kareems review
---
.../omp-maps-for-privatized-symbols.fir | 35 -------------------
1 file changed, 35 deletions(-)
diff --git a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
index 9bd54611893e32..d32444aaabf237 100644
--- a/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
+++ b/flang/test/Transforms/omp-maps-for-privatized-symbols.fir
@@ -4,43 +4,8 @@ module attributes {omp.is_target_device = false} {
^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>):
%0 = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "simple_var", pinned, uniq_name = "_QFtarget_simpleEsimple_var"}
%1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- %2 = fir.box_addr %1 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
- %3 = fir.convert %2 : (!fir.heap<i32>) -> i64
- %c0_i64 = arith.constant 0 : i64
- %4 = arith.cmpi ne, %3, %c0_i64 : i64
- fir.if %4 {
- %6 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- %7 = fir.box_addr %6 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
- %8 = fir.allocmem i32 {fir.must_be_heap = true, uniq_name = "_QFtarget_simpleEsimple_var.alloc"}
- %9 = fir.embox %8 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
- fir.store %9 to %0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- } else {
- %6 = fir.zero_bits !fir.heap<i32>
- %7 = fir.embox %6 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
- fir.store %7 to %0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- }
%5:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtarget_simpleEsimple_var"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
omp.yield(%5#0 : !fir.ref<!fir.box<!fir.heap<i32>>>)
- } dealloc {
- ^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>):
- %0 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- %1 = fir.box_addr %0 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
- %2 = fir.convert %1 : (!fir.heap<i32>) -> i64
- %c0_i64 = arith.constant 0 : i64
- %3 = arith.cmpi ne, %2, %c0_i64 : i64
- fir.if %3 {
- %false = arith.constant false
- %4 = fir.absent !fir.box<none>
- %c70 = arith.constant 70 : index
- %c10_i32 = arith.constant 10 : i32
- %6 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- %7 = fir.box_addr %6 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
- fir.freemem %7 : !fir.heap<i32>
- %8 = fir.zero_bits !fir.heap<i32>
- %9 = fir.embox %8 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
- fir.store %9 to %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
- }
- omp.yield
}
func.func @_QPtarget_simple() {
%0 = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFtarget_simpleEa"}
More information about the flang-commits
mailing list