https://github.com/YuriPlyakhin updated https://github.com/llvm/llvm-project/pull/169425
>From ce7ab7652cf29469a8addea8ebe67f408b4b03af Mon Sep 17 00:00:00 2001 From: "Plyakhin, Yury" <[email protected]> Date: Tue, 25 Nov 2025 00:40:45 +0100 Subject: [PATCH 1/3] [Offloading] Extend OffloadBinary format to support multiple metadata entries --- llvm/include/llvm/Object/OffloadBinary.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Object/OffloadBinary.h b/llvm/include/llvm/Object/OffloadBinary.h index f3847c1624977..cf25c02bc43fd 100644 --- a/llvm/include/llvm/Object/OffloadBinary.h +++ b/llvm/include/llvm/Object/OffloadBinary.h @@ -67,7 +67,7 @@ class OffloadBinary : public Binary { using string_iterator_range = iterator_range<string_iterator>; /// The current version of the binary used for backwards compatibility. - static const uint32_t Version = 1; + static const uint32_t Version = 2; /// The offloading metadata that will be serialized to a memory buffer. struct OffloadingImage { @@ -109,9 +109,12 @@ class OffloadBinary : public Binary { struct Header { uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes. uint32_t Version = OffloadBinary::Version; // Version identifier. - uint64_t Size; // Size in bytes of this entire binary. - uint64_t EntryOffset; // Offset of the metadata entry in bytes. - uint64_t EntrySize; // Size of the metadata entry in bytes. + uint64_t Size; // Size in bytes of this entire binary. + uint64_t EntriesCount; // Number of metadata entries in the binary. + uint64_t EntriesOffset; // Offset in bytes to the start of entries block. + uint64_t EntriesSize; // Size of the entries block in bytes. + uint64_t StringOffset; // Offset in bytes to the global string map + uint64_t NumStrings; // Number of entries in the global string map. }; struct Entry { @@ -127,6 +130,7 @@ class OffloadBinary : public Binary { struct StringEntry { uint64_t KeyOffset; uint64_t ValueOffset; + uint64_t ValueSize; // Size of the value in bytes. }; private: >From f66ae8cca8d7678ba900c15eef1fa5fdb83a70dc Mon Sep 17 00:00:00 2001 From: "Plyakhin, Yury" <[email protected]> Date: Tue, 25 Nov 2025 21:04:43 +0100 Subject: [PATCH 2/3] updated offloadbinary per discussion --- llvm/include/llvm/Object/OffloadBinary.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/Object/OffloadBinary.h b/llvm/include/llvm/Object/OffloadBinary.h index cf25c02bc43fd..bdcacce204966 100644 --- a/llvm/include/llvm/Object/OffloadBinary.h +++ b/llvm/include/llvm/Object/OffloadBinary.h @@ -52,6 +52,13 @@ enum ImageKind : uint16_t { IMG_LAST, }; +/// Flags associated with the Entry. +enum OffloadEntryFlags : uint32_t { + OIF_None = 0, + // Entry doesn't contain image. Used to keep metadata only entries. + OIF_NoImage = (1 << 0), +}; + /// A simple binary serialization of an offloading file. We use this format to /// embed the offloading image into the host executable so it can be extracted /// and used by the linker. @@ -110,17 +117,14 @@ class OffloadBinary : public Binary { uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes. uint32_t Version = OffloadBinary::Version; // Version identifier. uint64_t Size; // Size in bytes of this entire binary. - uint64_t EntriesCount; // Number of metadata entries in the binary. uint64_t EntriesOffset; // Offset in bytes to the start of entries block. - uint64_t EntriesSize; // Size of the entries block in bytes. - uint64_t StringOffset; // Offset in bytes to the global string map - uint64_t NumStrings; // Number of entries in the global string map. + uint64_t EntriesCount; // Number of metadata entries in the binary. }; struct Entry { ImageKind TheImageKind; // The kind of the image stored. OffloadKind TheOffloadKind; // The producer of this image. - uint32_t Flags; // Additional flags associated with the image. + uint32_t Flags; // Additional flags associated with the entry. uint64_t StringOffset; // Offset in bytes to the string map. uint64_t NumStrings; // Number of entries in the string map. uint64_t ImageOffset; // Offset in bytes of the actual binary image. >From 98ad7e9b818a68029b4f8d1b274d5165d8dd1bdf Mon Sep 17 00:00:00 2001 From: "Plyakhin, Yury" <[email protected]> Date: Wed, 26 Nov 2025 03:16:48 +0100 Subject: [PATCH 3/3] Minimal changes to make build and lit tests pass with new OffloadBinary format. --- clang/test/Driver/linker-wrapper-image.c | 2 +- llvm/include/llvm/Object/OffloadBinary.h | 2 +- llvm/include/llvm/ObjectYAML/OffloadYAML.h | 4 ++-- .../Frontend/Offloading/OffloadWrapper.cpp | 2 +- llvm/lib/Object/OffloadBinary.cpp | 24 +++++++++++-------- llvm/lib/ObjectYAML/OffloadEmitter.cpp | 8 +++---- llvm/lib/ObjectYAML/OffloadYAML.cpp | 4 ++-- ...size.yaml => malformed-entries-count.yaml} | 2 +- .../ObjectYAML/Offload/malformed-offset.yaml | 2 +- .../ObjectYAML/Offload/malformed-version.yaml | 2 +- 10 files changed, 28 insertions(+), 24 deletions(-) rename llvm/test/ObjectYAML/Offload/{malformed-entry-size.yaml => malformed-entries-count.yaml} (94%) diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c index b9327121edcf9..2c0df8c6be925 100644 --- a/clang/test/Driver/linker-wrapper-image.c +++ b/clang/test/Driver/linker-wrapper-image.c @@ -25,7 +25,7 @@ // OPENMP-REL: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading.relocatable", align 8 // OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading", align 8 -// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr getelementptr ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries }] +// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr ([[[IMG_OFF:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 [[IMG_OFF]]), ptr getelementptr ([[[IMG_OFF]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 [[IMG_OFF]]), ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries }] // OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries } // OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] diff --git a/llvm/include/llvm/Object/OffloadBinary.h b/llvm/include/llvm/Object/OffloadBinary.h index bdcacce204966..74dcd5cc7384b 100644 --- a/llvm/include/llvm/Object/OffloadBinary.h +++ b/llvm/include/llvm/Object/OffloadBinary.h @@ -134,7 +134,7 @@ class OffloadBinary : public Binary { struct StringEntry { uint64_t KeyOffset; uint64_t ValueOffset; - uint64_t ValueSize; // Size of the value in bytes. + uint64_t ValueSize; // Size of the value in bytes. }; private: diff --git a/llvm/include/llvm/ObjectYAML/OffloadYAML.h b/llvm/include/llvm/ObjectYAML/OffloadYAML.h index f897b52aa8b0e..63ff561f3fcbf 100644 --- a/llvm/include/llvm/ObjectYAML/OffloadYAML.h +++ b/llvm/include/llvm/ObjectYAML/OffloadYAML.h @@ -39,8 +39,8 @@ struct Binary { std::optional<uint32_t> Version; std::optional<uint64_t> Size; - std::optional<uint64_t> EntryOffset; - std::optional<uint64_t> EntrySize; + std::optional<uint64_t> EntriesOffset; + std::optional<uint64_t> EntriesCount; std::vector<Member> Members; }; diff --git a/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp b/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp index 288fa10fc04bb..f1602765dbaa7 100644 --- a/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp +++ b/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp @@ -161,7 +161,7 @@ GlobalVariable *createBinDesc(Module &M, ArrayRef<ArrayRef<char>> Bufs, Binary.bytes_begin()); const auto *Entry = reinterpret_cast<const object::OffloadBinary::Entry *>( - Binary.bytes_begin() + Header->EntryOffset); + Binary.bytes_begin() + Header->EntriesOffset); BeginOffset = Entry->ImageOffset; EndOffset = Entry->ImageOffset + Entry->ImageSize; } diff --git a/llvm/lib/Object/OffloadBinary.cpp b/llvm/lib/Object/OffloadBinary.cpp index 3fff6b6a09e08..8e51b94b92951 100644 --- a/llvm/lib/Object/OffloadBinary.cpp +++ b/llvm/lib/Object/OffloadBinary.cpp @@ -189,19 +189,23 @@ OffloadBinary::create(MemoryBufferRef Buf) { TheHeader->Size < sizeof(Entry) || TheHeader->Size < sizeof(Header)) return errorCodeToError(object_error::unexpected_eof); - if (TheHeader->EntryOffset > TheHeader->Size - sizeof(Entry) || - TheHeader->EntrySize > TheHeader->Size - sizeof(Header)) + uint64_t EntriesSize = sizeof(Entry) * TheHeader->EntriesCount; + if (TheHeader->EntriesOffset > TheHeader->Size - EntriesSize || + EntriesSize > TheHeader->Size - sizeof(Header)) return errorCodeToError(object_error::unexpected_eof); - const Entry *TheEntry = - reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]); + const Entry *Entries = + reinterpret_cast<const Entry *>(&Start[TheHeader->EntriesOffset]); + for (uint32_t I = 0; I < TheHeader->EntriesCount; ++I) { + const Entry *TheEntry = &Entries[I]; - if (TheEntry->ImageOffset > Buf.getBufferSize() || - TheEntry->StringOffset > Buf.getBufferSize()) - return errorCodeToError(object_error::unexpected_eof); + if (TheEntry->ImageOffset > Buf.getBufferSize() || + TheEntry->StringOffset > Buf.getBufferSize()) + return errorCodeToError(object_error::unexpected_eof); + } return std::unique_ptr<OffloadBinary>( - new OffloadBinary(Buf, TheHeader, TheEntry)); + new OffloadBinary(Buf, TheHeader, Entries)); } SmallString<0> OffloadBinary::write(const OffloadingImage &OffloadingData) { @@ -227,8 +231,8 @@ SmallString<0> OffloadBinary::write(const OffloadingImage &OffloadingData) { Header TheHeader; TheHeader.Size = alignTo( BinaryDataSize + OffloadingData.Image->getBufferSize(), getAlignment()); - TheHeader.EntryOffset = sizeof(Header); - TheHeader.EntrySize = sizeof(Entry); + TheHeader.EntriesOffset = sizeof(Header); + TheHeader.EntriesCount = 1; // Create the entry using the string table offsets. The string table will be // placed directly after the entry in memory, and the image after that. diff --git a/llvm/lib/ObjectYAML/OffloadEmitter.cpp b/llvm/lib/ObjectYAML/OffloadEmitter.cpp index 131da68d77506..34eca4d61a410 100644 --- a/llvm/lib/ObjectYAML/OffloadEmitter.cpp +++ b/llvm/lib/ObjectYAML/OffloadEmitter.cpp @@ -45,10 +45,10 @@ bool yaml2offload(Binary &Doc, raw_ostream &Out, ErrorHandler EH) { TheHeader->Version = *Doc.Version; if (Doc.Size) TheHeader->Size = *Doc.Size; - if (Doc.EntryOffset) - TheHeader->EntryOffset = *Doc.EntryOffset; - if (Doc.EntrySize) - TheHeader->EntrySize = *Doc.EntrySize; + if (Doc.EntriesOffset) + TheHeader->EntriesOffset = *Doc.EntriesOffset; + if (Doc.EntriesCount) + TheHeader->EntriesCount = *Doc.EntriesCount; Out.write(Buffer.begin(), Buffer.size()); } diff --git a/llvm/lib/ObjectYAML/OffloadYAML.cpp b/llvm/lib/ObjectYAML/OffloadYAML.cpp index d5a0edde2179f..cab5a39741294 100644 --- a/llvm/lib/ObjectYAML/OffloadYAML.cpp +++ b/llvm/lib/ObjectYAML/OffloadYAML.cpp @@ -50,8 +50,8 @@ void MappingTraits<OffloadYAML::Binary>::mapping(IO &IO, IO.mapTag("!Offload", true); IO.mapOptional("Version", O.Version); IO.mapOptional("Size", O.Size); - IO.mapOptional("EntryOffset", O.EntryOffset); - IO.mapOptional("EntrySize", O.EntrySize); + IO.mapOptional("EntriesOffset", O.EntriesOffset); + IO.mapOptional("EntriesCount", O.EntriesCount); IO.mapRequired("Members", O.Members); IO.setContext(nullptr); } diff --git a/llvm/test/ObjectYAML/Offload/malformed-entry-size.yaml b/llvm/test/ObjectYAML/Offload/malformed-entries-count.yaml similarity index 94% rename from llvm/test/ObjectYAML/Offload/malformed-entry-size.yaml rename to llvm/test/ObjectYAML/Offload/malformed-entries-count.yaml index 3194607ae39a5..bb2a34277963f 100644 --- a/llvm/test/ObjectYAML/Offload/malformed-entry-size.yaml +++ b/llvm/test/ObjectYAML/Offload/malformed-entries-count.yaml @@ -1,6 +1,6 @@ # RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s !Offload -EntrySize: 999999999 +EntriesCount: 999999999 Members: - ImageKind: IMG_Cubin OffloadKind: OFK_OpenMP diff --git a/llvm/test/ObjectYAML/Offload/malformed-offset.yaml b/llvm/test/ObjectYAML/Offload/malformed-offset.yaml index 03c0431053cce..5aecfffd937bf 100644 --- a/llvm/test/ObjectYAML/Offload/malformed-offset.yaml +++ b/llvm/test/ObjectYAML/Offload/malformed-offset.yaml @@ -1,6 +1,6 @@ # RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s !Offload -EntryOffset: 999999999 +EntriesOffset: 999999999 Members: - ImageKind: IMG_Cubin OffloadKind: OFK_OpenMP diff --git a/llvm/test/ObjectYAML/Offload/malformed-version.yaml b/llvm/test/ObjectYAML/Offload/malformed-version.yaml index f9279a52e2764..99383491acce0 100644 --- a/llvm/test/ObjectYAML/Offload/malformed-version.yaml +++ b/llvm/test/ObjectYAML/Offload/malformed-version.yaml @@ -1,6 +1,6 @@ # RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s !Offload -Version: 2 +Version: 3 Members: - ImageKind: IMG_Cubin OffloadKind: OFK_OpenMP _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
