blob: 9525b168fbd3fd706313d35d41c1728f1e3209d3 [file] [log] [blame]
Lang Hames4328ea32018-09-28 01:41:33 +00001//===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities
2//h-===//
Lang Hames8d76c712018-09-26 01:24:12 +00003//
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
16namespace llvm {
17namespace orc {
18
19ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM,
20 GVPredicate ShouldCloneDef,
21 GVModifier UpdateClonedDefSource) {
22 assert(TSM && "Can not clone null module");
23
24 if (!ShouldCloneDef)
Lang Hames4328ea32018-09-28 01:41:33 +000025 ShouldCloneDef = [](const GlobalValue &) { return true; };
Lang Hames8d76c712018-09-26 01:24:12 +000026
27 auto Lock = TSM.getContextLock();
28
29 SmallVector<char, 1> ClonedModuleBuffer;
30
31 {
Lang Hames98440292018-09-29 23:49:57 +000032 std::set<GlobalValue *> ClonedDefsInSrc;
Lang Hames8d76c712018-09-26 01:24:12 +000033 ValueToValueMapTy VMap;
Lang Hames4328ea32018-09-28 01:41:33 +000034 auto Tmp = CloneModule(*TSM.getModule(), VMap, [&](const GlobalValue *GV) {
Lang Hames8d76c712018-09-26 01:24:12 +000035 if (ShouldCloneDef(*GV)) {
Lang Hames98440292018-09-29 23:49:57 +000036 ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));
Lang Hames8d76c712018-09-26 01:24:12 +000037 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