14328ea34SLang Hames //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities
24328ea34SLang Hames //h-===//
38d76c711SLang Hames //
42946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
52946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
62946cd70SChandler 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
cloneToNewContext(const ThreadSafeModule & TSM,GVPredicate ShouldCloneDef,GVModifier UpdateClonedDefSource)18*f12db8cfSStefan Gränitz ThreadSafeModule cloneToNewContext(const 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
26809e9d1eSLang Hames return TSM.withModuleDo([&](Module &M) {
278d76c711SLang Hames SmallVector<char, 1> ClonedModuleBuffer;
288d76c711SLang Hames
298d76c711SLang Hames {
3098440293SLang Hames std::set<GlobalValue *> ClonedDefsInSrc;
318d76c711SLang Hames ValueToValueMapTy VMap;
32809e9d1eSLang Hames auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) {
338d76c711SLang Hames if (ShouldCloneDef(*GV)) {
3498440293SLang Hames ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));
358d76c711SLang Hames return true;
368d76c711SLang Hames }
378d76c711SLang Hames return false;
388d76c711SLang Hames });
398d76c711SLang Hames
408d76c711SLang Hames if (UpdateClonedDefSource)
418d76c711SLang Hames for (auto *GV : ClonedDefsInSrc)
428d76c711SLang Hames UpdateClonedDefSource(*GV);
438d76c711SLang Hames
448d76c711SLang Hames BitcodeWriter BCWriter(ClonedModuleBuffer);
458d76c711SLang Hames
468d76c711SLang Hames BCWriter.writeModule(*Tmp);
478d76c711SLang Hames BCWriter.writeSymtab();
488d76c711SLang Hames BCWriter.writeStrtab();
498d76c711SLang Hames }
508d76c711SLang Hames
518d76c711SLang Hames MemoryBufferRef ClonedModuleBufferRef(
528d76c711SLang Hames StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()),
538d76c711SLang Hames "cloned module buffer");
540eaee545SJonas Devlieghere ThreadSafeContext NewTSCtx(std::make_unique<LLVMContext>());
558d76c711SLang Hames
56809e9d1eSLang Hames auto ClonedModule = cantFail(
57809e9d1eSLang Hames parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext()));
58809e9d1eSLang Hames ClonedModule->setModuleIdentifier(M.getName());
598d76c711SLang Hames return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx));
60809e9d1eSLang Hames });
618d76c711SLang Hames }
628d76c711SLang Hames
638d76c711SLang Hames } // end namespace orc
648d76c711SLang Hames } // end namespace llvm
65