================
@@ -5303,6 +5348,121 @@ static bool checkIfPointerMap(omp::MapInfoOp mapOp) {
return false;
}
+// This function handles the insertion of a single item of map data from
+// MapInfoData into the OMPIRBuilders MapInfo list. Utilising this function
+// means the map being inserted can be treated as a non-parent map entity,
+// if the memberOfFlag is set then the map being inserted is treated as
+// a member map of a larger entity. The insertion into the MapInfo list of
+// the OMPIRBuilder can vary based on a number of factors, such as if it's
+// a ref_ptr or ref_ptee map, if it's a member of a record, what construct
+// the map belongs to and the various map type bit flags that are set for
+// the map.
+static void
+processIndividualMap(llvm::IRBuilderBase &builder,
+ llvm::OpenMPIRBuilder &ompBuilder, MapInfoData &mapData,
+ size_t mapDataIdx, MapInfosTy &combinedInfo,
+ TargetDirectiveEnumTy targetDirective,
+ llvm::omp::OpenMPOffloadMappingFlags memberOfFlag =
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE,
+ bool isTargetParam = true, int mapDataParentIdx = -1) {
+ auto mapFlag = mapData.Types[mapDataIdx];
+ auto mapInfoOp = llvm::cast<omp::MapInfoOp>(mapData.MapClause[mapDataIdx]);
+
+ bool isPtrTy = checkIfPointerMap(mapInfoOp);
+ bool isAttachMap = ((convertClauseMapFlags(mapInfoOp.getMapType()) &
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ATTACH) ==
+ llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_ATTACH);
+
+ // Declare target variables are not passed to the kernel, and for the moment
+ // attach maps are not passed to the kernel. However, it is possible to
create
+ // attach maps that transfer data and thus can be kernel arguments, but our
+ // existing frontend does not do this.
+ if (isTargetParam &&
+ (targetDirective == TargetDirectiveEnumTy::Target &&
+ !mapData.IsDeclareTarget[mapDataIdx]) &&
+ !isAttachMap)
+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM;
+
+ if (mapInfoOp.getMapCaptureType() == omp::VariableCaptureKind::ByCopy &&
+ !isPtrTy)
+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_LITERAL;
+
+ // If we have a pointer and it's part of a MEMBER_OF mapping we do not apply
+ // MEMBER_OF, as the runtime currently has a work-around that utilises
+ // MEMBER_OF to prevent reference updating in certain scenarios instead of
+ // target_param. However, this causes a noticeable issue in cases where we
+ // map some data (Fortran descriptor primarily at the moment), alter it on
+ // the host, and then expect it to not be updated in a subsequent implicit
map
+ // (such as an implicit map on a target).
+ if (memberOfFlag != llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE) {
+ // If we are in a declare mapper, we apply MEMBER_OF even if it's an attach
+ // or pointer map, this is to make the MEMBER_OF flag uniform across all
+ // maps within the declare mapper, as even if we do not apply it here on
+ // nestings greater than the first layer we will have a member of flag
+ // applied automatically. So, we canonicalize it here, which keeps the
+ // behaviour of pointer/data maps consistent across layers.
+ if ((!isPtrTy && !isAttachMap) ||
+ mapInfoOp->getParentOfType<omp::DeclareMapperOp>())
+ ompBuilder.setCorrectMemberOfFlag(mapFlag, memberOfFlag);
+
+ // The return parameter should be the over-riding parent in cases where we
+ // have a return parameter that is echoed to all members, the main case of
+ // this currently is with fortran descriptors. It may need more finessing
+ // for C/C++ in the future or descriptors that are members of derived
+ // types.
+ mapFlag &= ~llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_RETURN_PARAM;
+ }
+
+ // We apply MAP_PTR_AND_OBJ when within a declare mapper object as it
enforces
+ // MEMBER_OF mappings on maps that are passed the initial nesting depth,
which
+ // includes pointed to data and attach members, both of which are technically
+ // not part of the main object. This has the side effect of causing early
+ // map-backs in certain cases where an implicit declare mapper has been
+ // emitted for a target region. Applying MAP_PTR_AND_OBJ in these situations
+ // circumvents this.
+ if (isPtrTy && !isAttachMap &&
+ (mapData.IsDeclareTarget[mapDataIdx] ||
+ mapInfoOp->getParentOfType<omp::DeclareMapperOp>()))
+ mapFlag |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PTR_AND_OBJ;
+
+ // if we're provided a mapDataParentIdx, then the data being mapped is
+ // part of a larger object (in a parent <-> member mapping) and in this
+ // case our BasePointer should be the parent. Except in the edge case
+ // where we are mapping pointee data, where we try staying close to
+ // what Clang currently does and utilise the regular base pointer of the
+ // data.
+ bool isRefPtee =
+ !bitEnumContainsAll(mapInfoOp.getMapType(),
+ omp::ClauseMapFlags::ref_ptr) &&
+ bitEnumContainsAll(mapInfoOp.getMapType(),
omp::ClauseMapFlags::ref_ptee);
+ bool isRefPtrPtee =
+ bitEnumContainsAll(mapInfoOp.getMapType(),
+ omp::ClauseMapFlags::ref_ptr) &&
+ bitEnumContainsAll(mapInfoOp.getMapType(),
omp::ClauseMapFlags::ref_ptee);
----------------
skatrak wrote:
That is really strange. `bitEnumContainsAll(x, y) && bitEnumContainsAll(x, z)`
should be the same as `bitEnumContainsAll(x, y | z)`.
Is it possible that the test issues you saw were related to my other comment,
where I suggested using bitEnumContains**Any** in place of
`bitEnumContainsAll() || bitEnumContainsAll()`?.
In any case, if you are able to confirm that this is currently causing
problems, just leave it as it is, as it was only intended as a simplification.
https://github.com/llvm/llvm-project/pull/179023
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits