1*8d76c711SLang Hames //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities h-===// 2*8d76c711SLang Hames // 3*8d76c711SLang Hames // The LLVM Compiler Infrastructure 4*8d76c711SLang Hames // 5*8d76c711SLang Hames // This file is distributed under the University of Illinois Open Source 6*8d76c711SLang Hames // License. See LICENSE.TXT for details. 7*8d76c711SLang Hames // 8*8d76c711SLang Hames //===----------------------------------------------------------------------===// 9*8d76c711SLang Hames 10*8d76c711SLang Hames #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 11*8d76c711SLang Hames #include "llvm/Bitcode/BitcodeReader.h" 12*8d76c711SLang Hames #include "llvm/Bitcode/BitcodeWriter.h" 13*8d76c711SLang Hames #include "llvm/Transforms/Utils/Cloning.h" 14*8d76c711SLang Hames 15*8d76c711SLang Hames namespace llvm { 16*8d76c711SLang Hames namespace orc { 17*8d76c711SLang Hames 18*8d76c711SLang Hames ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM, 19*8d76c711SLang Hames GVPredicate ShouldCloneDef, 20*8d76c711SLang Hames GVModifier UpdateClonedDefSource) { 21*8d76c711SLang Hames assert(TSM && "Can not clone null module"); 22*8d76c711SLang Hames 23*8d76c711SLang Hames if (!ShouldCloneDef) 24*8d76c711SLang Hames ShouldCloneDef = [](const GlobalValue&) { return true; }; 25*8d76c711SLang Hames 26*8d76c711SLang Hames auto Lock = TSM.getContextLock(); 27*8d76c711SLang Hames 28*8d76c711SLang Hames SmallVector<char, 1> ClonedModuleBuffer; 29*8d76c711SLang Hames 30*8d76c711SLang Hames { 31*8d76c711SLang Hames std::vector<GlobalValue *> ClonedDefsInSrc; 32*8d76c711SLang Hames ValueToValueMapTy VMap; 33*8d76c711SLang Hames auto Tmp = CloneModule(*TSM.getModule(), VMap, 34*8d76c711SLang Hames [&](const GlobalValue *GV) { 35*8d76c711SLang Hames if (ShouldCloneDef(*GV)) { 36*8d76c711SLang Hames ClonedDefsInSrc.push_back(const_cast<GlobalValue *>(GV)); 37*8d76c711SLang Hames return true; 38*8d76c711SLang Hames } 39*8d76c711SLang Hames return false; 40*8d76c711SLang Hames }); 41*8d76c711SLang Hames 42*8d76c711SLang Hames if (UpdateClonedDefSource) 43*8d76c711SLang Hames for (auto *GV : ClonedDefsInSrc) 44*8d76c711SLang Hames UpdateClonedDefSource(*GV); 45*8d76c711SLang Hames 46*8d76c711SLang Hames BitcodeWriter BCWriter(ClonedModuleBuffer); 47*8d76c711SLang Hames 48*8d76c711SLang Hames BCWriter.writeModule(*Tmp); 49*8d76c711SLang Hames BCWriter.writeSymtab(); 50*8d76c711SLang Hames BCWriter.writeStrtab(); 51*8d76c711SLang Hames } 52*8d76c711SLang Hames 53*8d76c711SLang Hames MemoryBufferRef ClonedModuleBufferRef( 54*8d76c711SLang Hames StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), 55*8d76c711SLang Hames "cloned module buffer"); 56*8d76c711SLang Hames ThreadSafeContext NewTSCtx(llvm::make_unique<LLVMContext>()); 57*8d76c711SLang Hames 58*8d76c711SLang Hames auto ClonedModule = 59*8d76c711SLang Hames cantFail(parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext())); 60*8d76c711SLang Hames ClonedModule->setModuleIdentifier(TSM.getModule()->getName()); 61*8d76c711SLang Hames return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx)); 62*8d76c711SLang Hames } 63*8d76c711SLang Hames 64*8d76c711SLang Hames } // end namespace orc 65*8d76c711SLang Hames } // end namespace llvm 66