diff --git a/openmp/libomptarget/include/omptarget.h b/openmp/libomptarget/include/omptarget.h index ffdf9659f278..76180fc123fc 100644 --- a/openmp/libomptarget/include/omptarget.h +++ b/openmp/libomptarget/include/omptarget.h @@ -14,6 +14,7 @@ #ifndef _OMPTARGET_H_ #define _OMPTARGET_H_ +#include #include #include @@ -136,6 +137,10 @@ struct DeviceTy; /// associated with a libomptarget layer device. RAII semantics to avoid /// mistakes. class AsyncInfoTy { + /// Locations we used in (potentially) asynchronous calls which should live + /// as long as this AsyncInfoTy object. + std::deque BufferLocations; + __tgt_async_info AsyncInfo; DeviceTy &Device; @@ -151,6 +156,10 @@ public: /// /// \returns OFFLOAD_FAIL or OFFLOAD_SUCCESS appropriately. int synchronize(); + + /// Return a void* reference with a lifetime that is at least as long as this + /// AsyncInfoTy object. The location can be used as intermediate buffer. + void *&getVoidPtrLocation(); }; /// This struct is a record of non-contiguous information diff --git a/openmp/libomptarget/src/omptarget.cpp b/openmp/libomptarget/src/omptarget.cpp index 51dcfecbad60..ddefdd884918 100644 --- a/openmp/libomptarget/src/omptarget.cpp +++ b/openmp/libomptarget/src/omptarget.cpp @@ -31,6 +31,11 @@ int AsyncInfoTy::synchronize() { return Result; } +void *&AsyncInfoTy::getVoidPtrLocation() { + BufferLocations.push_back(nullptr); + return BufferLocations.back(); +} + /* All begin addresses for partially mapped structs must be 8-aligned in order * to ensure proper alignment of members. E.g. * @@ -432,7 +437,8 @@ int targetDataBegin(ident_t *loc, DeviceTy &Device, int32_t arg_num, DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n", DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin)); uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase; - void *TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta); + void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation(); + TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta); int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase, sizeof(void *), AsyncInfo); if (rt != OFFLOAD_SUCCESS) { @@ -1123,8 +1129,9 @@ static int processDataBefore(ident_t *loc, int64_t DeviceId, void *HostPtr, DP("Parent lambda base " DPxMOD "\n", DPxPTR(TgtPtrBase)); uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase; void *TgtPtrBegin = (void *)((uintptr_t)TgtPtrBase + Delta); - void *PointerTgtPtrBegin = Device.getTgtPtrBegin( - HstPtrVal, ArgSizes[I], IsLast, false, IsHostPtr); + void *&PointerTgtPtrBegin = AsyncInfo.getVoidPtrLocation(); + PointerTgtPtrBegin = Device.getTgtPtrBegin(HstPtrVal, ArgSizes[I], + IsLast, false, IsHostPtr); if (!PointerTgtPtrBegin) { DP("No lambda captured variable mapped (" DPxMOD ") - ignored\n", DPxPTR(HstPtrVal));