1 //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities -===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 10 #include "llvm/Bitcode/BitcodeReader.h" 11 #include "llvm/Bitcode/BitcodeWriter.h" 12 #include "llvm/Transforms/Utils/Cloning.h" 13 14 namespace llvm { 15 namespace orc { 16 17 ThreadSafeModule cloneToContext(const ThreadSafeModule &TSM, 18 ThreadSafeContext TSCtx, 19 GVPredicate ShouldCloneDef, 20 GVModifier UpdateClonedDefSource) { 21 assert(TSM && "Can not clone null module"); 22 23 if (!ShouldCloneDef) 24 ShouldCloneDef = [](const GlobalValue &) { return true; }; 25 26 // First copy the source module into a buffer. 27 std::string ModuleName; 28 SmallVector<char, 1> ClonedModuleBuffer; 29 TSM.withModuleDo([&](Module &M) { 30 ModuleName = M.getModuleIdentifier(); 31 std::set<GlobalValue *> ClonedDefsInSrc; 32 ValueToValueMapTy VMap; 33 auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) { 34 if (ShouldCloneDef(*GV)) { 35 ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV)); 36 return true; 37 } 38 return false; 39 }); 40 41 if (UpdateClonedDefSource) 42 for (auto *GV : ClonedDefsInSrc) 43 UpdateClonedDefSource(*GV); 44 45 BitcodeWriter BCWriter(ClonedModuleBuffer); 46 BCWriter.writeModule(*Tmp); 47 BCWriter.writeSymtab(); 48 BCWriter.writeStrtab(); 49 }); 50 51 MemoryBufferRef ClonedModuleBufferRef( 52 StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), 53 "cloned module buffer"); 54 55 // Then parse the buffer into the new Module. 56 auto M = TSCtx.withContextDo([&](LLVMContext *Ctx) { 57 assert(Ctx && "No LLVMContext provided"); 58 auto TmpM = cantFail(parseBitcodeFile(ClonedModuleBufferRef, *Ctx)); 59 TmpM->setModuleIdentifier(ModuleName); 60 return TmpM; 61 }); 62 63 return ThreadSafeModule(std::move(M), std::move(TSCtx)); 64 } 65 66 ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSM, 67 GVPredicate ShouldCloneDef, 68 GVModifier UpdateClonedDefSource) { 69 assert(TSM && "Can not clone null module"); 70 71 ThreadSafeContext TSCtx(std::make_unique<LLVMContext>()); 72 return cloneToContext(TSM, std::move(TSCtx), std::move(ShouldCloneDef), 73 std::move(UpdateClonedDefSource)); 74 } 75 76 } // end namespace orc 77 } // end namespace llvm 78