1*4328ea34SLang Hames //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities 2*4328ea34SLang Hames //h-===// 38d76c711SLang Hames // 48d76c711SLang Hames // The LLVM Compiler Infrastructure 58d76c711SLang Hames // 68d76c711SLang Hames // This file is distributed under the University of Illinois Open Source 78d76c711SLang Hames // License. See LICENSE.TXT for details. 88d76c711SLang Hames // 98d76c711SLang Hames //===----------------------------------------------------------------------===// 108d76c711SLang Hames 118d76c711SLang Hames #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 128d76c711SLang Hames #include "llvm/Bitcode/BitcodeReader.h" 138d76c711SLang Hames #include "llvm/Bitcode/BitcodeWriter.h" 148d76c711SLang Hames #include "llvm/Transforms/Utils/Cloning.h" 158d76c711SLang Hames 168d76c711SLang Hames namespace llvm { 178d76c711SLang Hames namespace orc { 188d76c711SLang Hames 198d76c711SLang Hames ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM, 208d76c711SLang Hames GVPredicate ShouldCloneDef, 218d76c711SLang Hames GVModifier UpdateClonedDefSource) { 228d76c711SLang Hames assert(TSM && "Can not clone null module"); 238d76c711SLang Hames 248d76c711SLang Hames if (!ShouldCloneDef) 258d76c711SLang Hames ShouldCloneDef = [](const GlobalValue &) { return true; }; 268d76c711SLang Hames 278d76c711SLang Hames auto Lock = TSM.getContextLock(); 288d76c711SLang Hames 298d76c711SLang Hames SmallVector<char, 1> ClonedModuleBuffer; 308d76c711SLang Hames 318d76c711SLang Hames { 328d76c711SLang Hames std::vector<GlobalValue *> ClonedDefsInSrc; 338d76c711SLang Hames ValueToValueMapTy VMap; 34*4328ea34SLang Hames auto Tmp = CloneModule(*TSM.getModule(), VMap, [&](const GlobalValue *GV) { 358d76c711SLang Hames if (ShouldCloneDef(*GV)) { 368d76c711SLang Hames ClonedDefsInSrc.push_back(const_cast<GlobalValue *>(GV)); 378d76c711SLang Hames return true; 388d76c711SLang Hames } 398d76c711SLang Hames return false; 408d76c711SLang Hames }); 418d76c711SLang Hames 428d76c711SLang Hames if (UpdateClonedDefSource) 438d76c711SLang Hames for (auto *GV : ClonedDefsInSrc) 448d76c711SLang Hames UpdateClonedDefSource(*GV); 458d76c711SLang Hames 468d76c711SLang Hames BitcodeWriter BCWriter(ClonedModuleBuffer); 478d76c711SLang Hames 488d76c711SLang Hames BCWriter.writeModule(*Tmp); 498d76c711SLang Hames BCWriter.writeSymtab(); 508d76c711SLang Hames BCWriter.writeStrtab(); 518d76c711SLang Hames } 528d76c711SLang Hames 538d76c711SLang Hames MemoryBufferRef ClonedModuleBufferRef( 548d76c711SLang Hames StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), 558d76c711SLang Hames "cloned module buffer"); 568d76c711SLang Hames ThreadSafeContext NewTSCtx(llvm::make_unique<LLVMContext>()); 578d76c711SLang Hames 588d76c711SLang Hames auto ClonedModule = 598d76c711SLang Hames cantFail(parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext())); 608d76c711SLang Hames ClonedModule->setModuleIdentifier(TSM.getModule()->getName()); 618d76c711SLang Hames return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx)); 628d76c711SLang Hames } 638d76c711SLang Hames 648d76c711SLang Hames } // end namespace orc 658d76c711SLang Hames } // end namespace llvm 66