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