Skip to content

Commit ccc3c58

Browse files
committed
[flang][OpenMP] Create one utility for mapping temporary values to target
Similar to llvm#1993, this PR adds a shared util to map temporary values. This util is needed by both OpenMP lowering as well as `do concurrent` to OpenMP mapping.
1 parent 8193e42 commit ccc3c58

File tree

4 files changed

+87
-107
lines changed

4 files changed

+87
-107
lines changed

flang/include/flang/Support/OpenMP-utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ mlir::omp::MapInfoOp createMapInfoOp(mlir::OpBuilder &builder,
8383
uint64_t mapType, mlir::omp::VariableCaptureKind mapCaptureType,
8484
mlir::Type retTy, bool partialMap = false,
8585
mlir::FlatSymbolRefAttr mapperId = mlir::FlatSymbolRefAttr());
86+
87+
mlir::Value mapTemporaryValue(fir::FirOpBuilder &firOpBuilder,
88+
mlir::omp::TargetOp targetOp, mlir::Value val, llvm::StringRef name);
8689
} // namespace Fortran::common::openmp
8790

8891
#endif // FORTRAN_SUPPORT_OPENMP_UTILS_H_

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 6 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,70 +1372,12 @@ static void genBodyOfTargetOp(
13721372
valOp->getResults().replaceUsesWithIf(clonedOp->getResults(), replace);
13731373
valOp->replaceUsesWithIf(clonedOp, replace);
13741374
} else {
1375-
auto savedIP = firOpBuilder.getInsertionPoint();
1376-
firOpBuilder.setInsertionPointAfter(valOp);
1377-
auto copyVal =
1378-
firOpBuilder.createTemporary(val.getLoc(), val.getType());
1379-
firOpBuilder.createStoreWithConvert(copyVal.getLoc(), val, copyVal);
1380-
1381-
fir::factory::AddrAndBoundsInfo info =
1382-
fir::factory::getDataOperandBaseAddr(
1383-
firOpBuilder, val, /*isOptional=*/false, val.getLoc());
1384-
llvm::SmallVector<mlir::Value> bounds =
1385-
fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
1386-
mlir::omp::MapBoundsType>(
1387-
firOpBuilder, info,
1388-
hlfir::translateToExtendedValue(val.getLoc(), firOpBuilder,
1389-
hlfir::Entity{val})
1390-
.first,
1391-
/*dataExvIsAssumedSize=*/false, val.getLoc());
1392-
1393-
std::stringstream name;
1394-
firOpBuilder.setInsertionPoint(targetOp);
1395-
1396-
llvm::omp::OpenMPOffloadMappingFlags mapFlag =
1397-
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
1398-
mlir::omp::VariableCaptureKind captureKind =
1399-
mlir::omp::VariableCaptureKind::ByRef;
1400-
1401-
mlir::Type eleType = copyVal.getType();
1402-
if (auto refType =
1403-
mlir::dyn_cast<fir::ReferenceType>(copyVal.getType()))
1404-
eleType = refType.getElementType();
1405-
1406-
if (fir::isa_trivial(eleType) || fir::isa_char(eleType)) {
1407-
captureKind = mlir::omp::VariableCaptureKind::ByCopy;
1408-
} else if (!fir::isa_builtin_cptr_type(eleType)) {
1409-
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
1410-
}
1411-
1412-
mlir::Value mapOp = Fortran::common::openmp::createMapInfoOp(
1413-
firOpBuilder, copyVal.getLoc(), copyVal,
1414-
/*varPtrPtr=*/mlir::Value{}, name.str(), bounds,
1415-
/*members=*/llvm::SmallVector<mlir::Value>{},
1416-
/*membersIndex=*/mlir::ArrayAttr{},
1417-
static_cast<
1418-
std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
1419-
mapFlag),
1420-
captureKind, copyVal.getType());
1421-
1422-
// Get the index of the first non-map argument before modifying mapVars,
1423-
// then append an element to mapVars and an associated entry block
1424-
// argument at that index.
1425-
unsigned insertIndex =
1426-
argIface.getMapBlockArgsStart() + argIface.numMapBlockArgs();
1427-
targetOp.getMapVarsMutable().append(mapOp);
1428-
mlir::Value clonedValArg = region.insertArgument(
1429-
insertIndex, copyVal.getType(), copyVal.getLoc());
1430-
1431-
firOpBuilder.setInsertionPointToStart(entryBlock);
1432-
auto loadOp = firOpBuilder.create<fir::LoadOp>(clonedValArg.getLoc(),
1433-
clonedValArg);
1434-
val.replaceUsesWithIf(loadOp->getResult(0),
1435-
[entryBlock](mlir::OpOperand &use) {
1436-
return use.getOwner()->getBlock() == entryBlock;
1437-
});
1438-
firOpBuilder.setInsertionPoint(entryBlock, savedIP);
1375+
mlir::Value mappedTemp = Fortran::common::openmp::mapTemporaryValue(
1376+
firOpBuilder, targetOp, val,
1377+
/*name=*/{});
1378+
val.replaceUsesWithIf(mappedTemp, [entryBlock](mlir::OpOperand &use) {
1379+
return use.getOwner()->getBlock() == entryBlock;
1380+
});
14391381
}
14401382
}
14411383
valuesDefinedAbove.clear();

flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -43,41 +43,6 @@ namespace Fortran {
4343
namespace lower {
4444
namespace omp {
4545
namespace internal {
46-
mlir::Value mapTemporaryValue(fir::FirOpBuilder &builder,
47-
mlir::omp::TargetOp targetOp, mlir::Value val,
48-
llvm::StringRef name) {
49-
mlir::OpBuilder::InsertionGuard guard(builder);
50-
builder.setInsertionPointAfterValue(val);
51-
auto copyVal = builder.createTemporary(val.getLoc(), val.getType());
52-
builder.createStoreWithConvert(copyVal.getLoc(), val, copyVal);
53-
54-
llvm::SmallVector<mlir::Value> bounds;
55-
builder.setInsertionPoint(targetOp);
56-
mlir::Value mapOp = Fortran::common::openmp::createMapInfoOp(
57-
builder, copyVal.getLoc(), copyVal,
58-
/*varPtrPtr=*/mlir::Value{}, name.str(), bounds,
59-
/*members=*/llvm::SmallVector<mlir::Value>{},
60-
/*membersIndex=*/mlir::ArrayAttr{},
61-
static_cast<std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
62-
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT),
63-
mlir::omp::VariableCaptureKind::ByCopy, copyVal.getType());
64-
65-
mlir::Region &targetRegion = targetOp.getRegion();
66-
67-
auto argIface = llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(*targetOp);
68-
unsigned insertIndex =
69-
argIface.getMapBlockArgsStart() + argIface.numMapBlockArgs();
70-
targetOp.getMapVarsMutable().append(mlir::ValueRange{mapOp});
71-
mlir::Value clonedValArg =
72-
targetRegion.insertArgument(insertIndex, mapOp.getType(), mapOp.getLoc());
73-
74-
mlir::Block *targetEntryBlock = &targetRegion.getBlocks().front();
75-
builder.setInsertionPointToStart(targetEntryBlock);
76-
auto loadOp =
77-
builder.create<fir::LoadOp>(clonedValArg.getLoc(), clonedValArg);
78-
return loadOp.getResult();
79-
}
80-
8146
/// Check if cloning the bounds introduced any dependency on the outer region.
8247
/// If so, then either clone them as well if they are MemoryEffectFree, or else
8348
/// copy them to a new temporary and add them to the map and block_argument
@@ -106,8 +71,9 @@ void cloneOrMapRegionOutsiders(fir::FirOpBuilder &builder,
10671
return use.getOwner()->getBlock() == targetEntryBlock;
10772
});
10873
} else {
109-
mlir::Value mappedTemp = mapTemporaryValue(builder, targetOp, val,
110-
/*name=*/llvm::StringRef{});
74+
mlir::Value mappedTemp = Fortran::common::openmp::mapTemporaryValue(
75+
builder, targetOp, val,
76+
/*name=*/llvm::StringRef{});
11177
val.replaceUsesWithIf(
11278
mappedTemp, [targetEntryBlock](mlir::OpOperand &use) {
11379
return use.getOwner()->getBlock() == targetEntryBlock;
@@ -732,11 +698,11 @@ class DoConcurrentConversion
732698
llvm::zip_equal(targetShapeCreationInfo.startIndices,
733699
targetShapeCreationInfo.extents)) {
734700
shapeShiftOperands.push_back(
735-
Fortran::lower::omp::internal::mapTemporaryValue(
701+
Fortran::common::openmp::mapTemporaryValue(
736702
builder, targetOp, startIndex,
737703
liveInName + ".start_idx.dim" + std::to_string(shapeIdx)));
738704
shapeShiftOperands.push_back(
739-
Fortran::lower::omp::internal::mapTemporaryValue(
705+
Fortran::common::openmp::mapTemporaryValue(
740706
builder, targetOp, extent,
741707
liveInName + ".extent.dim" + std::to_string(shapeIdx)));
742708
++shapeIdx;
@@ -751,10 +717,9 @@ class DoConcurrentConversion
751717
llvm::SmallVector<mlir::Value> shapeOperands;
752718
size_t shapeIdx = 0;
753719
for (auto extent : targetShapeCreationInfo.extents) {
754-
shapeOperands.push_back(
755-
Fortran::lower::omp::internal::mapTemporaryValue(
756-
builder, targetOp, extent,
757-
liveInName + ".extent.dim" + std::to_string(shapeIdx)));
720+
shapeOperands.push_back(Fortran::common::openmp::mapTemporaryValue(
721+
builder, targetOp, extent,
722+
liveInName + ".extent.dim" + std::to_string(shapeIdx)));
758723
++shapeIdx;
759724
}
760725

flang/lib/Support/OpenMP-utils.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "flang/Support/OpenMP-utils.h"
10+
#include "flang/Optimizer/Builder/DirectivesCommon.h"
11+
#include "flang/Optimizer/Builder/FIRBuilder.h"
12+
#include "flang/Optimizer/Builder/HLFIRTools.h"
1013

1114
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
1215
#include "mlir/IR/OpDefinition.h"
1316

17+
#include "llvm/Frontend/OpenMP/OMPConstants.h"
18+
1419
namespace Fortran::common::openmp {
1520
mlir::Block *genEntryBlock(mlir::OpBuilder &builder, const EntryBlockArgs &args,
1621
mlir::Region &region) {
@@ -79,4 +84,69 @@ mlir::omp::MapInfoOp createMapInfoOp(mlir::OpBuilder &builder,
7984
builder.getStringAttr(name), builder.getBoolAttr(partialMap));
8085
return op;
8186
}
87+
88+
mlir::Value mapTemporaryValue(fir::FirOpBuilder &firOpBuilder,
89+
mlir::omp::TargetOp targetOp, mlir::Value val, llvm::StringRef name) {
90+
mlir::OpBuilder::InsertionGuard guard(firOpBuilder);
91+
92+
firOpBuilder.setInsertionPointAfterValue(val);
93+
auto copyVal = firOpBuilder.createTemporary(val.getLoc(), val.getType());
94+
firOpBuilder.createStoreWithConvert(copyVal.getLoc(), val, copyVal);
95+
96+
fir::factory::AddrAndBoundsInfo info = fir::factory::getDataOperandBaseAddr(
97+
firOpBuilder, val, /*isOptional=*/false, val.getLoc());
98+
llvm::SmallVector<mlir::Value> bounds =
99+
fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
100+
mlir::omp::MapBoundsType>(firOpBuilder, info,
101+
hlfir::translateToExtendedValue(
102+
val.getLoc(), firOpBuilder, hlfir::Entity{val})
103+
.first,
104+
/*dataExvIsAssumedSize=*/false, val.getLoc());
105+
106+
firOpBuilder.setInsertionPoint(targetOp);
107+
108+
llvm::omp::OpenMPOffloadMappingFlags mapFlag =
109+
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_IMPLICIT;
110+
mlir::omp::VariableCaptureKind captureKind =
111+
mlir::omp::VariableCaptureKind::ByRef;
112+
113+
mlir::Type eleType = copyVal.getType();
114+
if (auto refType = mlir::dyn_cast<fir::ReferenceType>(copyVal.getType())) {
115+
eleType = refType.getElementType();
116+
}
117+
118+
if (fir::isa_trivial(eleType) || fir::isa_char(eleType)) {
119+
captureKind = mlir::omp::VariableCaptureKind::ByCopy;
120+
} else if (!fir::isa_builtin_cptr_type(eleType)) {
121+
mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO;
122+
}
123+
124+
mlir::Value mapOp = Fortran::common::openmp::createMapInfoOp(firOpBuilder,
125+
copyVal.getLoc(), copyVal,
126+
/*varPtrPtr=*/mlir::Value{}, name.str(), bounds,
127+
/*members=*/llvm::SmallVector<mlir::Value>{},
128+
/*membersIndex=*/mlir::ArrayAttr{},
129+
static_cast<std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
130+
mapFlag),
131+
captureKind, copyVal.getType());
132+
133+
auto argIface = llvm::cast<mlir::omp::BlockArgOpenMPOpInterface>(*targetOp);
134+
mlir::Region &region = targetOp.getRegion();
135+
136+
// Get the index of the first non-map argument before modifying mapVars,
137+
// then append an element to mapVars and an associated entry block
138+
// argument at that index.
139+
unsigned insertIndex =
140+
argIface.getMapBlockArgsStart() + argIface.numMapBlockArgs();
141+
targetOp.getMapVarsMutable().append(mapOp);
142+
mlir::Value clonedValArg =
143+
region.insertArgument(insertIndex, copyVal.getType(), copyVal.getLoc());
144+
145+
mlir::Block *entryBlock = &region.getBlocks().front();
146+
firOpBuilder.setInsertionPointToStart(entryBlock);
147+
auto loadOp =
148+
firOpBuilder.create<fir::LoadOp>(clonedValArg.getLoc(), clonedValArg);
149+
return loadOp.getResult();
150+
}
151+
82152
} // namespace Fortran::common::openmp

0 commit comments

Comments
 (0)