================
@@ -609,208 +880,210 @@ class MapInfoFinalizationPass
       assert(mapMemberUsers.size() == 1 &&
              "OMPMapInfoFinalization currently only supports single users of a 
"
              "MapInfoOp");
-      auto baseAddr = genBaseAddrMap(descriptor, op.getBounds(),
-                                     op.getMapType(), builder, mapperId);
       ParentAndPlacement mapUser = mapMemberUsers[0];
-      adjustMemberIndices(memberIndices, mapUser.index);
+      adjustMemberIndices(memberIndices, mapUser);
       llvm::SmallVector<mlir::Value> newMemberOps;
       for (auto v : mapUser.parent.getMembers()) {
         newMemberOps.push_back(v);
-        if (v == op)
+        if (v == parentOp)
           newMemberOps.push_back(baseAddr);
       }
       mapUser.parent.getMembersMutable().assign(newMemberOps);
       mapUser.parent.setMembersIndexAttr(
           builder.create2DI64ArrayAttr(memberIndices));
-    } else if (!isHasDeviceAddrFlag) {
-      auto baseAddr = genBaseAddrMap(descriptor, op.getBounds(),
-                                     op.getMapType(), builder, mapperId);
+    } else {
       newMembers.push_back(baseAddr);
-      if (!op.getMembers().empty()) {
+      if (!parentOp.getMembers().empty()) {
         for (auto &indices : memberIndices)
           indices.insert(indices.begin(), 0);
         memberIndices.insert(memberIndices.begin(), {0});
         newMembersAttr = builder.create2DI64ArrayAttr(memberIndices);
-        newMembers.append(op.getMembers().begin(), op.getMembers().end());
+        newMembers.append(parentOp.getMembers().begin(),
+                          parentOp.getMembers().end());
       } else {
         llvm::SmallVector<llvm::SmallVector<int64_t>> memberIdx = {{0}};
         newMembersAttr = builder.create2DI64ArrayAttr(memberIdx);
       }
     }
-
-    // Descriptors for objects listed on the `has_device_addr` 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.
-    mlir::omp::ClauseMapFlags mapType = op.getMapType();
-    if (isHasDeviceAddrFlag) {
-      mapType |= mlir::omp::ClauseMapFlags::always;
-    }
-
-    mlir::omp::MapInfoOp newDescParentMapOp = mlir::omp::MapInfoOp::create(
-        builder, op->getLoc(), op.getResult().getType(), descriptor,
-        mlir::TypeAttr::get(fir::unwrapRefType(descriptor.getType())),
-        builder.getAttr<mlir::omp::ClauseMapFlagsAttr>(
-            getDescriptorMapType(mapType, target)),
-        op.getMapCaptureTypeAttr(), /*varPtrPtr=*/mlir::Value{},
-        /*varPtrPtrType=*/mlir::TypeAttr{}, newMembers, newMembersAttr,
-        /*bounds=*/mlir::SmallVector<mlir::Value>{},
-        /*mapperId=*/mlir::FlatSymbolRefAttr(), op.getNameAttr(),
-        /*partial_map=*/builder.getBoolAttr(false));
-    op.replaceAllUsesWith(newDescParentMapOp.getResult());
-    op->erase();
-
-    if (descCanBeDeferred)
-      deferrableDesc.push_back(newDescParentMapOp);
-
-    return newDescParentMapOp;
   }
 
-  // We add all mapped record members not directly used in the target region
-  // to the block arguments in front of their parent and we place them into
-  // the map operands list for consistency.
+  // This function handles the spliting of allocatable/pointer maps in
+  // Fortran into descriptor, pointer and attach map components, as
+  // well as the handling of ref_ptr, ref_ptee, ref_ptr_ptee and attach
+  // modifier semantics.
   //
-  // These indirect uses (via accesses to their parent) will still be
-  // mapped individually in most cases, and a parent mapping doesn't
-  // guarantee the parent will be mapped in its totality, partial
-  // mapping is common.
+  // For ref_ptr, we generate a map of the descriptor with user specified
+  // map types and, in the default auto attach case, we generate an
+  // additional attach map which indicates to the runtime to try and attach
+  // the base address to the descriptor if it's available and it's the first
+  // time the ref_ptr has been allocated on the device.
   //
-  // For example:
-  //    map(tofrom: x%y)
+  // For ref_ptee, we generate a map of the base address with user specified
+  // map types and, in the default auto attach case, we generate an
+  // additional attach map which indicates to the runtime to try and attach
+  // the base address to the descriptor if it's available and it's the first
+  // time the ref_ptee has been allocated on the device.
   //
-  // Will generate a mapping for "x" (the parent) and "y" (the member).
-  // The parent "x" will not be mapped, but the member "y" will.
-  // However, we must have the parent as a BlockArg and MapOperand
-  // in these cases, to maintain the correct uses within the region and
-  // to help tracking that the member is part of a larger object.
-  //
-  // In the case of:
-  //    map(tofrom: x%y, x%z)
-  //
-  // The parent member becomes more critical, as we perform a partial
-  // structure mapping where we link the mapping of the members y
-  // and z together via the parent x. We do this at a kernel argument
-  // level in LLVM IR and not just MLIR, which is important to maintain
-  // similarity to Clang and for the runtime to do the correct thing.
-  // However, we still do not map the structure in its totality but
-  // rather we generate an un-sized "binding" map entry for it.
-  //
-  // In the case of:
-  //    map(tofrom: x, x%y, x%z)
-  //
-  // We do actually map the entirety of "x", so the explicit mapping of
-  // x%y, x%z becomes unnecessary. It is redundant to write this from a
-  // Fortran OpenMP perspective (although it is legal), as even if the
-  // members were allocatables or pointers, we are mandated by the
-  // specification to map these (and any recursive components) in their
-  // entirety, which is different to the C++ equivalent, which requires
-  // explicit mapping of these segments.
-  void addImplicitMembersToTarget(mlir::omp::MapInfoOp op,
-                                  fir::FirOpBuilder &builder,
-                                  mlir::Operation *target) {
-    auto mapClauseOwner =
-        llvm::dyn_cast_if_present<mlir::omp::MapClauseOwningOpInterface>(
-            target);
-    // TargetDataOp is technically a MapClauseOwningOpInterface, so we
-    // do not need to explicitly check for the extra cases here for use_device
-    // addr/ptr
-    if (!mapClauseOwner)
-      return;
+  // For ref_ptr_ptee, it is the standard descriptor mapping that combines both
+  // of the above, a map is generated for the descriptor and its base address,
+  // similarly in the default auto attach case, we generate an additional 
attach
+  // map.
+  void genDescriptorMaps(mlir::omp::MapInfoOp op, fir::FirOpBuilder &builder,
----------------
agozillon wrote:

I personally prefer it as is, as I can tell at a glance what the differences 
are without digging around, but I also wrote it and have been staring at it for 
a while, so I can appreciate that it's likely not so easy for others! So, happy 
to change it to the more compartmentalized style :-)  

https://github.com/llvm/llvm-project/pull/177715
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to