aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/OpenMP
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/OpenMP')
-rw-r--r--flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp3
-rw-r--r--flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp67
-rw-r--r--flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp24
-rw-r--r--flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp137
4 files changed, 144 insertions, 87 deletions
diff --git a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
index 9aad8cd..1012a96 100644
--- a/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
+++ b/flang/lib/Optimizer/OpenMP/DoConcurrentConversion.cpp
@@ -848,7 +848,8 @@ private:
if (!ompReducer) {
ompReducer = mlir::omp::DeclareReductionOp::create(
rewriter, firReducer.getLoc(), ompReducerName,
- firReducer.getTypeAttr().getValue());
+ firReducer.getTypeAttr().getValue(),
+ firReducer.getByrefElementTypeAttr());
cloneFIRRegionToOMP(rewriter, firReducer.getAllocRegion(),
ompReducer.getAllocRegion());
diff --git a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
index d60da89..3fe133d 100644
--- a/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapInfoFinalization.cpp
@@ -347,10 +347,10 @@ class MapInfoFinalizationPass
/// base address (BoxOffsetOp) and a MapInfoOp for it. The most
/// important thing to note is that we normally move the bounds from
/// the descriptor map onto the base address map.
- mlir::omp::MapInfoOp genBaseAddrMap(mlir::Value descriptor,
- mlir::OperandRange bounds,
- mlir::omp::ClauseMapFlags mapType,
- fir::FirOpBuilder &builder) {
+ mlir::omp::MapInfoOp
+ genBaseAddrMap(mlir::Value descriptor, mlir::OperandRange bounds,
+ mlir::omp::ClauseMapFlags mapType, fir::FirOpBuilder &builder,
+ mlir::FlatSymbolRefAttr mapperId = mlir::FlatSymbolRefAttr()) {
mlir::Location loc = descriptor.getLoc();
mlir::Value baseAddrAddr = fir::BoxOffsetOp::create(
builder, loc, descriptor, fir::BoxFieldAttr::base_addr);
@@ -372,7 +372,7 @@ class MapInfoFinalizationPass
mlir::omp::VariableCaptureKind::ByRef),
baseAddrAddr, /*members=*/mlir::SmallVector<mlir::Value>{},
/*membersIndex=*/mlir::ArrayAttr{}, bounds,
- /*mapperId*/ mlir::FlatSymbolRefAttr(),
+ /*mapperId=*/mapperId,
/*name=*/builder.getStringAttr(""),
/*partial_map=*/builder.getBoolAttr(false));
}
@@ -437,6 +437,20 @@ class MapInfoFinalizationPass
mapFlags flags =
mapFlags::to | (mapTypeFlag & (mapFlags::implicit | mapFlags::always));
+
+ // Descriptors for objects will always be copied. This is because the
+ // descriptor can be rematerialized by the compiler, and so the address
+ // of the descriptor for a given object at one place in the code may
+ // differ from that address in another place. The contents of the
+ // descriptor (the base address in particular) will remain unchanged
+ // though.
+ // TODO/FIXME: We currently cannot have MAP_CLOSE and MAP_ALWAYS on
+ // the descriptor at once, these are mutually exclusive and when
+ // both are applied the runtime will fail to map.
+ flags |= ((mapFlags(mapTypeFlag) & mapFlags::close) == mapFlags::close)
+ ? mapFlags::close
+ : mapFlags::always;
+
// For unified_shared_memory, we additionally add `CLOSE` on the descriptor
// to ensure device-local placement where required by tests relying on USM +
// close semantics.
@@ -578,6 +592,7 @@ class MapInfoFinalizationPass
// from the descriptor to be used verbatim, i.e. without additional
// remapping. To avoid this remapping, simply don't generate any map
// information for the descriptor members.
+ mlir::FlatSymbolRefAttr mapperId = op.getMapperIdAttr();
if (!mapMemberUsers.empty()) {
// Currently, there should only be one user per map when this pass
// is executed. Either a parent map, holding the current map in its
@@ -588,8 +603,8 @@ class MapInfoFinalizationPass
assert(mapMemberUsers.size() == 1 &&
"OMPMapInfoFinalization currently only supports single users of a "
"MapInfoOp");
- auto baseAddr =
- genBaseAddrMap(descriptor, op.getBounds(), op.getMapType(), builder);
+ auto baseAddr = genBaseAddrMap(descriptor, op.getBounds(),
+ op.getMapType(), builder, mapperId);
ParentAndPlacement mapUser = mapMemberUsers[0];
adjustMemberIndices(memberIndices, mapUser.index);
llvm::SmallVector<mlir::Value> newMemberOps;
@@ -602,8 +617,8 @@ class MapInfoFinalizationPass
mapUser.parent.setMembersIndexAttr(
builder.create2DI64ArrayAttr(memberIndices));
} else if (!isHasDeviceAddrFlag) {
- auto baseAddr =
- genBaseAddrMap(descriptor, op.getBounds(), op.getMapType(), builder);
+ auto baseAddr = genBaseAddrMap(descriptor, op.getBounds(),
+ op.getMapType(), builder, mapperId);
newMembers.push_back(baseAddr);
if (!op.getMembers().empty()) {
for (auto &indices : memberIndices)
@@ -635,7 +650,7 @@ class MapInfoFinalizationPass
getDescriptorMapType(mapType, target)),
op.getMapCaptureTypeAttr(), /*varPtrPtr=*/mlir::Value{}, newMembers,
newMembersAttr, /*bounds=*/mlir::SmallVector<mlir::Value>{},
- /*mapperId*/ mlir::FlatSymbolRefAttr(), op.getNameAttr(),
+ /*mapperId=*/mlir::FlatSymbolRefAttr(), op.getNameAttr(),
/*partial_map=*/builder.getBoolAttr(false));
op.replaceAllUsesWith(newDescParentMapOp.getResult());
op->erase();
@@ -943,38 +958,6 @@ class MapInfoFinalizationPass
localBoxAllocas.clear();
deferrableDesc.clear();
- // First, walk `omp.map.info` ops to see if any of them have varPtrs
- // with an underlying type of fir.char<k, ?>, i.e a character
- // with dynamic length. If so, check if they need bounds added.
- func->walk([&](mlir::omp::MapInfoOp op) {
- if (!op.getBounds().empty())
- return;
-
- mlir::Value varPtr = op.getVarPtr();
- mlir::Type underlyingVarType = fir::unwrapRefType(varPtr.getType());
-
- if (!fir::characterWithDynamicLen(underlyingVarType))
- return;
-
- fir::factory::AddrAndBoundsInfo info =
- fir::factory::getDataOperandBaseAddr(
- builder, varPtr, /*isOptional=*/false, varPtr.getLoc());
-
- fir::ExtendedValue extendedValue =
- hlfir::translateToExtendedValue(varPtr.getLoc(), builder,
- hlfir::Entity{info.addr},
- /*continguousHint=*/true)
- .first;
- builder.setInsertionPoint(op);
- llvm::SmallVector<mlir::Value> boundsOps =
- fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
- mlir::omp::MapBoundsType>(
- builder, info, extendedValue,
- /*dataExvIsAssumedSize=*/false, varPtr.getLoc());
-
- op.getBoundsMutable().append(boundsOps);
- });
-
// Next, walk `omp.map.info` ops to see if any record members should be
// implicitly mapped.
func->walk([&](mlir::omp::MapInfoOp op) {
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 0972861..6404e18 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -104,21 +104,31 @@ class MapsForPrivatizedSymbolsPass
llvm::SmallVector<mlir::Value> boundsOps;
if (needsBoundsOps(varPtr))
genBoundsOps(builder, varPtr, boundsOps);
+ mlir::Type varType = varPtr.getType();
mlir::omp::VariableCaptureKind captureKind =
mlir::omp::VariableCaptureKind::ByRef;
- if (fir::isa_trivial(fir::unwrapRefType(varPtr.getType())) ||
- fir::isa_char(fir::unwrapRefType(varPtr.getType()))) {
- if (canPassByValue(fir::unwrapRefType(varPtr.getType()))) {
+ if (fir::isa_trivial(fir::unwrapRefType(varType)) ||
+ fir::isa_char(fir::unwrapRefType(varType))) {
+ if (canPassByValue(fir::unwrapRefType(varType))) {
captureKind = mlir::omp::VariableCaptureKind::ByCopy;
}
}
+ // Use tofrom if what we are mapping is not a trivial type. In all
+ // likelihood, it is a descriptor
+ mlir::omp::ClauseMapFlags mapFlag;
+ if (fir::isa_trivial(fir::unwrapRefType(varType)) ||
+ fir::isa_char(fir::unwrapRefType(varType)))
+ mapFlag = mlir::omp::ClauseMapFlags::to;
+ else
+ mapFlag = mlir::omp::ClauseMapFlags::to | mlir::omp::ClauseMapFlags::from;
+
return omp::MapInfoOp::create(
- builder, loc, varPtr.getType(), varPtr,
- TypeAttr::get(llvm::cast<omp::PointerLikeType>(varPtr.getType())
- .getElementType()),
- builder.getAttr<omp::ClauseMapFlagsAttr>(omp::ClauseMapFlags::to),
+ builder, loc, varType, varPtr,
+ TypeAttr::get(
+ llvm::cast<omp::PointerLikeType>(varType).getElementType()),
+ builder.getAttr<omp::ClauseMapFlagsAttr>(mapFlag),
builder.getAttr<omp::VariableCaptureKindAttr>(captureKind),
/*varPtrPtr=*/Value{},
/*members=*/SmallVector<Value>{},
diff --git a/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp b/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp
index 0b0e6bd..5fa77fb 100644
--- a/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp
+++ b/flang/lib/Optimizer/OpenMP/MarkDeclareTarget.cpp
@@ -21,6 +21,7 @@
#include "mlir/Pass/Pass.h"
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/TypeSwitch.h"
namespace flangomp {
#define GEN_PASS_DEF_MARKDECLARETARGETPASS
@@ -31,9 +32,93 @@ namespace {
class MarkDeclareTargetPass
: public flangomp::impl::MarkDeclareTargetPassBase<MarkDeclareTargetPass> {
- void markNestedFuncs(mlir::omp::DeclareTargetDeviceType parentDevTy,
- mlir::omp::DeclareTargetCaptureClause parentCapClause,
- bool parentAutomap, mlir::Operation *currOp,
+ struct ParentInfo {
+ mlir::omp::DeclareTargetDeviceType devTy;
+ mlir::omp::DeclareTargetCaptureClause capClause;
+ bool automap;
+ };
+
+ void processSymbolRef(mlir::SymbolRefAttr symRef, ParentInfo parentInfo,
+ llvm::SmallPtrSet<mlir::Operation *, 16> visited) {
+ if (auto currFOp =
+ getOperation().lookupSymbol<mlir::func::FuncOp>(symRef)) {
+ auto current = llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(
+ currFOp.getOperation());
+
+ if (current.isDeclareTarget()) {
+ auto currentDt = current.getDeclareTargetDeviceType();
+
+ // Found the same function twice, with different device_types,
+ // mark as Any as it belongs to both
+ if (currentDt != parentInfo.devTy &&
+ currentDt != mlir::omp::DeclareTargetDeviceType::any) {
+ current.setDeclareTarget(mlir::omp::DeclareTargetDeviceType::any,
+ current.getDeclareTargetCaptureClause(),
+ current.getDeclareTargetAutomap());
+ }
+ } else {
+ current.setDeclareTarget(parentInfo.devTy, parentInfo.capClause,
+ parentInfo.automap);
+ }
+
+ markNestedFuncs(parentInfo, currFOp, visited);
+ }
+ }
+
+ void processReductionRefs(std::optional<mlir::ArrayAttr> symRefs,
+ ParentInfo parentInfo,
+ llvm::SmallPtrSet<mlir::Operation *, 16> visited) {
+ if (!symRefs)
+ return;
+
+ for (auto symRef : symRefs->getAsRange<mlir::SymbolRefAttr>()) {
+ if (auto declareReductionOp =
+ getOperation().lookupSymbol<mlir::omp::DeclareReductionOp>(
+ symRef)) {
+ markNestedFuncs(parentInfo, declareReductionOp, visited);
+ }
+ }
+ }
+
+ void
+ processReductionClauses(mlir::Operation *op, ParentInfo parentInfo,
+ llvm::SmallPtrSet<mlir::Operation *, 16> visited) {
+ llvm::TypeSwitch<mlir::Operation &>(*op)
+ .Case([&](mlir::omp::LoopOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::ParallelOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::SectionsOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::SimdOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::TargetOp op) {
+ processReductionRefs(op.getInReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::TaskgroupOp op) {
+ processReductionRefs(op.getTaskReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::TaskloopOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ processReductionRefs(op.getInReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::TaskOp op) {
+ processReductionRefs(op.getInReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::TeamsOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ })
+ .Case([&](mlir::omp::WsloopOp op) {
+ processReductionRefs(op.getReductionSyms(), parentInfo, visited);
+ })
+ .Default([](mlir::Operation &) {});
+ }
+
+ void markNestedFuncs(ParentInfo parentInfo, mlir::Operation *currOp,
llvm::SmallPtrSet<mlir::Operation *, 16> visited) {
if (visited.contains(currOp))
return;
@@ -43,33 +128,10 @@ class MarkDeclareTargetPass
if (auto callOp = llvm::dyn_cast<mlir::CallOpInterface>(op)) {
if (auto symRef = llvm::dyn_cast_if_present<mlir::SymbolRefAttr>(
callOp.getCallableForCallee())) {
- if (auto currFOp =
- getOperation().lookupSymbol<mlir::func::FuncOp>(symRef)) {
- auto current = llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(
- currFOp.getOperation());
-
- if (current.isDeclareTarget()) {
- auto currentDt = current.getDeclareTargetDeviceType();
-
- // Found the same function twice, with different device_types,
- // mark as Any as it belongs to both
- if (currentDt != parentDevTy &&
- currentDt != mlir::omp::DeclareTargetDeviceType::any) {
- current.setDeclareTarget(
- mlir::omp::DeclareTargetDeviceType::any,
- current.getDeclareTargetCaptureClause(),
- current.getDeclareTargetAutomap());
- }
- } else {
- current.setDeclareTarget(parentDevTy, parentCapClause,
- parentAutomap);
- }
-
- markNestedFuncs(parentDevTy, parentCapClause, parentAutomap,
- currFOp, visited);
- }
+ processSymbolRef(symRef, parentInfo, visited);
}
}
+ processReductionClauses(op, parentInfo, visited);
});
}
@@ -82,10 +144,10 @@ class MarkDeclareTargetPass
functionOp.getOperation());
if (declareTargetOp.isDeclareTarget()) {
llvm::SmallPtrSet<mlir::Operation *, 16> visited;
- markNestedFuncs(declareTargetOp.getDeclareTargetDeviceType(),
- declareTargetOp.getDeclareTargetCaptureClause(),
- declareTargetOp.getDeclareTargetAutomap(), functionOp,
- visited);
+ ParentInfo parentInfo{declareTargetOp.getDeclareTargetDeviceType(),
+ declareTargetOp.getDeclareTargetCaptureClause(),
+ declareTargetOp.getDeclareTargetAutomap()};
+ markNestedFuncs(parentInfo, functionOp, visited);
}
}
@@ -96,12 +158,13 @@ class MarkDeclareTargetPass
// the contents of the device clause
getOperation()->walk([&](mlir::omp::TargetOp tarOp) {
llvm::SmallPtrSet<mlir::Operation *, 16> visited;
- markNestedFuncs(
- /*parentDevTy=*/mlir::omp::DeclareTargetDeviceType::nohost,
- /*parentCapClause=*/mlir::omp::DeclareTargetCaptureClause::to,
- /*parentAutomap=*/false, tarOp, visited);
+ ParentInfo parentInfo = {
+ /*devTy=*/mlir::omp::DeclareTargetDeviceType::nohost,
+ /*capClause=*/mlir::omp::DeclareTargetCaptureClause::to,
+ /*automap=*/false,
+ };
+ markNestedFuncs(parentInfo, tarOp, visited);
});
}
};
-
} // namespace