[llvm] 5f15479 - [JITLink] Add convenience methods for creating block readers / writers.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 18 16:25:53 PDT 2022


Author: Lang Hames
Date: 2022-10-18T16:25:47-07:00
New Revision: 5f154795efc999cb0b6c15e82bbdf55ec15d1cac

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

LOG: [JITLink] Add convenience methods for creating block readers / writers.

This saves clients some boilerplate compared to setting up the readers and
writers manually.

To obtain a BinaryStreamWriter / BinaryStreamReader for a given block, B,
clients can now write:

auto Reader = G.getBlockContentReader(B);

and

auto Writer = G.getBlockContentWriter(B);

The latter will trigger a copy to mutable memory allocated on the graph's
allocator if the block is currently marked as backed by read-only memory.

This commit also introduces a new createMutableContentBlock overload that
creates a block with a given size and zero-filled content (by default --
passing false for the ZeroInitialize bypasses initialization entirely).
This overload is intended to be used with getBlockContentWriter above when
creating new content for the graph.

Added: 
    

Modified: 
    llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
    llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index 7f8dd7303050f..f6e7706a7e9e3 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -22,6 +22,8 @@
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
@@ -1031,6 +1033,20 @@ class LinkGraph {
                        AlignmentOffset);
   }
 
+  /// Create a content block with initially mutable data of the given size.
+  /// Content will be allocated via the LinkGraph's allocateBuffer method.
+  /// By default the memory will be zero-initialized. Passing false for
+  /// ZeroInitialize will prevent this.
+  Block &createMutableContentBlock(Section &Parent, size_t ContentSize,
+                                   orc::ExecutorAddr Address,
+                                   uint64_t Alignment, uint64_t AlignmentOffset,
+                                   bool ZeroInitialize = true) {
+    auto Content = allocateContent(ContentSize);
+    if (ZeroInitialize)
+      memset(Content.data(), 0, Content.size());
+    return createBlock(Parent, Content, Address, Alignment, AlignmentOffset);
+  }
+
   /// Create a zero-fill block.
   Block &createZeroFillBlock(Section &Parent, orc::ExecutorAddrDiff Size,
                              orc::ExecutorAddr Address, uint64_t Alignment,
@@ -1038,6 +1054,22 @@ class LinkGraph {
     return createBlock(Parent, Size, Address, Alignment, AlignmentOffset);
   }
 
+  /// Returns a BinaryStreamReader for the given block.
+  BinaryStreamReader getBlockContentReader(Block &B) {
+    ArrayRef<uint8_t> C(
+        reinterpret_cast<const uint8_t *>(B.getContent().data()), B.getSize());
+    return BinaryStreamReader(C, getEndianness());
+  }
+
+  /// Returns a BinaryStreamWriter for the given block.
+  /// This will call getMutableContent to obtain mutable content for the block.
+  BinaryStreamWriter getBlockContentWriter(Block &B) {
+    MutableArrayRef<uint8_t> C(
+        reinterpret_cast<uint8_t *>(B.getMutableContent(*this).data()),
+        B.getSize());
+    return BinaryStreamWriter(C, getEndianness());
+  }
+
   /// Cache type for the splitBlock function.
   using SplitBlockCache = Optional<SmallVector<Symbol *, 8>>;
 

diff  --git a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
index bbb93ceb4b243..c16757d7c55af 100644
--- a/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
+++ b/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp
@@ -10,6 +10,8 @@
 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Memory.h"
+
+#include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -196,6 +198,16 @@ TEST(LinkGraphTest, ContentAccessAndUpdate) {
   EXPECT_EQ(MutableContent3.size(), MutableContent.size())
       << "Unexpected mutable content 2 size";
 
+  // Check that we can obtain a writer and reader over the content.
+  // Check that we can get a BinaryStreamReader for B.
+  auto Writer = G.getBlockContentWriter(B);
+  EXPECT_THAT_ERROR(Writer.writeInteger((uint32_t)0xcafef00d), Succeeded());
+
+  auto Reader = G.getBlockContentReader(B);
+  uint32_t Initial32Bits = 0;
+  EXPECT_THAT_ERROR(Reader.readInteger(Initial32Bits), Succeeded());
+  EXPECT_EQ(Initial32Bits, (uint32_t)0xcafef00d);
+
   // Set content back to immutable and check that everything behaves as
   // expected again.
   B.setContent(BlockContent);


        


More information about the llvm-commits mailing list