@@ -241,26 +241,44 @@ class MapInfoFinalizationPass
241241 // / allowing `to` mappings, and `target update` not allowing both `to` and
242242 // / `from` simultaneously. We currently try to maintain the `implicit` flag
243243 // / where necessary, although it does not seem strictly required.
244- unsigned long getDescriptorMapType (mlir::omp::MapInfoOp op ,
244+ unsigned long getDescriptorMapType (unsigned long mapTypeFlag ,
245245 mlir::Operation *target) {
246246 using mapFlags = llvm::omp::OpenMPOffloadMappingFlags;
247- unsigned long mapType = op.getMapType ().value_or (0 );
248247 if (llvm::isa_and_nonnull<mlir::omp::TargetExitDataOp,
249248 mlir::omp::TargetUpdateOp>(target))
250- return mapType ;
249+ return mapTypeFlag ;
251250 mapFlags flags = mapFlags::OMP_MAP_TO |
252- (mapFlags (mapType) & mapFlags::OMP_MAP_IMPLICIT);
251+ (mapFlags (mapTypeFlag) & mapFlags::OMP_MAP_IMPLICIT);
252+ // Descriptors for objects will always be copied. This is because the
253+ // descriptor can be rematerialized by the compiler, and so the addres
254+ // of the descriptor for a given object at one place in the code may
255+ // differ from that address in another place. The contents of the
256+ // descriptor (the base address in particular) will remain unchanged
257+ // though.
253258 // TODO/FIXME: We currently cannot have MAP_CLOSE and MAP_ALWAYS on
254259 // the descriptor at once, these are mutually exclusive and when
255260 // both are applied the runtime will fail to map.
256- flags |= ((mapFlags (mapType ) & mapFlags::OMP_MAP_CLOSE) ==
261+ flags |= ((mapFlags (mapTypeFlag ) & mapFlags::OMP_MAP_CLOSE) ==
257262 mapFlags::OMP_MAP_CLOSE)
258263 ? mapFlags::OMP_MAP_CLOSE
259264 : mapFlags::OMP_MAP_ALWAYS;
260265 flags |= mapFlags::OMP_MAP_DESCRIPTOR;
261266 return llvm::to_underlying (flags);
262267 }
263268
269+ // / Check if the mapOp is present in the HasDeviceAddr clause on
270+ // / the userOp. Only applies to TargetOp.
271+ bool isHasDeviceAddr (mlir::omp::MapInfoOp mapOp, mlir::Operation *userOp) {
272+ assert (userOp && " Expecting non-null argument" );
273+ if (auto targetOp = llvm::dyn_cast<mlir::omp::TargetOp>(userOp)) {
274+ for (mlir::Value hda : targetOp.getHasDeviceAddrVars ()) {
275+ if (hda.getDefiningOp () == mapOp)
276+ return true ;
277+ }
278+ }
279+ return false ;
280+ }
281+
264282 mlir::omp::MapInfoOp genDescriptorMemberMaps (mlir::omp::MapInfoOp op,
265283 fir::FirOpBuilder &builder,
266284 mlir::Operation *target) {
@@ -270,11 +288,11 @@ class MapInfoFinalizationPass
270288 // TODO: map the addendum segment of the descriptor, similarly to the
271289 // base address/data pointer member.
272290 mlir::Value descriptor = getDescriptorFromBoxMap (op, builder);
273- auto baseAddr = genBaseAddrMap (descriptor, op.getBounds (),
274- op.getMapType ().value_or (0 ), builder);
291+
275292 mlir::ArrayAttr newMembersAttr;
276293 mlir::SmallVector<mlir::Value> newMembers;
277294 llvm::SmallVector<llvm::SmallVector<int64_t >> memberIndices;
295+ bool IsHasDeviceAddr = isHasDeviceAddr (op, target);
278296
279297 if (!mapMemberUsers.empty () || !op.getMembers ().empty ())
280298 getMemberIndicesAsVectors (
@@ -288,6 +306,12 @@ class MapInfoFinalizationPass
288306 // member information to now have one new member for the base address, or
289307 // we are expanding a parent that is a descriptor and we have to adjust
290308 // all of its members to reflect the insertion of the base address.
309+ //
310+ // If we're expanding a top-level descriptor for a map operation that
311+ // resulted from "has_device_addr" clause, then we want the base pointer
312+ // from the descriptor to be used verbatim, i.e. without additional
313+ // remapping. To avoid this remapping, simply don't generate any map
314+ // information for the descriptor members.
291315 if (!mapMemberUsers.empty ()) {
292316 // Currently, there should only be one user per map when this pass
293317 // is executed. Either a parent map, holding the current map in its
@@ -298,6 +322,8 @@ class MapInfoFinalizationPass
298322 assert (mapMemberUsers.size () == 1 &&
299323 " OMPMapInfoFinalization currently only supports single users of a "
300324 " MapInfoOp" );
325+ auto baseAddr = genBaseAddrMap (descriptor, op.getBounds (),
326+ op.getMapType ().value_or (0 ), builder);
301327 ParentAndPlacement mapUser = mapMemberUsers[0 ];
302328 adjustMemberIndices (memberIndices, mapUser.index );
303329 llvm::SmallVector<mlir::Value> newMemberOps;
@@ -309,7 +335,9 @@ class MapInfoFinalizationPass
309335 mapUser.parent .getMembersMutable ().assign (newMemberOps);
310336 mapUser.parent .setMembersIndexAttr (
311337 builder.create2DI64ArrayAttr (memberIndices));
312- } else {
338+ } else if (!IsHasDeviceAddr) {
339+ auto baseAddr = genBaseAddrMap (descriptor, op.getBounds (),
340+ op.getMapType ().value_or (0 ), builder);
313341 newMembers.push_back (baseAddr);
314342 if (!op.getMembers ().empty ()) {
315343 for (auto &indices : memberIndices)
@@ -331,7 +359,7 @@ class MapInfoFinalizationPass
331359 /* bounds=*/ mlir::SmallVector<mlir::Value>{},
332360 builder.getIntegerAttr (
333361 builder.getIntegerType (64 , false ),
334- getDescriptorMapType (op, target)),
362+ getDescriptorMapType (op. getMapType (). value_or ( 0 ) , target)),
335363 /* mapperId*/ mlir::FlatSymbolRefAttr (), op.getMapCaptureTypeAttr (),
336364 op.getNameAttr (),
337365 /* partial_map=*/ builder.getBoolAttr (false ));
@@ -448,6 +476,12 @@ class MapInfoFinalizationPass
448476 addOperands (useDevPtrMutableOpRange, target,
449477 argIface.getUseDevicePtrBlockArgsStart () +
450478 argIface.numUseDevicePtrBlockArgs ());
479+ } else if (auto targetOp = llvm::dyn_cast<mlir::omp::TargetOp>(target)) {
480+ mlir::MutableOperandRange hasDevAddrMutableOpRange =
481+ targetOp.getHasDeviceAddrVarsMutable ();
482+ addOperands (hasDevAddrMutableOpRange, target,
483+ argIface.getHasDeviceAddrBlockArgsStart () +
484+ argIface.numHasDeviceAddrBlockArgs ());
451485 }
452486 }
453487
0 commit comments