[clang] [llvm] [Offload][libsycl][clang-sycl-linker] Simplify SYCL Offload wrapping (PR #193876)

Kseniya Tikhomirova via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 02:54:23 PDT 2026


================
@@ -13,113 +13,95 @@
 #include <detail/device_impl.hpp>
 #include <detail/offload/offload_utils.hpp>
 
-#include <cstring>
+#include <llvm/Frontend/Offloading/Utility.h>
 
 _LIBSYCL_BEGIN_NAMESPACE_SYCL
 namespace detail {
 
-static inline bool checkFatBinVersion(const __sycl_tgt_bin_desc &FatbinDesc) {
-  return FatbinDesc.Version == SupportedOffloadBinaryVersion;
-}
-
 static inline bool
-checkDeviceImageValidity(const __sycl_tgt_device_image &DeviceImage) {
-  return (DeviceImage.Version == SupportedDeviceBinaryVersion) &&
-         (DeviceImage.OffloadKind == llvm::object::OFK_SYCL) &&
-         (DeviceImage.ImageFormat == llvm::object::IMG_SPIRV);
+checkDeviceImageValidity(const llvm::object::OffloadBinary &OB) {
+  return (OB.getOffloadKind() == llvm::object::OFK_SYCL) &&
+         (OB.getImageKind() == llvm::object::IMG_SPIRV);
 }
 
-void ProgramAndKernelManager::registerFatBin(__sycl_tgt_bin_desc *FatbinDesc) {
-  assert(FatbinDesc && "Device images descriptor can't be nullptr");
+void ProgramAndKernelManager::registerFatBin(const void *BinaryStart,
+                                             size_t Size) {
+  assert(BinaryStart && "Binary pointer can't be nullptr");
 
-  if (!checkFatBinVersion(*FatbinDesc))
+  llvm::MemoryBufferRef MBR(
+      llvm::StringRef(static_cast<const char *>(BinaryStart), Size),
+      /*Identifier=*/"");
+  auto BinOrErr = llvm::object::OffloadBinary::create(MBR);
+  if (!BinOrErr || BinOrErr->empty())
     throw sycl::exception(sycl::make_error_code(sycl::errc::runtime),
-                          "Incompatible version of device images descriptor.");
-  if (!FatbinDesc->NumDeviceBinaries)
-    return;
+                          "Failed to parse OffloadBinary");
+
+  DeviceImageManagerVec Images;
+  Images.reserve(BinOrErr->size());
 
   std::lock_guard<std::mutex> Guard(MDataCollectionMutex);
-  for (uint16_t I = 0; I < FatbinDesc->NumDeviceBinaries; ++I) {
-    const auto &RawDeviceImage = FatbinDesc->DeviceImages[I];
-    if (!checkDeviceImageValidity(RawDeviceImage))
+  for (std::unique_ptr<llvm::object::OffloadBinary> &OB : *BinOrErr) {
+    if (!checkDeviceImageValidity(*OB))
       throw sycl::exception(sycl::make_error_code(sycl::errc::runtime),
                             "Incompatible device image.");
 
-    const llvm::offloading::EntryTy *EntriesB = RawDeviceImage.EntriesBegin;
-    const llvm::offloading::EntryTy *EntriesE = RawDeviceImage.EntriesEnd;
-    // Ignore "empty" device image.
-    if (EntriesB == EntriesE)
-      continue;
+    llvm::StringRef Symbols = OB->getString("symbols");
 
-    std::unique_ptr<DeviceImageManager> NewImageWrapper =
-        std::make_unique<DeviceImageManager>(RawDeviceImage);
-
-    for (auto EntriesIt = EntriesB; EntriesIt != EntriesE; ++EntriesIt) {
-      auto Name = EntriesIt->SymbolName;
+    Images.push_back(std::make_unique<DeviceImageManager>(std::move(OB)));
+    DeviceImageManager &NewImageWrapper = *Images.back();
 
+    llvm::offloading::sycl::forEachSymbol(Symbols, [&](llvm::StringRef Name) {
       auto It = MDeviceKernelInfoMap.find(std::string_view(Name));
       if (It == MDeviceKernelInfoMap.end()) {
-
         [[maybe_unused]] auto [Iterator, EmplaceSucceeded] =
             MDeviceKernelInfoMap.emplace(
-                std::piecewise_construct, std::forward_as_tuple(Name),
-                std::forward_as_tuple(Name, *NewImageWrapper));
+                std::piecewise_construct,
+                std::forward_as_tuple(std::string_view(Name)),
+                std::forward_as_tuple(std::string_view(Name), NewImageWrapper));
         assert(EmplaceSucceeded && "Kernel name found in multiple images");
       }
-    }
-
-    MDeviceImageManagers.insert(
-        std::make_pair(&RawDeviceImage, std::move(NewImageWrapper)));
+    });
   }
-}
 
-void ProgramAndKernelManager::unregisterFatBin(
-    __sycl_tgt_bin_desc *FatbinDesc) {
-  assert(FatbinDesc && "Device images descriptor can't be nullptr");
+  [[maybe_unused]] auto [It, Inserted] =
+      MDeviceImageManagers.emplace(BinaryStart, std::move(Images));
+  assert(Inserted && "Fat binary registered twice");
+}
 
-  if (!checkFatBinVersion(*FatbinDesc) || FatbinDesc->NumDeviceBinaries == 0)
-    return;
+void ProgramAndKernelManager::unregisterFatBin(const void *BinaryStart) {
----------------
KseniyaTikhomirova wrote:

I would keep signature the same as registerFatBin. The fact that we use only pointer for clean up now is implementation details of SYCL RT

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


More information about the cfe-commits mailing list