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