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