[llvm] [Offload][OpenMP] Report source location of data transfers and synchr… (PR #223730)

Jason Van Beusekom via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 14:45:56 PDT 2026


https://github.com/Jason-Van-Beusekom updated https://github.com/llvm/llvm-project/pull/223730

>From deb5784110a23073f00aab289b4b6d6cc687d3c9 Mon Sep 17 00:00:00 2001
From: Jason Van Beusekom <jason.van-beusekom at hpe.com>
Date: Tue, 15 Sep 2026 09:54:28 -0500
Subject: [PATCH 1/2] [Offload][OpenMP] Report source location of data
 transfers and synchronization

---
 offload/include/OpenMP/Mapping.h      |  6 ++++--
 offload/include/Shared/SourceInfo.h   | 13 +++++++++++++
 offload/include/device.h              |  6 ++++--
 offload/libompaccsupport/Mapping.cpp  | 27 +++++++++++++++++----------
 offload/libompaccsupport/device.cpp   | 17 +++++++++++------
 offload/libomptarget/interface.cpp    |  8 ++++++--
 offload/libomptarget/omptarget.cpp    |  9 +++++----
 offload/libomptarget/private.h        | 11 +++++++++++
 offload/test/offloading/force-usm.cpp |  1 +
 offload/test/offloading/info.c        | 10 +++++++---
 10 files changed, 79 insertions(+), 29 deletions(-)

diff --git a/offload/include/OpenMP/Mapping.h b/offload/include/OpenMP/Mapping.h
index e4024abf26690..4b160684ddb32 100644
--- a/offload/include/OpenMP/Mapping.h
+++ b/offload/include/OpenMP/Mapping.h
@@ -671,7 +671,8 @@ struct MappingInfoTy {
       bool HasFlagTo, bool HasFlagAlways, bool IsImplicit, bool UpdateRefCount,
       bool HasCloseModifier, bool HasPresentModifier, bool HasHoldModifier,
       AsyncInfoTy &AsyncInfo, HostDataToTargetTy *OwnedTPR = nullptr,
-      bool ReleaseHDTTMap = true, StateInfoTy *StateInfo = nullptr);
+      bool ReleaseHDTTMap = true, StateInfoTy *StateInfo = nullptr,
+      const ident_t *Loc = nullptr);
 
   /// Return the target pointer for \p HstPtrBegin in \p HDTTMap. The accessor
   /// ensures exclusive access to the HDTT map.
@@ -717,7 +718,8 @@ struct MappingInfoTy {
   /// is set, the associated metadata will be printed as well.
   void printCopyInfo(void *TgtPtr, void *HstPtr, int64_t Size, bool H2D,
                      HostDataToTargetTy *Entry,
-                     MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr);
+                     MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr,
+                     const ident_t *Loc = nullptr, const char *Name = nullptr);
 
 private:
   DeviceTy &Device;
diff --git a/offload/include/Shared/SourceInfo.h b/offload/include/Shared/SourceInfo.h
index 63488ff0e8cac..876ccb80fcb0f 100644
--- a/offload/include/Shared/SourceInfo.h
+++ b/offload/include/Shared/SourceInfo.h
@@ -111,4 +111,17 @@ static inline std::string getNameFromMapping(const map_var_info_t Name) {
   return NameStr.substr(Begin + 1, End - Begin - 1);
 }
 
+/// Returns "<Prefix><filename>:<line>:<column>" when \p Loc carries a
+/// compiler-provided source location, or an empty string otherwise, so info
+/// output can be annotated without emitting "unknown:0:0".
+static inline std::string getSourceLocationSuffix(const ident_t *Loc,
+                                                  const char *Prefix) {
+  SourceInfo Info(Loc);
+  if (!Info.isAvailible())
+    return "";
+  return std::string(Prefix) + Info.getFilename() + ":" +
+         std::to_string(Info.getLine()) + ":" +
+         std::to_string(Info.getColumn());
+}
+
 #endif // OMPTARGET_SHARED_SOURCE_INFO_H
diff --git a/offload/include/device.h b/offload/include/device.h
index 266a2a675df0c..54a85021da70d 100644
--- a/offload/include/device.h
+++ b/offload/include/device.h
@@ -87,13 +87,15 @@ struct DeviceTy {
   int32_t submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size,
                      AsyncInfoTy &AsyncInfo,
                      HostDataToTargetTy *Entry = nullptr,
-                     MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr);
+                     MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr,
+                     const ident_t *Loc = nullptr, const char *Name = nullptr);
 
   // Copy data from device back to host
   int32_t retrieveData(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size,
                        AsyncInfoTy &AsyncInfo,
                        HostDataToTargetTy *Entry = nullptr,
-                       MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr);
+                       MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr,
+                       const ident_t *Loc = nullptr);
 
   // Return true if data can be copied to DstDevice directly
   bool isDataExchangable(const DeviceTy &DstDevice);
diff --git a/offload/libompaccsupport/Mapping.cpp b/offload/libompaccsupport/Mapping.cpp
index 1bb2e424bd083..a4905e4106deb 100644
--- a/offload/libompaccsupport/Mapping.cpp
+++ b/offload/libompaccsupport/Mapping.cpp
@@ -210,7 +210,7 @@ TargetPointerResultTy MappingInfoTy::getTargetPointer(
     bool HasFlagAlways, bool IsImplicit, bool UpdateRefCount,
     bool HasCloseModifier, bool HasPresentModifier, bool HasHoldModifier,
     AsyncInfoTy &AsyncInfo, HostDataToTargetTy *OwnedTPR, bool ReleaseHDTTMap,
-    StateInfoTy *StateInfo) {
+    StateInfoTy *StateInfo, const ident_t *Loc) {
 
   LookupResult LR = lookupMapping(HDTTMap, HstPtrBegin, Size, OwnedTPR);
   LR.TPR.Flags.IsPresent = true;
@@ -385,7 +385,8 @@ TargetPointerResultTy MappingInfoTy::getTargetPointer(
                       << ") -> (tgt:" << LR.TPR.TargetPointer << ")";
 
     int Ret = Device.submitData(LR.TPR.TargetPointer, HstPtrBegin, Size,
-                                AsyncInfo, LR.TPR.getEntry());
+                                AsyncInfo, LR.TPR.getEntry(),
+                                /*HDTTMapPtr=*/nullptr, Loc);
     if (Ret != OFFLOAD_SUCCESS) {
       REPORT() << "Copying data to device failed.";
       // We will also return nullptr if the data movement fails because that
@@ -557,21 +558,27 @@ int MappingInfoTy::deallocTgtPtrAndEntry(HostDataToTargetTy *Entry,
 
 static void printCopyInfoImpl(int DeviceId, bool H2D, void *SrcPtrBegin,
                               void *DstPtrBegin, int64_t Size,
-                              HostDataToTargetTy *HT) {
+                              HostDataToTargetTy *HT, const ident_t *Loc,
+                              const char *Name) {
+
+  std::string LocStr = getSourceLocationSuffix(Loc, ", at ");
 
   INFO(OMP_INFOTYPE_DATA_TRANSFER, DeviceId,
        "Copying data from %s to %s, %sPtr=" DPxMOD ", %sPtr=" DPxMOD
-       ", Size=%" PRId64 ", Name=%s\n",
+       ", Size=%" PRId64 ", Name=%s%s\n",
        H2D ? "host" : "device", H2D ? "device" : "host", H2D ? "Hst" : "Tgt",
        DPxPTR(H2D ? SrcPtrBegin : DstPtrBegin), H2D ? "Tgt" : "Hst",
        DPxPTR(H2D ? DstPtrBegin : SrcPtrBegin), Size,
        (HT && HT->HstPtrName) ? getNameFromMapping(HT->HstPtrName).c_str()
-                              : "unknown");
+                              : (Name ? Name : "unknown"),
+       LocStr.c_str());
 }
 
-void MappingInfoTy::printCopyInfo(
-    void *TgtPtrBegin, void *HstPtrBegin, int64_t Size, bool H2D,
-    HostDataToTargetTy *Entry, MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr) {
+void MappingInfoTy::printCopyInfo(void *TgtPtrBegin, void *HstPtrBegin,
+                                  int64_t Size, bool H2D,
+                                  HostDataToTargetTy *Entry,
+                                  MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr,
+                                  const ident_t *Loc, const char *Name) {
   auto HDTTMap =
       HostDataToTargetMap.getExclusiveAccessor(!!Entry || !!HDTTMapPtr);
   LookupResult LR;
@@ -579,6 +586,6 @@ void MappingInfoTy::printCopyInfo(
     LR = lookupMapping(HDTTMapPtr ? *HDTTMapPtr : HDTTMap, HstPtrBegin, Size);
     Entry = LR.TPR.getEntry();
   }
-  printCopyInfoImpl(Device.DeviceID, H2D, HstPtrBegin, TgtPtrBegin, Size,
-                    Entry);
+  printCopyInfoImpl(Device.DeviceID, H2D, HstPtrBegin, TgtPtrBegin, Size, Entry,
+                    Loc, Name);
 }
diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp
index 688746477861c..2e74d3a11f586 100644
--- a/offload/libompaccsupport/device.cpp
+++ b/offload/libompaccsupport/device.cpp
@@ -198,7 +198,8 @@ setupIndirectCallTable(DeviceTy &Device, __tgt_device_image *Image,
       IndirectCallTable.size() * sizeof(std::pair<void *, void *>);
   void *DevicePtr = Device.allocData(TableSize, nullptr, TARGET_ALLOC_DEVICE);
   if (Device.submitData(DevicePtr, IndirectCallTable.data(), TableSize,
-                        AsyncInfo))
+                        AsyncInfo, /*Entry=*/nullptr, /*HDTTMapPtr=*/nullptr,
+                        /*Loc=*/nullptr, /*Name=*/"IndirectCallTable"))
     return error::createOffloadError(error::ErrorCode::INVALID_BINARY,
                                      "failed to copy data");
   // The IndirectCallTable is on the stack, so we must synchronize to ensure
@@ -247,7 +248,9 @@ DeviceTy::loadBinary(__tgt_device_image *Img) {
 
   AsyncInfoTy AsyncInfo(*this);
   if (submitData(DeviceEnvironmentPtr, &DeviceEnvironment,
-                 sizeof(DeviceEnvironment), AsyncInfo))
+                 sizeof(DeviceEnvironment), AsyncInfo, /*Entry=*/nullptr,
+                 /*HDTTMapPtr=*/nullptr, /*Loc=*/nullptr,
+                 /*Name=*/"DeviceEnvironment"))
     return error::createOffloadError(error::ErrorCode::INVALID_BINARY,
                                      "failed to copy data");
 
@@ -279,10 +282,11 @@ int32_t DeviceTy::deleteData(void *TgtAllocBegin, int32_t Kind) {
 // Submit data to device
 int32_t DeviceTy::submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size,
                              AsyncInfoTy &AsyncInfo, HostDataToTargetTy *Entry,
-                             MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr) {
+                             MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr,
+                             const ident_t *Loc, const char *Name) {
   if (getInfoLevel() & OMP_INFOTYPE_DATA_TRANSFER)
     MappingInfo.printCopyInfo(TgtPtrBegin, HstPtrBegin, Size, /*H2D=*/true,
-                              Entry, HDTTMapPtr);
+                              Entry, HDTTMapPtr, Loc, Name);
 
   /// RAII to establish tool anchors before and after data submit
   OMPT_IF_BUILT(
@@ -299,10 +303,11 @@ int32_t DeviceTy::submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size,
 int32_t DeviceTy::retrieveData(void *HstPtrBegin, void *TgtPtrBegin,
                                int64_t Size, AsyncInfoTy &AsyncInfo,
                                HostDataToTargetTy *Entry,
-                               MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr) {
+                               MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr,
+                               const ident_t *Loc) {
   if (getInfoLevel() & OMP_INFOTYPE_DATA_TRANSFER)
     MappingInfo.printCopyInfo(TgtPtrBegin, HstPtrBegin, Size, /*H2D=*/false,
-                              Entry, HDTTMapPtr);
+                              Entry, HDTTMapPtr, Loc);
 
   /// RAII to establish tool anchors before and after data retrieval
   OMPT_IF_BUILT(
diff --git a/offload/libomptarget/interface.cpp b/offload/libomptarget/interface.cpp
index 5d7d948711b99..7b0cd04cda4c2 100644
--- a/offload/libomptarget/interface.cpp
+++ b/offload/libomptarget/interface.cpp
@@ -186,8 +186,10 @@ targetData(ident_t *Loc, int64_t DeviceId, int32_t ArgNum, void **ArgsBase,
     if (StateInfo && !StateInfo->AttachEntries.empty())
       Rc = processAttachEntries(*DeviceOrErr, *StateInfo, AsyncInfo);
 
-    if (Rc == OFFLOAD_SUCCESS)
+    if (Rc == OFFLOAD_SUCCESS) {
+      printSyncInfo(Loc, DeviceId);
       Rc = AsyncInfo.synchronize();
+    }
   }
 
   handleTargetOutcome(Rc == OFFLOAD_SUCCESS, Loc);
@@ -439,8 +441,10 @@ static inline int targetKernel(ident_t *Loc, int64_t DeviceId, int32_t NumTeams,
   Rc = target(Loc, *DeviceOrErr, HostPtr, *KernelArgs, AsyncInfo);
   { // required to show synchronization
     TIMESCOPE_WITH_DETAILS_AND_IDENT("Runtime: synchronize", "", Loc);
-    if (Rc == OFFLOAD_SUCCESS)
+    if (Rc == OFFLOAD_SUCCESS) {
+      printSyncInfo(Loc, DeviceId);
       Rc = AsyncInfo.synchronize();
+    }
 
     handleTargetOutcome(Rc == OFFLOAD_SUCCESS, Loc);
     assert(Rc == OFFLOAD_SUCCESS && "__tgt_target_kernel unexpected failure!");
diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp
index 9e93bca77b292..648501dfb8a25 100644
--- a/offload/libomptarget/omptarget.cpp
+++ b/offload/libomptarget/omptarget.cpp
@@ -665,7 +665,7 @@ int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
         HDTTMap, HstPtrBegin, HstPtrBase, TgtPadding, DataSize, HstPtrName,
         HasFlagTo, HasFlagAlways, IsImplicit, UpdateRef, HasCloseModifier,
         HasPresentModifier, HasHoldModifier, AsyncInfo, PointerTpr.getEntry(),
-        /*ReleaseHDTTMap=*/true, StateInfo);
+        /*ReleaseHDTTMap=*/true, StateInfo, Loc);
     void *TgtPtrBegin = TPR.TargetPointer;
     IsHostPtr = TPR.Flags.IsHostPointer;
     // If data_size==0, then the argument could be a zero-length pointer to
@@ -1236,7 +1236,8 @@ int targetDataEnd(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
         }
       }
 
-      int Ret = Device.retrieveData(HstPtr, TgtPtr, Size, AsyncInfo, Entry);
+      int Ret = Device.retrieveData(HstPtr, TgtPtr, Size, AsyncInfo, Entry,
+                                    /*HDTTMapPtr=*/nullptr, Loc);
       if (Ret != OFFLOAD_SUCCESS) {
         REPORT() << "Copying data from device failed.";
         return OFFLOAD_FAIL;
@@ -1417,7 +1418,7 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
     ODBG(ODT_Mapping) << "Moving " << ArgSize << " bytes (hst:" << HstPtrBegin
                       << ") -> (tgt:" << TgtPtrBegin << ")";
     int Ret = Device.submitData(TgtPtrBegin, HstPtrBegin, ArgSize, AsyncInfo,
-                                TPR.getEntry());
+                                TPR.getEntry(), /*HDTTMapPtr=*/nullptr, Loc);
     if (Ret != OFFLOAD_SUCCESS) {
       REPORT() << "Copying data to device failed.";
       return OFFLOAD_FAIL;
@@ -1458,7 +1459,7 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
     ODBG(ODT_Mapping) << "Moving " << ArgSize << " bytes (tgt:" << TgtPtrBegin
                       << ") -> (hst:" << HstPtrBegin << ")";
     int Ret = Device.retrieveData(HstPtrBegin, TgtPtrBegin, ArgSize, AsyncInfo,
-                                  TPR.getEntry());
+                                  TPR.getEntry(), /*HDTTMapPtr=*/nullptr, Loc);
     if (Ret != OFFLOAD_SUCCESS) {
       REPORT() << "Copying data from device failed.";
       return OFFLOAD_FAIL;
diff --git a/offload/libomptarget/private.h b/offload/libomptarget/private.h
index 80630f9c366ac..0de02cb2304d6 100644
--- a/offload/libomptarget/private.h
+++ b/offload/libomptarget/private.h
@@ -86,6 +86,17 @@ printKernelArguments(const ident_t *Loc, const int64_t DeviceId,
   }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+/// Report that the runtime is about to wait for the region's outstanding
+/// asynchronous operations (data transfers and kernels) to complete.
+static inline void printSyncInfo(const ident_t *Loc, const int64_t DeviceId) {
+  if (!(getInfoLevel() & OMP_INFOTYPE_DATA_TRANSFER))
+    return;
+  std::string LocStr = getSourceLocationSuffix(Loc, " at ");
+  INFO(OMP_INFOTYPE_DATA_TRANSFER, DeviceId,
+       "Waiting for asynchronous operations to complete%s\n", LocStr.c_str());
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 /// Checks if the passed device is the initial device (i.e., host device)
 /// While the device number is defined as the value of the total number of
diff --git a/offload/test/offloading/force-usm.cpp b/offload/test/offloading/force-usm.cpp
index 8a0fd1828b809..f8a2f1a80645e 100644
--- a/offload/test/offloading/force-usm.cpp
+++ b/offload/test/offloading/force-usm.cpp
@@ -55,6 +55,7 @@ int main(void) {
 // NO-USM-NEXT: device 0 info: Copying data from device to host, TgtPtr={{.*}}, HstPtr={{.*}}, Size=4
 // NO-USM-NEXT: device 0 info: Copying data from device to host, TgtPtr={{.*}}, HstPtr={{.*}}, Size=12
 // NO-USM-NEXT: device 0 info: Copying data from device to host, TgtPtr={{.*}}, HstPtr={{.*}}, Size=4
+// NO-USM-NEXT: device 0 info: Waiting for asynchronous operations to complete
 // NO-USM-NEXT: SUCCESS
 
 // FORCE-USM: SUCCESS
diff --git a/offload/test/offloading/info.c b/offload/test/offloading/info.c
index be2a96f8c0970..06145fe0556ee 100644
--- a/offload/test/offloading/info.c
+++ b/offload/test/offloading/info.c
@@ -30,11 +30,13 @@ int main() {
 // INFO: info: alloc(A[0:64])[256]
 // INFO: info: tofrom(B[0:64])[256]
 // INFO: info: to(C[0:64])[256]
+// INFO: info: Copying data from host to device, HstPtr={{.*}}, TgtPtr={{.*}}, Size={{[0-9]+}}, Name=DeviceEnvironment
 // INFO: info: Creating new map entry with HstPtrBase={{.*}}, HstPtrBegin={{.*}}, TgtPtrBegin={{.*}}, Size=256, DynRefCount=1, HoldRefCount=0, Name=A[0:64]
 // INFO: info: Creating new map entry with HstPtrBase={{.*}}, HstPtrBegin={{.*}}, TgtPtrBegin={{.*}}, Size=256, DynRefCount=0, HoldRefCount=1, Name=B[0:64]
-// INFO: info: Copying data from host to device, HstPtr={{.*}}, TgtPtr={{.*}}, Size=256, Name=B[0:64]
+// INFO: info: Copying data from host to device, HstPtr={{.*}}, TgtPtr={{.*}}, Size=256, Name=B[0:64], at info.c:{{[0-9]+}}:{{[0-9]+}}
 // INFO: info: Creating new map entry with HstPtrBase={{.*}}, HstPtrBegin={{.*}}, TgtPtrBegin={{.*}}, Size=256, DynRefCount=1, HoldRefCount=0, Name=C[0:64]
-// INFO: info: Copying data from host to device, HstPtr={{.*}}, TgtPtr={{.*}}, Size=256, Name=C[0:64]
+// INFO: info: Copying data from host to device, HstPtr={{.*}}, TgtPtr={{.*}}, Size=256, Name=C[0:64], at info.c:{{[0-9]+}}:{{[0-9]+}}
+// INFO: info: Waiting for asynchronous operations to complete at info.c:{{[0-9]+}}:{{[0-9]+}}
 // INFO: info: OpenMP Host-Device pointer mappings after block at info.c:{{[0-9]+}}:{{[0-9]+}}:
 // INFO: info: Host Ptr           Target Ptr         Size (B) DynRefCount HoldRefCount Declaration
 // INFO: info: {{.*}}             {{.*}}             256      1           0            C[0:64] at info.c:{{[0-9]+}}:{{[0-9]+}}
@@ -44,6 +46,7 @@ int main() {
 // INFO: info: firstprivate(val)[4]
 // INFO: info: Launching kernel __omp_offloading_{{.*}}main{{.*}} with [{{[0-9]+}},1,1] blocks and [{{[0-9]+}},1,1] threads in Generic mode
 // AMDGPU: AMDGPU device {{[0-9]}} info: #Args: {{[0-9]}} Teams x Thrds: {{[0-9]+}}x {{[0-9]+}} (MaxFlatWorkGroupSize: {{[0-9]+}}) LDS Usage: {{[0-9]+}}B #SGPRs/VGPRs: {{[0-9]+}}/{{[0-9]+}} #SGPR/VGPR Spills: {{[0-9]+}}/{{[0-9]+}} Tripcount: {{[0-9]+}}
+// INFO: info: Waiting for asynchronous operations to complete at info.c:{{[0-9]+}}:{{[0-9]+}}
 // INFO: info: OpenMP Host-Device pointer mappings after block at info.c:{{[0-9]+}}:{{[0-9]+}}:
 // INFO: info: Host Ptr           Target Ptr         Size (B) DynRefCount HoldRefCount Declaration
 // INFO: info: {{.*}}             {{.*}}             256      1           0            C[0:64] at info.c:{{[0-9]+}}:{{[0-9]+}}
@@ -53,7 +56,8 @@ int main() {
 // INFO: info: alloc(A[0:64])[256]
 // INFO: info: tofrom(B[0:64])[256]
 // INFO: info: to(C[0:64])[256]
-// INFO: info: Copying data from device to host, TgtPtr={{.*}}, HstPtr={{.*}}, Size=256, Name=B[0:64]
+// INFO: info: Copying data from device to host, TgtPtr={{.*}}, HstPtr={{.*}}, Size=256, Name=B[0:64], at info.c:{{[0-9]+}}:{{[0-9]+}}
+// INFO: info: Waiting for asynchronous operations to complete at info.c:{{[0-9]+}}:{{[0-9]+}}
 // INFO: info: Removing map entry with HstPtrBegin={{.*}}, TgtPtrBegin={{.*}}, Size=256, Name=C[0:64]
 // INFO: info: Removing map entry with HstPtrBegin={{.*}}, TgtPtrBegin={{.*}}, Size=256, Name=B[0:64]
 // INFO: info: Removing map entry with HstPtrBegin={{.*}}, TgtPtrBegin={{.*}}, Size=256, Name=A[0:64]

>From cb10b6c440f6b9df63a6a34ebc0b8123541421f3 Mon Sep 17 00:00:00 2001
From: Jason Van Beusekom <jason.van-beusekom at hpe.com>
Date: Wed, 16 Sep 2026 16:45:43 -0500
Subject: [PATCH 2/2] feedback

---
 offload/include/Shared/SourceInfo.h   | 13 -------
 offload/libompaccsupport/Mapping.cpp  |  8 +++--
 offload/libomptarget/interface.cpp    |  4 +--
 offload/libomptarget/private.h        | 10 ++++--
 offload/test/offloading/info_nowait.c | 50 +++++++++++++++++++++++++++
 5 files changed, 65 insertions(+), 20 deletions(-)
 create mode 100644 offload/test/offloading/info_nowait.c

diff --git a/offload/include/Shared/SourceInfo.h b/offload/include/Shared/SourceInfo.h
index 876ccb80fcb0f..63488ff0e8cac 100644
--- a/offload/include/Shared/SourceInfo.h
+++ b/offload/include/Shared/SourceInfo.h
@@ -111,17 +111,4 @@ static inline std::string getNameFromMapping(const map_var_info_t Name) {
   return NameStr.substr(Begin + 1, End - Begin - 1);
 }
 
-/// Returns "<Prefix><filename>:<line>:<column>" when \p Loc carries a
-/// compiler-provided source location, or an empty string otherwise, so info
-/// output can be annotated without emitting "unknown:0:0".
-static inline std::string getSourceLocationSuffix(const ident_t *Loc,
-                                                  const char *Prefix) {
-  SourceInfo Info(Loc);
-  if (!Info.isAvailible())
-    return "";
-  return std::string(Prefix) + Info.getFilename() + ":" +
-         std::to_string(Info.getLine()) + ":" +
-         std::to_string(Info.getColumn());
-}
-
 #endif // OMPTARGET_SHARED_SOURCE_INFO_H
diff --git a/offload/libompaccsupport/Mapping.cpp b/offload/libompaccsupport/Mapping.cpp
index a4905e4106deb..d02689783c6c3 100644
--- a/offload/libompaccsupport/Mapping.cpp
+++ b/offload/libompaccsupport/Mapping.cpp
@@ -560,8 +560,12 @@ static void printCopyInfoImpl(int DeviceId, bool H2D, void *SrcPtrBegin,
                               void *DstPtrBegin, int64_t Size,
                               HostDataToTargetTy *HT, const ident_t *Loc,
                               const char *Name) {
-
-  std::string LocStr = getSourceLocationSuffix(Loc, ", at ");
+  SourceInfo Info(Loc);
+  std::string LocStr;
+  if (Info.isAvailible())
+    LocStr = ", at " + std::string(Info.getFilename()) + ":" +
+             std::to_string(Info.getLine()) + ":" +
+             std::to_string(Info.getColumn());
 
   INFO(OMP_INFOTYPE_DATA_TRANSFER, DeviceId,
        "Copying data from %s to %s, %sPtr=" DPxMOD ", %sPtr=" DPxMOD
diff --git a/offload/libomptarget/interface.cpp b/offload/libomptarget/interface.cpp
index 7b0cd04cda4c2..1346f90d18100 100644
--- a/offload/libomptarget/interface.cpp
+++ b/offload/libomptarget/interface.cpp
@@ -187,7 +187,7 @@ targetData(ident_t *Loc, int64_t DeviceId, int32_t ArgNum, void **ArgsBase,
       Rc = processAttachEntries(*DeviceOrErr, *StateInfo, AsyncInfo);
 
     if (Rc == OFFLOAD_SUCCESS) {
-      printSyncInfo(Loc, DeviceId);
+      printSyncInfo(Loc, DeviceId, AsyncInfo);
       Rc = AsyncInfo.synchronize();
     }
   }
@@ -442,7 +442,7 @@ static inline int targetKernel(ident_t *Loc, int64_t DeviceId, int32_t NumTeams,
   { // required to show synchronization
     TIMESCOPE_WITH_DETAILS_AND_IDENT("Runtime: synchronize", "", Loc);
     if (Rc == OFFLOAD_SUCCESS) {
-      printSyncInfo(Loc, DeviceId);
+      printSyncInfo(Loc, DeviceId, AsyncInfo);
       Rc = AsyncInfo.synchronize();
     }
 
diff --git a/offload/libomptarget/private.h b/offload/libomptarget/private.h
index 0de02cb2304d6..79bdffab9a2e0 100644
--- a/offload/libomptarget/private.h
+++ b/offload/libomptarget/private.h
@@ -89,12 +89,16 @@ printKernelArguments(const ident_t *Loc, const int64_t DeviceId,
 ////////////////////////////////////////////////////////////////////////////////
 /// Report that the runtime is about to wait for the region's outstanding
 /// asynchronous operations (data transfers and kernels) to complete.
-static inline void printSyncInfo(const ident_t *Loc, const int64_t DeviceId) {
+static inline void printSyncInfo(const ident_t *Loc, const int64_t DeviceId,
+                                 const AsyncInfoTy &AsyncInfo) {
   if (!(getInfoLevel() & OMP_INFOTYPE_DATA_TRANSFER))
     return;
-  std::string LocStr = getSourceLocationSuffix(Loc, " at ");
+  if (AsyncInfo.SyncType != AsyncInfoTy::SyncTy::BLOCKING)
+    return;
+  SourceInfo Info(Loc);
   INFO(OMP_INFOTYPE_DATA_TRANSFER, DeviceId,
-       "Waiting for asynchronous operations to complete%s\n", LocStr.c_str());
+       "Waiting for asynchronous operations to complete at %s:%d:%d\n",
+       Info.getFilename(), Info.getLine(), Info.getColumn());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/offload/test/offloading/info_nowait.c b/offload/test/offloading/info_nowait.c
new file mode 100644
index 0000000000000..af2cbefe0151b
--- /dev/null
+++ b/offload/test/offloading/info_nowait.c
@@ -0,0 +1,50 @@
+// Verify LIBOMPTARGET_INFO reporting of data-transfer synchronization.
+//
+// RUN: %libomptarget-compile-generic -gline-tables-only -fopenmp-extensions
+// RUN: env LIBOMPTARGET_INFO=32 %libomptarget-run-generic 2>&1 | \
+// RUN:   %fcheck-generic -allow-empty -check-prefixes=INFO
+
+// FIXME: Fails due to optimized debugging in 'ptxas'.
+// UNSUPPORTED: nvptx64-nvidia-cuda-LTO
+
+#include <stdio.h>
+
+int main(void) {
+  int x = 0, y = 0;
+
+  // Blocking region: synchronization is blocking, so the wait is announced.
+#pragma omp target map(tofrom : x)
+  x = 1;
+
+  // Nowait kernel inside an active parallel/single: it has a task team and
+  // therefore synchronizes non-blockingly, so no wait must be announced even
+  // though its data transfers are still reported.
+#pragma omp parallel num_threads(2)
+#pragma omp single
+  {
+#pragma omp target map(tofrom : x) nowait
+    x = 2;
+#pragma omp taskwait
+  }
+
+  // Nowait target-data constructs reach the synchronization notice through a
+  // different runtime entry point; they are non-blocking here too and likewise
+  // must not announce a wait.
+#pragma omp parallel num_threads(2)
+#pragma omp single
+  {
+#pragma omp target enter data map(to : y) nowait
+#pragma omp taskwait
+#pragma omp target exit data map(from : y) nowait
+#pragma omp taskwait
+  }
+
+  printf("x = %d, y = %d\n", x, y);
+  return x != 2;
+}
+
+// clang-format off
+// INFO: info: Waiting for asynchronous operations to complete at info_nowait.c:{{[0-9]+}}:{{[0-9]+}}
+// INFO: info: Copying data from host to device,{{.*}}at info_nowait.c:{{[0-9]+}}:{{[0-9]+}}
+// INFO-NOT: Waiting for asynchronous operations to complete
+// clang-format on



More information about the llvm-commits mailing list