150
|
1 //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities
|
|
2 //h-===//
|
|
3 //
|
|
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
5 // See https://llvm.org/LICENSE.txt for license information.
|
|
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
7 //
|
|
8 //===----------------------------------------------------------------------===//
|
|
9
|
|
10 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
|
|
11 #include "llvm/Bitcode/BitcodeReader.h"
|
|
12 #include "llvm/Bitcode/BitcodeWriter.h"
|
|
13 #include "llvm/Transforms/Utils/Cloning.h"
|
|
14
|
|
15 namespace llvm {
|
|
16 namespace orc {
|
|
17
|
|
18 ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM,
|
|
19 GVPredicate ShouldCloneDef,
|
|
20 GVModifier UpdateClonedDefSource) {
|
|
21 assert(TSM && "Can not clone null module");
|
|
22
|
|
23 if (!ShouldCloneDef)
|
|
24 ShouldCloneDef = [](const GlobalValue &) { return true; };
|
|
25
|
|
26 return TSM.withModuleDo([&](Module &M) {
|
|
27 SmallVector<char, 1> ClonedModuleBuffer;
|
|
28
|
|
29 {
|
|
30 std::set<GlobalValue *> ClonedDefsInSrc;
|
|
31 ValueToValueMapTy VMap;
|
|
32 auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) {
|
|
33 if (ShouldCloneDef(*GV)) {
|
|
34 ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));
|
|
35 return true;
|
|
36 }
|
|
37 return false;
|
|
38 });
|
|
39
|
|
40 if (UpdateClonedDefSource)
|
|
41 for (auto *GV : ClonedDefsInSrc)
|
|
42 UpdateClonedDefSource(*GV);
|
|
43
|
|
44 BitcodeWriter BCWriter(ClonedModuleBuffer);
|
|
45
|
|
46 BCWriter.writeModule(*Tmp);
|
|
47 BCWriter.writeSymtab();
|
|
48 BCWriter.writeStrtab();
|
|
49 }
|
|
50
|
|
51 MemoryBufferRef ClonedModuleBufferRef(
|
|
52 StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()),
|
|
53 "cloned module buffer");
|
|
54 ThreadSafeContext NewTSCtx(std::make_unique<LLVMContext>());
|
|
55
|
|
56 auto ClonedModule = cantFail(
|
|
57 parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext()));
|
|
58 ClonedModule->setModuleIdentifier(M.getName());
|
|
59 return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx));
|
|
60 });
|
|
61 }
|
|
62
|
|
63 } // end namespace orc
|
|
64 } // end namespace llvm
|