[clang] afd2f7e - [Binary] Promote OffloadBinary to inherit from Binary

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 1 15:41:06 PDT 2022


Author: Joseph Huber
Date: 2022-06-01T18:40:57-04:00
New Revision: afd2f7e9919737e30f9fae2d3cff892189301a55

URL: https://github.com/llvm/llvm-project/commit/afd2f7e9919737e30f9fae2d3cff892189301a55
DIFF: https://github.com/llvm/llvm-project/commit/afd2f7e9919737e30f9fae2d3cff892189301a55.diff

LOG: [Binary] Promote OffloadBinary to inherit from Binary

We use the `OffloadBinary` to create binary images of offloading files
and their corresonding metadata. This patch changes this to inherit from
the base `Binary` class. This allows us to create and insepect these
more generically. This patch includes all the necessary glue to
implement this as a new binary format, along with added the magic bytes
we use to distinguish the offloading binary to the `file_magic`
implementation.

Reviewed By: tra

Differential Revision: https://reviews.llvm.org/D126812

Added: 
    

Modified: 
    clang/lib/CodeGen/BackendUtil.cpp
    llvm/include/llvm-c/Object.h
    llvm/include/llvm/BinaryFormat/Magic.h
    llvm/include/llvm/Object/Binary.h
    llvm/include/llvm/Object/OffloadBinary.h
    llvm/lib/BinaryFormat/Magic.cpp
    llvm/lib/Object/Binary.cpp
    llvm/lib/Object/Object.cpp
    llvm/lib/Object/ObjectFile.cpp
    llvm/lib/Object/OffloadBinary.cpp
    llvm/unittests/Object/OffloadingTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 94808e8a625e6..0de15b1e48078 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1221,6 +1221,6 @@ void clang::EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
     }
 
     llvm::embedBufferInModule(*M, **ObjectOrErr, ".llvm.offloading",
-                              Align(OffloadBinary::getAlignment()));
+                              Align(object::OffloadBinary::getAlignment()));
   }
 }

diff  --git a/llvm/include/llvm-c/Object.h b/llvm/include/llvm-c/Object.h
index 9a9596aaa08cd..f422c1ad224d2 100644
--- a/llvm/include/llvm-c/Object.h
+++ b/llvm/include/llvm-c/Object.h
@@ -38,21 +38,23 @@ typedef struct LLVMOpaqueSymbolIterator *LLVMSymbolIteratorRef;
 typedef struct LLVMOpaqueRelocationIterator *LLVMRelocationIteratorRef;
 
 typedef enum {
-  LLVMBinaryTypeArchive,                /**< Archive file. */
-  LLVMBinaryTypeMachOUniversalBinary,   /**< Mach-O Universal Binary file. */
-  LLVMBinaryTypeCOFFImportFile,         /**< COFF Import file. */
-  LLVMBinaryTypeIR,                     /**< LLVM IR. */
-  LLVMBinaryTypeWinRes,                 /**< Windows resource (.res) file. */
-  LLVMBinaryTypeCOFF,                   /**< COFF Object file. */
-  LLVMBinaryTypeELF32L,                 /**< ELF 32-bit, little endian. */
-  LLVMBinaryTypeELF32B,                 /**< ELF 32-bit, big endian. */
-  LLVMBinaryTypeELF64L,                 /**< ELF 64-bit, little endian. */
-  LLVMBinaryTypeELF64B,                 /**< ELF 64-bit, big endian. */
-  LLVMBinaryTypeMachO32L,               /**< MachO 32-bit, little endian. */
-  LLVMBinaryTypeMachO32B,               /**< MachO 32-bit, big endian. */
-  LLVMBinaryTypeMachO64L,               /**< MachO 64-bit, little endian. */
-  LLVMBinaryTypeMachO64B,               /**< MachO 64-bit, big endian. */
-  LLVMBinaryTypeWasm,                   /**< Web Assembly. */
+  LLVMBinaryTypeArchive,              /**< Archive file. */
+  LLVMBinaryTypeMachOUniversalBinary, /**< Mach-O Universal Binary file. */
+  LLVMBinaryTypeCOFFImportFile,       /**< COFF Import file. */
+  LLVMBinaryTypeIR,                   /**< LLVM IR. */
+  LLVMBinaryTypeWinRes,               /**< Windows resource (.res) file. */
+  LLVMBinaryTypeCOFF,                 /**< COFF Object file. */
+  LLVMBinaryTypeELF32L,               /**< ELF 32-bit, little endian. */
+  LLVMBinaryTypeELF32B,               /**< ELF 32-bit, big endian. */
+  LLVMBinaryTypeELF64L,               /**< ELF 64-bit, little endian. */
+  LLVMBinaryTypeELF64B,               /**< ELF 64-bit, big endian. */
+  LLVMBinaryTypeMachO32L,             /**< MachO 32-bit, little endian. */
+  LLVMBinaryTypeMachO32B,             /**< MachO 32-bit, big endian. */
+  LLVMBinaryTypeMachO64L,             /**< MachO 64-bit, little endian. */
+  LLVMBinaryTypeMachO64B,             /**< MachO 64-bit, big endian. */
+  LLVMBinaryTypeWasm,                 /**< Web Assembly. */
+  LLVMBinaryTypeOffload,              /**< Offloading fatbinary. */
+
 } LLVMBinaryType;
 
 /**

diff  --git a/llvm/include/llvm/BinaryFormat/Magic.h b/llvm/include/llvm/BinaryFormat/Magic.h
index b6bc4e9b2a7a3..c8e0dad42b0bc 100644
--- a/llvm/include/llvm/BinaryFormat/Magic.h
+++ b/llvm/include/llvm/BinaryFormat/Magic.h
@@ -52,6 +52,7 @@ struct file_magic {
     pdb,                 ///< Windows PDB debug info file
     tapi_file,           ///< Text-based Dynamic Library Stub file
     cuda_fatbinary,      ///< CUDA Fatbinary object file
+    offload_binary,      ///< LLVM offload object file
     dxcontainer_object,  ///< DirectX container file
   };
 

diff  --git a/llvm/include/llvm/Object/Binary.h b/llvm/include/llvm/Object/Binary.h
index b496956fc2123..77ebf250bc0e7 100644
--- a/llvm/include/llvm/Object/Binary.h
+++ b/llvm/include/llvm/Object/Binary.h
@@ -69,6 +69,8 @@ class Binary {
 
     ID_Wasm,
 
+    ID_Offload, // Offloading binary file.
+
     ID_EndObjects
   };
 
@@ -133,6 +135,8 @@ class Binary {
 
   bool isWasm() const { return TypeID == ID_Wasm; }
 
+  bool isOffloadFile() const { return TypeID == ID_Offload; }
+
   bool isCOFFImportFile() const {
     return TypeID == ID_COFFImportFile;
   }

diff  --git a/llvm/include/llvm/Object/OffloadBinary.h b/llvm/include/llvm/Object/OffloadBinary.h
index d8a7d5fff7ae4..3a8c98105c93b 100644
--- a/llvm/include/llvm/Object/OffloadBinary.h
+++ b/llvm/include/llvm/Object/OffloadBinary.h
@@ -19,12 +19,15 @@
 
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Binary.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <memory>
 
 namespace llvm {
 
+namespace object {
+
 /// The producer of the associated offloading image.
 enum OffloadKind : uint16_t {
   OFK_None = 0,
@@ -54,7 +57,7 @@ enum ImageKind : uint16_t {
 /// detect ABI stability and the size is used to find other offloading entries
 /// that may exist in the same section. All offsets are given as absolute byte
 /// offsets from the beginning of the file.
-class OffloadBinary {
+class OffloadBinary : public Binary {
 public:
   /// The offloading metadata that will be serialized to a memory buffer.
   struct OffloadingImage {
@@ -87,6 +90,8 @@ class OffloadBinary {
 
   StringRef getString(StringRef Key) const { return StringData.lookup(Key); }
 
+  static bool classof(const Binary *V) { return V->isOffloadFile(); }
+
 private:
   struct Header {
     uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
@@ -111,10 +116,10 @@ class OffloadBinary {
     uint64_t ValueOffset;
   };
 
-  OffloadBinary(const char *Buffer, const Header *TheHeader,
+  OffloadBinary(MemoryBufferRef Source, const Header *TheHeader,
                 const Entry *TheEntry)
-      : Buffer(Buffer), TheHeader(TheHeader), TheEntry(TheEntry) {
-
+      : Binary(Binary::ID_Offload, Source), Buffer(Source.getBufferStart()),
+        TheHeader(TheHeader), TheEntry(TheEntry) {
     const StringEntry *StringMapBegin =
         reinterpret_cast<const StringEntry *>(&Buffer[TheEntry->StringOffset]);
     for (uint64_t I = 0, E = TheEntry->NumStrings; I != E; ++I) {
@@ -127,7 +132,7 @@ class OffloadBinary {
 
   /// Map from keys to offsets in the binary.
   StringMap<StringRef> StringData;
-  /// Pointer to the beginning of the memory buffer for convenience.
+  /// Raw pointer to the MemoryBufferRef for convenience.
   const char *Buffer;
   /// Location of the header within the binary.
   const Header *TheHeader;
@@ -147,5 +152,7 @@ OffloadKind getOffloadKind(StringRef Name);
 /// Convert an offload kind to its string representation.
 StringRef getOffloadKindName(OffloadKind Name);
 
+} // namespace object
+
 } // namespace llvm
 #endif

diff  --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index 99d3f692889de..d45195fb95c5c 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -74,6 +74,11 @@ file_magic llvm::identify_magic(StringRef Magic) {
       return file_magic::goff_object;
     break;
 
+  case 0x10:
+    if (startswith(Magic, "\x10\xFF\x10\xAD"))
+      return file_magic::offload_binary;
+    break;
+
   case 0xDE: // 0x0B17C0DE = BC wraper
     if (startswith(Magic, "\xDE\xC0\x17\x0B"))
       return file_magic::bitcode;

diff  --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp
index 1703f76cf318f..8065e3eb1d852 100644
--- a/llvm/lib/Object/Binary.cpp
+++ b/llvm/lib/Object/Binary.cpp
@@ -18,6 +18,7 @@
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/Minidump.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/OffloadBinary.h"
 #include "llvm/Object/TapiUniversal.h"
 #include "llvm/Object/WindowsResource.h"
 #include "llvm/Support/Error.h"
@@ -87,6 +88,8 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
   case file_magic::dxcontainer_object:
     // Unrecognized object file format.
     return errorCodeToError(object_error::invalid_file_type);
+  case file_magic::offload_binary:
+    return OffloadBinary::create(Buffer);
   case file_magic::minidump:
     return MinidumpFile::create(Buffer);
   case file_magic::tapi_file:

diff  --git a/llvm/lib/Object/Object.cpp b/llvm/lib/Object/Object.cpp
index 576eb8d069d62..d5e67160dfa36 100644
--- a/llvm/lib/Object/Object.cpp
+++ b/llvm/lib/Object/Object.cpp
@@ -120,6 +120,8 @@ LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {
         return LLVMBinaryTypeMachO64L;
       case ID_MachO64B:
         return LLVMBinaryTypeMachO64B;
+      case ID_Offload:
+        return LLVMBinaryTypeOffload;
       case ID_Wasm:
         return LLVMBinaryTypeWasm;
       case ID_StartObjects:

diff  --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp
index 609dfae25929e..1be8f11751beb 100644
--- a/llvm/lib/Object/ObjectFile.cpp
+++ b/llvm/lib/Object/ObjectFile.cpp
@@ -147,6 +147,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
   case file_magic::minidump:
   case file_magic::goff_object:
   case file_magic::cuda_fatbinary:
+  case file_magic::offload_binary:
   case file_magic::dxcontainer_object:
     return errorCodeToError(object_error::invalid_file_type);
   case file_magic::tapi_file:

diff  --git a/llvm/lib/Object/OffloadBinary.cpp b/llvm/lib/Object/OffloadBinary.cpp
index 6a64147ecebf7..f57d07c390233 100644
--- a/llvm/lib/Object/OffloadBinary.cpp
+++ b/llvm/lib/Object/OffloadBinary.cpp
@@ -9,22 +9,23 @@
 #include "llvm/Object/OffloadBinary.h"
 
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Magic.h"
 #include "llvm/MC/StringTableBuilder.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Support/FileOutputBuffer.h"
 
-using namespace llvm;
-
 namespace llvm {
 
+namespace object {
+
 Expected<std::unique_ptr<OffloadBinary>>
 OffloadBinary::create(MemoryBufferRef Buf) {
   if (Buf.getBufferSize() < sizeof(Header) + sizeof(Entry))
-    return errorCodeToError(llvm::object::object_error::parse_failed);
+    return errorCodeToError(object_error::parse_failed);
 
   // Check for 0x10FF1OAD magic bytes.
-  if (!Buf.getBuffer().startswith("\x10\xFF\x10\xAD"))
-    return errorCodeToError(llvm::object::object_error::parse_failed);
+  if (identify_magic(Buf.getBuffer()) != file_magic::offload_binary)
+    return errorCodeToError(object_error::parse_failed);
 
   const char *Start = Buf.getBufferStart();
   const Header *TheHeader = reinterpret_cast<const Header *>(Start);
@@ -32,7 +33,7 @@ OffloadBinary::create(MemoryBufferRef Buf) {
       reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);
 
   return std::unique_ptr<OffloadBinary>(
-      new OffloadBinary(Buf.getBufferStart(), TheHeader, TheEntry));
+      new OffloadBinary(Buf, TheHeader, TheEntry));
 }
 
 std::unique_ptr<MemoryBuffer>
@@ -141,4 +142,6 @@ StringRef getImageKindName(ImageKind Kind) {
   }
 }
 
+} // namespace object
+
 } // namespace llvm

diff  --git a/llvm/unittests/Object/OffloadingTest.cpp b/llvm/unittests/Object/OffloadingTest.cpp
index c404068c9424a..97c89ec450c3c 100644
--- a/llvm/unittests/Object/OffloadingTest.cpp
+++ b/llvm/unittests/Object/OffloadingTest.cpp
@@ -4,6 +4,9 @@
 #include "gtest/gtest.h"
 #include <random>
 
+using namespace llvm;
+using namespace llvm::object;
+
 TEST(OffloadingTest, checkOffloadingBinary) {
   // Create random data to fill the image.
   std::mt19937 Rng(std::random_device{}());
@@ -27,23 +30,22 @@ TEST(OffloadingTest, checkOffloadingBinary) {
   }
 
   // Create the image.
-  llvm::StringMap<llvm::StringRef> StringData;
+  StringMap<StringRef> StringData;
   for (auto &KeyAndValue : Strings)
     StringData[KeyAndValue.first] = KeyAndValue.second;
-  std::unique_ptr<llvm::MemoryBuffer> ImageData =
-      llvm::MemoryBuffer::getMemBuffer(
-          {reinterpret_cast<char *>(Image.data()), Image.size()}, "", false);
+  std::unique_ptr<MemoryBuffer> ImageData = MemoryBuffer::getMemBuffer(
+      {reinterpret_cast<char *>(Image.data()), Image.size()}, "", false);
 
-  llvm::OffloadBinary::OffloadingImage Data;
-  Data.TheImageKind = static_cast<llvm::ImageKind>(KindDist(Rng));
-  Data.TheOffloadKind = static_cast<llvm::OffloadKind>(KindDist(Rng));
+  OffloadBinary::OffloadingImage Data;
+  Data.TheImageKind = static_cast<ImageKind>(KindDist(Rng));
+  Data.TheOffloadKind = static_cast<OffloadKind>(KindDist(Rng));
   Data.Flags = KindDist(Rng);
   Data.StringData = StringData;
   Data.Image = *ImageData;
 
-  auto BinaryBuffer = llvm::OffloadBinary::write(Data);
+  auto BinaryBuffer = OffloadBinary::write(Data);
 
-  auto BinaryOrErr = llvm::OffloadBinary::create(*BinaryBuffer);
+  auto BinaryOrErr = OffloadBinary::create(*BinaryBuffer);
   if (!BinaryOrErr)
     FAIL();
 
@@ -60,6 +62,6 @@ TEST(OffloadingTest, checkOffloadingBinary) {
   EXPECT_TRUE(Data.Image.getBuffer() == Binary.getImage());
 
   // Ensure the size and alignment of the data is correct.
-  EXPECT_TRUE(Binary.getSize() % llvm::OffloadBinary::getAlignment() == 0);
+  EXPECT_TRUE(Binary.getSize() % OffloadBinary::getAlignment() == 0);
   EXPECT_TRUE(Binary.getSize() == BinaryBuffer->getBuffer().size());
 }


        


More information about the cfe-commits mailing list