14328ea34SLang Hames //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities 24328ea34SLang Hames //h-===// 38d76c711SLang Hames // 42946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 52946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 62946cd70SChandler 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 26809e9d1eSLang Hames return TSM.withModuleDo([&](Module &M) { 278d76c711SLang Hames SmallVector<char, 1> ClonedModuleBuffer; 288d76c711SLang Hames 298d76c711SLang Hames { 3098440293SLang Hames std::set<GlobalValue *> ClonedDefsInSrc; 318d76c711SLang Hames ValueToValueMapTy VMap; 32809e9d1eSLang Hames auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) { 338d76c711SLang Hames if (ShouldCloneDef(*GV)) { 3498440293SLang Hames ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV)); 358d76c711SLang Hames return true; 368d76c711SLang Hames } 378d76c711SLang Hames return false; 388d76c711SLang Hames }); 398d76c711SLang Hames 408d76c711SLang Hames if (UpdateClonedDefSource) 418d76c711SLang Hames for (auto *GV : ClonedDefsInSrc) 428d76c711SLang Hames UpdateClonedDefSource(*GV); 438d76c711SLang Hames 448d76c711SLang Hames BitcodeWriter BCWriter(ClonedModuleBuffer); 458d76c711SLang Hames 468d76c711SLang Hames BCWriter.writeModule(*Tmp); 478d76c711SLang Hames BCWriter.writeSymtab(); 488d76c711SLang Hames BCWriter.writeStrtab(); 498d76c711SLang Hames } 508d76c711SLang Hames 518d76c711SLang Hames MemoryBufferRef ClonedModuleBufferRef( 528d76c711SLang Hames StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), 538d76c711SLang Hames "cloned module buffer"); 54*0eaee545SJonas Devlieghere ThreadSafeContext NewTSCtx(std::make_unique<LLVMContext>()); 558d76c711SLang Hames 56809e9d1eSLang Hames auto ClonedModule = cantFail( 57809e9d1eSLang Hames parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext())); 58809e9d1eSLang Hames ClonedModule->setModuleIdentifier(M.getName()); 598d76c711SLang Hames return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx)); 60809e9d1eSLang Hames }); 618d76c711SLang Hames } 628d76c711SLang Hames 638d76c711SLang Hames } // end namespace orc 648d76c711SLang Hames } // end namespace llvm 65