Skip to content

Commit 11dad2f

Browse files
[flang][OpenMP] - Add MapInfoOp instances for target private variables when needed (#109862)
This PR adds 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.
1 parent e6625a2 commit 11dad2f

File tree

8 files changed

+251
-14
lines changed

8 files changed

+251
-14
lines changed

flang/include/flang/Optimizer/OpenMP/Passes.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ def MapInfoFinalizationPass
2222
let dependentDialects = ["mlir::omp::OpenMPDialect"];
2323
}
2424

25+
def MapsForPrivatizedSymbolsPass
26+
: Pass<"omp-maps-for-privatized-symbols", "mlir::func::FuncOp"> {
27+
let summary = "Creates MapInfoOp instances for privatized symbols when needed";
28+
let description = [{
29+
Adds omp.map.info operations for privatized symbols on omp.target ops
30+
In certain situations, such as when an allocatable is privatized, its
31+
descriptor is needed in the alloc region of the privatizer. This results
32+
in the use of the descriptor inside the target region. As such, the
33+
descriptor then needs to be mapped. This pass adds such MapInfoOp operations.
34+
}];
35+
let dependentDialects = ["mlir::omp::OpenMPDialect"];
36+
}
37+
2538
def MarkDeclareTargetPass
2639
: Pass<"omp-mark-declare-target", "mlir::ModuleOp"> {
2740
let summary = "Marks all functions called by an OpenMP declare target function as declare target";

flang/lib/Optimizer/OpenMP/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
22

33
add_flang_library(FlangOpenMPTransforms
44
FunctionFiltering.cpp
5+
MapsForPrivatizedSymbols.cpp
56
MapInfoFinalization.cpp
67
MarkDeclareTarget.cpp
78

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
//===- MapsForPrivatizedSymbols.cpp
2+
//-----------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
//===----------------------------------------------------------------------===//
11+
/// \file
12+
/// An OpenMP dialect related pass for FIR/HLFIR which creates MapInfoOp
13+
/// instances for certain privatized symbols.
14+
/// For example, if an allocatable variable is used in a private clause attached
15+
/// to a omp.target op, then the allocatable variable's descriptor will be
16+
/// needed on the device (e.g. GPU). This descriptor needs to be separately
17+
/// mapped onto the device. This pass creates the necessary omp.map.info ops for
18+
/// this.
19+
//===----------------------------------------------------------------------===//
20+
// TODO:
21+
// 1. Before adding omp.map.info, check if we already have an omp.map.info for
22+
// the variable in question.
23+
// 2. Generalize this for more than just omp.target ops.
24+
//===----------------------------------------------------------------------===//
25+
26+
#include "flang/Optimizer/Builder/FIRBuilder.h"
27+
#include "flang/Optimizer/Dialect/FIRType.h"
28+
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
29+
#include "flang/Optimizer/HLFIR/HLFIROps.h"
30+
#include "flang/Optimizer/OpenMP/Passes.h"
31+
#include "mlir/Dialect/Func/IR/FuncOps.h"
32+
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
33+
#include "mlir/IR/BuiltinAttributes.h"
34+
#include "mlir/IR/SymbolTable.h"
35+
#include "mlir/Pass/Pass.h"
36+
#include "llvm/Frontend/OpenMP/OMPConstants.h"
37+
#include "llvm/Support/Debug.h"
38+
#include <type_traits>
39+
40+
#define DEBUG_TYPE "omp-maps-for-privatized-symbols"
41+
42+
namespace flangomp {
43+
#define GEN_PASS_DEF_MAPSFORPRIVATIZEDSYMBOLSPASS
44+
#include "flang/Optimizer/OpenMP/Passes.h.inc"
45+
} // namespace flangomp
46+
using namespace mlir;
47+
namespace {
48+
class MapsForPrivatizedSymbolsPass
49+
: public flangomp::impl::MapsForPrivatizedSymbolsPassBase<
50+
MapsForPrivatizedSymbolsPass> {
51+
52+
bool privatizerNeedsMap(omp::PrivateClauseOp &privatizer) {
53+
Region &allocRegion = privatizer.getAllocRegion();
54+
Value blockArg0 = allocRegion.getArgument(0);
55+
if (blockArg0.use_empty())
56+
return false;
57+
return true;
58+
}
59+
omp::MapInfoOp createMapInfo(Location loc, Value var,
60+
fir::FirOpBuilder &builder) {
61+
uint64_t mapTypeTo = static_cast<
62+
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
63+
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO);
64+
Operation *definingOp = var.getDefiningOp();
65+
auto declOp = llvm::dyn_cast_or_null<hlfir::DeclareOp>(definingOp);
66+
assert(declOp &&
67+
"Expected defining Op of privatized var to be hlfir.declare");
68+
69+
// We want the first result of the hlfir.declare op because our goal
70+
// is to map the descriptor (fir.box or fir.boxchar) and the first
71+
// result for hlfir.declare is the descriptor if a the symbol being
72+
// decalred needs a descriptor.
73+
Value varPtr = declOp.getBase();
74+
75+
// If we do not have a reference to descritor, but the descriptor itself
76+
// then we need to store that on the stack so that we can map the
77+
// address of the descriptor.
78+
if (mlir::isa<fir::BaseBoxType>(varPtr.getType()) ||
79+
mlir::isa<fir::BoxCharType>(varPtr.getType())) {
80+
OpBuilder::InsertPoint savedInsPoint = builder.saveInsertionPoint();
81+
mlir::Block *allocaBlock = builder.getAllocaBlock();
82+
assert(allocaBlock && "No allocablock found for a funcOp");
83+
builder.setInsertionPointToStart(allocaBlock);
84+
auto alloca = builder.create<fir::AllocaOp>(loc, varPtr.getType());
85+
builder.restoreInsertionPoint(savedInsPoint);
86+
builder.create<fir::StoreOp>(loc, varPtr, alloca);
87+
varPtr = alloca;
88+
}
89+
return builder.create<omp::MapInfoOp>(
90+
loc, varPtr.getType(), varPtr,
91+
TypeAttr::get(llvm::cast<omp::PointerLikeType>(varPtr.getType())
92+
.getElementType()),
93+
/*varPtrPtr=*/Value{},
94+
/*members=*/SmallVector<Value>{},
95+
/*member_index=*/DenseIntElementsAttr{},
96+
/*bounds=*/ValueRange{},
97+
builder.getIntegerAttr(builder.getIntegerType(64, /*isSigned=*/false),
98+
mapTypeTo),
99+
builder.getAttr<omp::VariableCaptureKindAttr>(
100+
omp::VariableCaptureKind::ByRef),
101+
StringAttr(), builder.getBoolAttr(false));
102+
}
103+
void addMapInfoOp(omp::TargetOp targetOp, omp::MapInfoOp mapInfoOp) {
104+
auto argIface = llvm::cast<omp::BlockArgOpenMPOpInterface>(*targetOp);
105+
unsigned insertIndex =
106+
argIface.getMapBlockArgsStart() + argIface.numMapBlockArgs();
107+
targetOp.getMapVarsMutable().append(ValueRange{mapInfoOp});
108+
targetOp.getRegion().insertArgument(insertIndex, mapInfoOp.getType(),
109+
mapInfoOp.getLoc());
110+
}
111+
void addMapInfoOps(omp::TargetOp targetOp,
112+
llvm::SmallVectorImpl<omp::MapInfoOp> &mapInfoOps) {
113+
for (auto mapInfoOp : mapInfoOps)
114+
addMapInfoOp(targetOp, mapInfoOp);
115+
}
116+
void runOnOperation() override {
117+
ModuleOp module = getOperation()->getParentOfType<ModuleOp>();
118+
fir::KindMapping kindMap = fir::getKindMapping(module);
119+
fir::FirOpBuilder builder{module, std::move(kindMap)};
120+
llvm::DenseMap<Operation *, llvm::SmallVector<omp::MapInfoOp, 4>>
121+
mapInfoOpsForTarget;
122+
123+
getOperation()->walk([&](omp::TargetOp targetOp) {
124+
if (targetOp.getPrivateVars().empty())
125+
return;
126+
OperandRange privVars = targetOp.getPrivateVars();
127+
std::optional<ArrayAttr> privSyms = targetOp.getPrivateSyms();
128+
SmallVector<omp::MapInfoOp, 4> mapInfoOps;
129+
for (auto [privVar, privSym] : llvm::zip_equal(privVars, *privSyms)) {
130+
131+
SymbolRefAttr privatizerName = llvm::cast<SymbolRefAttr>(privSym);
132+
omp::PrivateClauseOp privatizer =
133+
SymbolTable::lookupNearestSymbolFrom<omp::PrivateClauseOp>(
134+
targetOp, privatizerName);
135+
if (!privatizerNeedsMap(privatizer)) {
136+
continue;
137+
}
138+
builder.setInsertionPoint(targetOp);
139+
Location loc = targetOp.getLoc();
140+
omp::MapInfoOp mapInfoOp = createMapInfo(loc, privVar, builder);
141+
mapInfoOps.push_back(mapInfoOp);
142+
LLVM_DEBUG(llvm::dbgs() << "MapsForPrivatizedSymbolsPass created ->\n");
143+
LLVM_DEBUG(mapInfoOp.dump());
144+
}
145+
if (!mapInfoOps.empty()) {
146+
mapInfoOpsForTarget.insert({targetOp.getOperation(), mapInfoOps});
147+
}
148+
});
149+
if (!mapInfoOpsForTarget.empty()) {
150+
for (auto &[targetOp, mapInfoOps] : mapInfoOpsForTarget) {
151+
addMapInfoOps(static_cast<omp::TargetOp>(targetOp), mapInfoOps);
152+
}
153+
}
154+
}
155+
};
156+
} // namespace

flang/lib/Optimizer/Passes/Pipelines.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm,
243243
/// rather than the host device.
244244
void createOpenMPFIRPassPipeline(mlir::PassManager &pm, bool isTargetDevice) {
245245
pm.addPass(flangomp::createMapInfoFinalizationPass());
246+
pm.addPass(flangomp::createMapsForPrivatizedSymbolsPass());
246247
pm.addPass(flangomp::createMarkDeclareTargetPass());
247248
if (isTargetDevice)
248249
pm.addPass(flangomp::createFunctionFilteringPass());

flang/test/Lower/OpenMP/DelayedPrivatization/target-private-allocatable.f90

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,22 @@ end subroutine target_allocatable
1818
! CHECK-SAME: @[[VAR_PRIVATIZER_SYM:.*]] :
1919
! CHECK-SAME: [[TYPE:!fir.ref<!fir.box<!fir.heap<i32>>>]] alloc {
2020
! CHECK: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]):
21-
! CHECK: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "alloc_var", {{.*}}}
21+
! CHECK: %[[PRIV_ALLOC:.*]] = fir.alloca [[DESC_TYPE:!fir.box<!fir.heap<i32>>]] {bindc_name = "alloc_var", {{.*}}}
2222

23-
! CHECK-NEXT: %[[PRIV_ARG_VAL:.*]] = fir.load %[[PRIV_ARG]] : !fir.ref<!fir.box<!fir.heap<i32>>>
24-
! CHECK-NEXT: %[[PRIV_ARG_BOX:.*]] = fir.box_addr %[[PRIV_ARG_VAL]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
23+
! CHECK-NEXT: %[[PRIV_ARG_VAL:.*]] = fir.load %[[PRIV_ARG]] : [[TYPE]]
24+
! CHECK-NEXT: %[[PRIV_ARG_BOX:.*]] = fir.box_addr %[[PRIV_ARG_VAL]] : ([[DESC_TYPE]]) -> !fir.heap<i32>
2525
! CHECK-NEXT: %[[PRIV_ARG_ADDR:.*]] = fir.convert %[[PRIV_ARG_BOX]] : (!fir.heap<i32>) -> i64
2626
! CHECK-NEXT: %[[C0:.*]] = arith.constant 0 : i64
2727
! CHECK-NEXT: %[[ALLOC_COND:.*]] = arith.cmpi ne, %[[PRIV_ARG_ADDR]], %[[C0]] : i64
2828

2929
! CHECK-NEXT: fir.if %[[ALLOC_COND]] {
3030
! CHECK: %[[PRIV_ALLOCMEM:.*]] = fir.allocmem i32 {fir.must_be_heap = true, {{.*}}}
31-
! CHECK-NEXT: %[[PRIV_ALLOCMEM_BOX:.*]] = fir.embox %[[PRIV_ALLOCMEM]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
32-
! CHECK-NEXT: fir.store %[[PRIV_ALLOCMEM_BOX]] to %[[PRIV_ALLOC]] : !fir.ref<!fir.box<!fir.heap<i32>>>
31+
! CHECK-NEXT: %[[PRIV_ALLOCMEM_BOX:.*]] = fir.embox %[[PRIV_ALLOCMEM]] : (!fir.heap<i32>) -> [[DESC_TYPE]]
32+
! CHECK-NEXT: fir.store %[[PRIV_ALLOCMEM_BOX]] to %[[PRIV_ALLOC]] : [[TYPE]]
3333
! CHECK-NEXT: } else {
3434
! CHECK-NEXT: %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<i32>
35-
! CHECK-NEXT: %[[ZERO_BOX:.*]] = fir.embox %[[ZERO_BITS]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
36-
! CHECK-NEXT: fir.store %[[ZERO_BOX]] to %[[PRIV_ALLOC]] : !fir.ref<!fir.box<!fir.heap<i32>>>
35+
! CHECK-NEXT: %[[ZERO_BOX:.*]] = fir.embox %[[ZERO_BITS]] : (!fir.heap<i32>) -> [[DESC_TYPE]]
36+
! CHECK-NEXT: fir.store %[[ZERO_BOX]] to %[[PRIV_ALLOC]] : [[TYPE]]
3737
! CHECK-NEXT: }
3838

3939
! CHECK-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]]
@@ -63,9 +63,11 @@ end subroutine target_allocatable
6363

6464
! CHECK-LABEL: func.func @_QPtarget_allocatable() {
6565

66-
! CHECK: %[[VAR_ALLOC:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
66+
! CHECK: %[[VAR_ALLOC:.*]] = fir.alloca [[DESC_TYPE]]
6767
! CHECK-SAME: {bindc_name = "alloc_var", {{.*}}}
6868
! CHECK: %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_ALLOC]]
6969

70-
! CHECK: omp.target private(
70+
! CHECK: %[[MAP_VAR:.*]] = omp.map.info var_ptr(%[[VAR_DECL]]#0 : [[TYPE]], [[DESC_TYPE]])
71+
! CHECK-SAME: map_clauses(to) capture(ByRef) -> [[TYPE]]
72+
! CHECK: omp.target map_entries(%[[MAP_VAR]] -> %arg0 : [[TYPE]]) private(
7173
! CHECK-SAME: @[[VAR_PRIVATIZER_SYM]] %[[VAR_DECL]]#0 -> %{{.*}} : [[TYPE]]) {

flang/test/Lower/OpenMP/DelayedPrivatization/target-private-multiple-variables.f90

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,29 @@ end subroutine target_allocatable
147147
! CHECK-NEXT: }
148148

149149
! CHECK: func.func @_QPtarget_allocatable
150+
! CHECK: %[[CHAR_VAR_DESC_ALLOCA:.*]] = fir.alloca !fir.boxchar<1>
151+
! CHECK: %[[REAL_ARR_DESC_ALLOCA:.*]] = fir.alloca !fir.box<!fir.array<?xf32>>
152+
! CHECK: %[[ALLOC_VAR_ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "alloc_var", {{.*}}}
153+
! CHECK: %[[ALLOC_VAR_DECL:.*]]:2 = hlfir.declare %[[ALLOC_VAR_ALLOCA]]
150154
! CHECK: %[[MAPPED_ALLOC:.*]] = fir.alloca i32 {bindc_name = "mapped_var", {{.*}}}
151155
! CHECK-NEXT: %[[MAPPED_DECL:.*]]:2 = hlfir.declare %[[MAPPED_ALLOC]]
152-
! CHECK: %[[MAPPED_MI:.*]] = omp.map.info var_ptr(%[[MAPPED_DECL]]#1 : !fir.ref<i32>, i32)
153-
156+
! CHECK: %[[CHAR_VAR_ALLOC:.*]] = fir.alloca !fir.char<1,?>{{.*}} {bindc_name = "char_var", {{.*}}}
157+
! CHECK: %[[CHAR_VAR_DECL:.*]]:2 = hlfir.declare %[[CHAR_VAR_ALLOC]] typeparams
158+
! CHECK: %[[REAL_ARR_ALLOC:.*]] = fir.alloca !fir.array<?xf32>, {{.*}} {bindc_name = "real_arr", {{.*}}}
159+
! CHECK: %[[REAL_ARR_DECL:.*]]:2 = hlfir.declare %[[REAL_ARR_ALLOC]]({{.*}})
160+
! CHECK: %[[MAPPED_MI0:.*]] = omp.map.info var_ptr(%[[MAPPED_DECL]]#1 : !fir.ref<i32>, i32) {{.*}}
161+
! 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>>)
162+
! CHECK: fir.store %[[REAL_ARR_DECL]]#0 to %[[REAL_ARR_DESC_ALLOCA]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
163+
! 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>>)
164+
! CHECK: fir.store %[[CHAR_VAR_DECL]]#0 to %[[CHAR_VAR_DESC_ALLOCA]] : !fir.ref<!fir.boxchar<1>>
165+
! CHECK: %[[CHAR_VAR_DESC_MAP:.*]] = omp.map.info var_ptr(%[[CHAR_VAR_DESC_ALLOCA]] : !fir.ref<!fir.boxchar<1>>, !fir.boxchar<1>)
154166
! CHECK: omp.target
155-
! CHECK-SAME: map_entries(%[[MAPPED_MI]] -> %[[MAPPED_ARG:.*]] : !fir.ref<i32>)
167+
! CHECK-SAME: map_entries(
168+
! CHECK-SAME: %[[MAPPED_MI0]] -> %[[MAPPED_ARG0:[^,]+]],
169+
! CHECK-SAME: %[[ALLOC_VAR_MAP]] -> %[[MAPPED_ARG1:[^,]+]]
170+
! CHECK-SAME %[[REAL_ARR_DESC_MAP]] -> %[[MAPPED_ARG2:[^,]+]]
171+
! CHECK_SAME %[[CHAR_VAR_DESC_MAP]] -> %[[MAPPED_ARG3:.[^,]+]] :
172+
! CHECK-SAME !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.array<?xf32>>>, !fir.ref<!fir.boxchar<1>>)
156173
! CHECK-SAME: private(
157174
! CHECK-SAME: @[[ALLOC_PRIVATIZER_SYM]] %{{[^[:space:]]+}}#0 -> %[[ALLOC_ARG:[^,]+]],
158175
! CHECK-SAME: @[[REAL_PRIVATIZER_SYM]] %{{[^[:space:]]+}}#0 -> %[[REAL_ARG:[^,]+]],
@@ -162,7 +179,6 @@ end subroutine target_allocatable
162179
! CHECK-SAME: @[[CHAR_PRIVATIZER_SYM]] %{{[^[:space:]]+}}#0 -> %[[CHAR_ARG:[^,]+]] :
163180
! CHECK-SAME: !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<f32>, !fir.ref<i64>, !fir.box<!fir.array<?xf32>>, !fir.ref<complex<f32>>, !fir.boxchar<1>) {
164181
! CHECK-NOT: fir.alloca
165-
! CHECK: hlfir.declare %[[MAPPED_ARG]]
166182
! CHECK: hlfir.declare %[[ALLOC_ARG]]
167183
! CHECK: hlfir.declare %[[REAL_ARG]]
168184
! CHECK: hlfir.declare %[[LB_ARG]]
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: fir-opt --split-input-file --omp-maps-for-privatized-symbols %s | FileCheck %s
2+
module attributes {omp.is_target_device = false} {
3+
omp.private {type = private} @_QFtarget_simpleEsimple_var_private_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> alloc {
4+
^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>):
5+
%0 = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "simple_var", pinned, uniq_name = "_QFtarget_simpleEsimple_var"}
6+
%1 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<i32>>>
7+
%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>>>)
8+
omp.yield(%5#0 : !fir.ref<!fir.box<!fir.heap<i32>>>)
9+
}
10+
func.func @_QPtarget_simple() {
11+
%0 = fir.alloca i32 {bindc_name = "a", uniq_name = "_QFtarget_simpleEa"}
12+
%1:2 = hlfir.declare %0 {uniq_name = "_QFtarget_simpleEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
13+
%2 = fir.alloca !fir.box<!fir.heap<i32>> {bindc_name = "simple_var", uniq_name = "_QFtarget_simpleEsimple_var"}
14+
%3 = fir.zero_bits !fir.heap<i32>
15+
%4 = fir.embox %3 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
16+
fir.store %4 to %2 : !fir.ref<!fir.box<!fir.heap<i32>>>
17+
%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>>>)
18+
%c2_i32 = arith.constant 2 : i32
19+
hlfir.assign %c2_i32 to %1#0 : i32, !fir.ref<i32>
20+
%6 = omp.map.info var_ptr(%1#1 : !fir.ref<i32>, i32) map_clauses(to) capture(ByRef) -> !fir.ref<i32> {name = "a"}
21+
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>>>) {
22+
%11:2 = hlfir.declare %arg0 {uniq_name = "_QFtarget_simpleEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
23+
%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>>>)
24+
%c10_i32 = arith.constant 10 : i32
25+
%13 = fir.load %11#0 : !fir.ref<i32>
26+
%14 = arith.addi %c10_i32, %13 : i32
27+
hlfir.assign %14 to %12#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<i32>>>
28+
omp.terminator
29+
}
30+
%7 = fir.load %5#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
31+
%8 = fir.box_addr %7 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
32+
%9 = fir.convert %8 : (!fir.heap<i32>) -> i64
33+
%c0_i64 = arith.constant 0 : i64
34+
%10 = arith.cmpi ne, %9, %c0_i64 : i64
35+
fir.if %10 {
36+
%11 = fir.load %5#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
37+
%12 = fir.box_addr %11 : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
38+
fir.freemem %12 : !fir.heap<i32>
39+
%13 = fir.zero_bits !fir.heap<i32>
40+
%14 = fir.embox %13 : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
41+
fir.store %14 to %5#1 : !fir.ref<!fir.box<!fir.heap<i32>>>
42+
}
43+
return
44+
}
45+
}
46+
// CHECK: %[[MAP0:.*]] = omp.map.info var_ptr({{.*}} : !fir.ref<i32>, i32) map_clauses(to) capture(ByRef) -> !fir.ref<i32> {name = "a"}
47+
// 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>>>
48+
// CHECK: omp.target map_entries(%[[MAP0]] -> %arg0, %[[MAP1]] -> %arg1 : !fir.ref<i32>, !fir.ref<!fir.box<!fir.heap<i32>>>)

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ def MapInfoOp : OpenMP_Op<"map.info", [AttrSizedOperandSegments]> {
948948
objects (e.g. derived types or classes), indicates the bounds to be copied
949949
of the variable. When it's an array slice it is in rank order where rank 0
950950
is the inner-most dimension.
951-
- 'map_clauses': OpenMP map type for this map capture, for example: from, to and
951+
- 'map_type': OpenMP map type for this map capture, for example: from, to and
952952
always. It's a bitfield composed of the OpenMP runtime flags stored in
953953
OpenMPOffloadMappingFlags.
954954
- 'map_capture_type': Capture type for the variable e.g. this, byref, byvalue, byvla

0 commit comments

Comments
 (0)