[llvm] implicit pointer hop for OpenMP runtime memory mapping table proper deletion https://github.com/ROCm/llvm-project/issues/287 (PR #163878)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 16 15:28:32 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-offload

Author: Aditya Srichandan (adityas-amd)

<details>
<summary>Changes</summary>

OpenMP: Fix refcounting for implicit pointer-hop entries in libomptarget (https://github.com/ROCm/llvm-project/issues/287)

This change prevents implicit pointer-only hops (compiler-generated chained pointer members) from incrementing/decrementing reference counts in libomptarget’s mapping table. Without this, intermediate implicit entries can linger after exit data, blocking proper cleanup.

Chained mappings like s.ps->ps->ps->ps->i generate implicit member pointer hops.
These hops are entries with no explicit TO/FROM/ALWAYS/DELETE and size == 0. they get refcounted as regular objects, leaving intermediate entries with non-zero refs after exit.

Problem:
After target enter data, implicit hops +1 refcount.
On target exit data, decrements don’t fully clear the intermediate hops.
Result: stale intermediate mappings prevent proper deletion and leak entries.

Solution
Detect implicit pointer-hop entries and do not update refcounts for them in begin/end paths.
Symmetric handling in targetDataBegin and targetDataEnd to avoid negative counts and ensure full cleanup.

---
Full diff: https://github.com/llvm/llvm-project/pull/163878.diff


1 Files Affected:

- (modified) offload/libomptarget/omptarget.cpp (+12) 


``````````diff
diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp
index 39286d41ec865..08a83c193b196 100644
--- a/offload/libomptarget/omptarget.cpp
+++ b/offload/libomptarget/omptarget.cpp
@@ -41,6 +41,15 @@ using llvm::SmallVector;
 #ifdef OMPT_SUPPORT
 using namespace llvm::omp::target::ompt;
 #endif
+static inline bool isImplicitPointerHop(int64_t MapType, int64_t Size) {
+  //Pointer hop entries flagged as PTR and MEMBER_OF
+  const bool IsPointer  = (MapType & OMP_TGT_MAPTYPE_PTR) != 0;
+  const bool IsMemberOf = (MapType & OMP_TGT_MAPTYPE_MEMBER_OF) != 0;
+  const bool HasExplicit =
+      (MapType & (OMP_TGT_MAPTYPE_TO | OMP_TGT_MAPTYPE_FROM |
+                  OMP_TGT_MAPTYPE_ALWAYS | OMP_TGT_MAPTYPE_DELETE)) != 0;
+  return IsPointer && IsMemberOf && !HasExplicit && Size == 0;
+}
 
 int AsyncInfoTy::synchronize() {
   int Result = OFFLOAD_SUCCESS;
@@ -567,6 +576,9 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
     // may be considered a hack, we could revise the scheme in the future.
     bool UpdateRef =
         !(ArgTypes[I] & OMP_TGT_MAPTYPE_MEMBER_OF) && !(FromMapper && I == 0);
+    if (IsImplicit && isImplicitPointerHop(ArgTypes[I], ArgSizes[I])) {
+         UpdateRef = false;
+    }
 
     MappingInfoTy::HDTTMapAccessorTy HDTTMap =
         Device.getMappingInfo().HostDataToTargetMap.getExclusiveAccessor();

``````````

</details>


https://github.com/llvm/llvm-project/pull/163878


More information about the llvm-commits mailing list