xref: /llvm-project/llvm/lib/ExecutionEngine/Orc/ThreadSafeModule.cpp (revision f12db8cf750bb16515ba635143ca34b0c012968a)
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