10b57cec5SDimitry Andric //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities 20b57cec5SDimitry Andric //h-===// 30b57cec5SDimitry Andric // 40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 110b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h" 120b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h" 130b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric namespace llvm { 160b57cec5SDimitry Andric namespace orc { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM, 190b57cec5SDimitry Andric GVPredicate ShouldCloneDef, 200b57cec5SDimitry Andric GVModifier UpdateClonedDefSource) { 210b57cec5SDimitry Andric assert(TSM && "Can not clone null module"); 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric if (!ShouldCloneDef) 240b57cec5SDimitry Andric ShouldCloneDef = [](const GlobalValue &) { return true; }; 250b57cec5SDimitry Andric 26*8bcb0991SDimitry Andric return TSM.withModuleDo([&](Module &M) { 270b57cec5SDimitry Andric SmallVector<char, 1> ClonedModuleBuffer; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric { 300b57cec5SDimitry Andric std::set<GlobalValue *> ClonedDefsInSrc; 310b57cec5SDimitry Andric ValueToValueMapTy VMap; 32*8bcb0991SDimitry Andric auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) { 330b57cec5SDimitry Andric if (ShouldCloneDef(*GV)) { 340b57cec5SDimitry Andric ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV)); 350b57cec5SDimitry Andric return true; 360b57cec5SDimitry Andric } 370b57cec5SDimitry Andric return false; 380b57cec5SDimitry Andric }); 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric if (UpdateClonedDefSource) 410b57cec5SDimitry Andric for (auto *GV : ClonedDefsInSrc) 420b57cec5SDimitry Andric UpdateClonedDefSource(*GV); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric BitcodeWriter BCWriter(ClonedModuleBuffer); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric BCWriter.writeModule(*Tmp); 470b57cec5SDimitry Andric BCWriter.writeSymtab(); 480b57cec5SDimitry Andric BCWriter.writeStrtab(); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric MemoryBufferRef ClonedModuleBufferRef( 520b57cec5SDimitry Andric StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), 530b57cec5SDimitry Andric "cloned module buffer"); 54*8bcb0991SDimitry Andric ThreadSafeContext NewTSCtx(std::make_unique<LLVMContext>()); 550b57cec5SDimitry Andric 56*8bcb0991SDimitry Andric auto ClonedModule = cantFail( 57*8bcb0991SDimitry Andric parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext())); 58*8bcb0991SDimitry Andric ClonedModule->setModuleIdentifier(M.getName()); 590b57cec5SDimitry Andric return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx)); 60*8bcb0991SDimitry Andric }); 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric } // end namespace orc 640b57cec5SDimitry Andric } // end namespace llvm 65