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