14328ea34SLang Hames //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities
24328ea34SLang Hames //h-===//
38d76c711SLang Hames //
4*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
6*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
78d76c711SLang Hames //
88d76c711SLang Hames //===----------------------------------------------------------------------===//
98d76c711SLang Hames 
108d76c711SLang Hames #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
118d76c711SLang Hames #include "llvm/Bitcode/BitcodeReader.h"
128d76c711SLang Hames #include "llvm/Bitcode/BitcodeWriter.h"
138d76c711SLang Hames #include "llvm/Transforms/Utils/Cloning.h"
148d76c711SLang Hames 
158d76c711SLang Hames namespace llvm {
168d76c711SLang Hames namespace orc {
178d76c711SLang Hames 
188d76c711SLang Hames ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM,
198d76c711SLang Hames                                    GVPredicate ShouldCloneDef,
208d76c711SLang Hames                                    GVModifier UpdateClonedDefSource) {
218d76c711SLang Hames   assert(TSM && "Can not clone null module");
228d76c711SLang Hames 
238d76c711SLang Hames   if (!ShouldCloneDef)
248d76c711SLang Hames     ShouldCloneDef = [](const GlobalValue &) { return true; };
258d76c711SLang Hames 
268d76c711SLang Hames   auto Lock = TSM.getContextLock();
278d76c711SLang Hames 
288d76c711SLang Hames   SmallVector<char, 1> ClonedModuleBuffer;
298d76c711SLang Hames 
308d76c711SLang Hames   {
3198440293SLang Hames     std::set<GlobalValue *> ClonedDefsInSrc;
328d76c711SLang Hames     ValueToValueMapTy VMap;
334328ea34SLang Hames     auto Tmp = CloneModule(*TSM.getModule(), VMap, [&](const GlobalValue *GV) {
348d76c711SLang Hames       if (ShouldCloneDef(*GV)) {
3598440293SLang Hames         ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));
368d76c711SLang Hames         return true;
378d76c711SLang Hames       }
388d76c711SLang Hames       return false;
398d76c711SLang Hames     });
408d76c711SLang Hames 
418d76c711SLang Hames     if (UpdateClonedDefSource)
428d76c711SLang Hames       for (auto *GV : ClonedDefsInSrc)
438d76c711SLang Hames         UpdateClonedDefSource(*GV);
448d76c711SLang Hames 
458d76c711SLang Hames     BitcodeWriter BCWriter(ClonedModuleBuffer);
468d76c711SLang Hames 
478d76c711SLang Hames     BCWriter.writeModule(*Tmp);
488d76c711SLang Hames     BCWriter.writeSymtab();
498d76c711SLang Hames     BCWriter.writeStrtab();
508d76c711SLang Hames   }
518d76c711SLang Hames 
528d76c711SLang Hames   MemoryBufferRef ClonedModuleBufferRef(
538d76c711SLang Hames       StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()),
548d76c711SLang Hames       "cloned module buffer");
558d76c711SLang Hames   ThreadSafeContext NewTSCtx(llvm::make_unique<LLVMContext>());
568d76c711SLang Hames 
578d76c711SLang Hames   auto ClonedModule =
588d76c711SLang Hames       cantFail(parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext()));
598d76c711SLang Hames   ClonedModule->setModuleIdentifier(TSM.getModule()->getName());
608d76c711SLang Hames   return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx));
618d76c711SLang Hames }
628d76c711SLang Hames 
638d76c711SLang Hames } // end namespace orc
648d76c711SLang Hames } // end namespace llvm
65