[ARM] Basic And/Or/Xor handling for MVE predicates
[llvm-complete.git] / lib / ExecutionEngine / JITLink / JITLinkMemoryManager.cpp
blob267307cfde05cb0a9489a1f264a2c3bb2d53f9d7
1 //===--- JITLinkMemoryManager.cpp - JITLinkMemoryManager implementation ---===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
11 #include "llvm/Support/Process.h"
13 namespace llvm {
14 namespace jitlink {
16 JITLinkMemoryManager::~JITLinkMemoryManager() = default;
17 JITLinkMemoryManager::Allocation::~Allocation() = default;
19 Expected<std::unique_ptr<JITLinkMemoryManager::Allocation>>
20 InProcessMemoryManager::allocate(const SegmentsRequestMap &Request) {
22 using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
24 // Local class for allocation.
25 class IPMMAlloc : public Allocation {
26 public:
27 IPMMAlloc(AllocationMap SegBlocks) : SegBlocks(std::move(SegBlocks)) {}
28 MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
29 assert(SegBlocks.count(Seg) && "No allocation for segment");
30 return {static_cast<char *>(SegBlocks[Seg].base()),
31 SegBlocks[Seg].allocatedSize()};
33 JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
34 assert(SegBlocks.count(Seg) && "No allocation for segment");
35 return reinterpret_cast<JITTargetAddress>(SegBlocks[Seg].base());
37 void finalizeAsync(FinalizeContinuation OnFinalize) override {
38 OnFinalize(applyProtections());
40 Error deallocate() override {
41 for (auto &KV : SegBlocks)
42 if (auto EC = sys::Memory::releaseMappedMemory(KV.second))
43 return errorCodeToError(EC);
44 return Error::success();
47 private:
48 Error applyProtections() {
49 for (auto &KV : SegBlocks) {
50 auto &Prot = KV.first;
51 auto &Block = KV.second;
52 if (auto EC = sys::Memory::protectMappedMemory(Block, Prot))
53 return errorCodeToError(EC);
54 if (Prot & sys::Memory::MF_EXEC)
55 sys::Memory::InvalidateInstructionCache(Block.base(),
56 Block.allocatedSize());
58 return Error::success();
61 AllocationMap SegBlocks;
64 AllocationMap Blocks;
65 const sys::Memory::ProtectionFlags ReadWrite =
66 static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
67 sys::Memory::MF_WRITE);
69 for (auto &KV : Request) {
70 auto &Seg = KV.second;
72 if (Seg.getContentAlignment() > sys::Process::getPageSizeEstimate())
73 return make_error<StringError>("Cannot request higher than page "
74 "alignment",
75 inconvertibleErrorCode());
77 if (sys::Process::getPageSizeEstimate() % Seg.getContentAlignment() != 0)
78 return make_error<StringError>("Page size is not a multiple of "
79 "alignment",
80 inconvertibleErrorCode());
82 uint64_t ZeroFillStart =
83 alignTo(Seg.getContentSize(), Seg.getZeroFillAlignment());
84 uint64_t SegmentSize = ZeroFillStart + Seg.getZeroFillSize();
86 std::error_code EC;
87 auto SegMem =
88 sys::Memory::allocateMappedMemory(SegmentSize, nullptr, ReadWrite, EC);
90 if (EC)
91 return errorCodeToError(EC);
93 // Zero out the zero-fill memory.
94 memset(static_cast<char *>(SegMem.base()) + ZeroFillStart, 0,
95 Seg.getZeroFillSize());
97 // Record the block for this segment.
98 Blocks[KV.first] = std::move(SegMem);
100 return std::unique_ptr<InProcessMemoryManager::Allocation>(
101 new IPMMAlloc(std::move(Blocks)));
104 } // end namespace jitlink
105 } // end namespace llvm