1*4328ea34SLang Hames //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities
2*4328ea34SLang Hames //h-===//
38d76c711SLang Hames //
48d76c711SLang Hames //                     The LLVM Compiler Infrastructure
58d76c711SLang Hames //
68d76c711SLang Hames // This file is distributed under the University of Illinois Open Source
78d76c711SLang Hames // License. See LICENSE.TXT for details.
88d76c711SLang Hames //
98d76c711SLang Hames //===----------------------------------------------------------------------===//
108d76c711SLang Hames 
118d76c711SLang Hames #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
128d76c711SLang Hames #include "llvm/Bitcode/BitcodeReader.h"
138d76c711SLang Hames #include "llvm/Bitcode/BitcodeWriter.h"
148d76c711SLang Hames #include "llvm/Transforms/Utils/Cloning.h"
158d76c711SLang Hames 
168d76c711SLang Hames namespace llvm {
178d76c711SLang Hames namespace orc {
188d76c711SLang Hames 
198d76c711SLang Hames ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM,
208d76c711SLang Hames                                    GVPredicate ShouldCloneDef,
218d76c711SLang Hames                                    GVModifier UpdateClonedDefSource) {
228d76c711SLang Hames   assert(TSM && "Can not clone null module");
238d76c711SLang Hames 
248d76c711SLang Hames   if (!ShouldCloneDef)
258d76c711SLang Hames     ShouldCloneDef = [](const GlobalValue &) { return true; };
268d76c711SLang Hames 
278d76c711SLang Hames   auto Lock = TSM.getContextLock();
288d76c711SLang Hames 
298d76c711SLang Hames   SmallVector<char, 1> ClonedModuleBuffer;
308d76c711SLang Hames 
318d76c711SLang Hames   {
328d76c711SLang Hames     std::vector<GlobalValue *> ClonedDefsInSrc;
338d76c711SLang Hames     ValueToValueMapTy VMap;
34*4328ea34SLang Hames     auto Tmp = CloneModule(*TSM.getModule(), VMap, [&](const GlobalValue *GV) {
358d76c711SLang Hames       if (ShouldCloneDef(*GV)) {
368d76c711SLang Hames         ClonedDefsInSrc.push_back(const_cast<GlobalValue *>(GV));
378d76c711SLang Hames         return true;
388d76c711SLang Hames       }
398d76c711SLang Hames       return false;
408d76c711SLang Hames     });
418d76c711SLang Hames 
428d76c711SLang Hames     if (UpdateClonedDefSource)
438d76c711SLang Hames       for (auto *GV : ClonedDefsInSrc)
448d76c711SLang Hames         UpdateClonedDefSource(*GV);
458d76c711SLang Hames 
468d76c711SLang Hames     BitcodeWriter BCWriter(ClonedModuleBuffer);
478d76c711SLang Hames 
488d76c711SLang Hames     BCWriter.writeModule(*Tmp);
498d76c711SLang Hames     BCWriter.writeSymtab();
508d76c711SLang Hames     BCWriter.writeStrtab();
518d76c711SLang Hames   }
528d76c711SLang Hames 
538d76c711SLang Hames   MemoryBufferRef ClonedModuleBufferRef(
548d76c711SLang Hames       StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()),
558d76c711SLang Hames       "cloned module buffer");
568d76c711SLang Hames   ThreadSafeContext NewTSCtx(llvm::make_unique<LLVMContext>());
578d76c711SLang Hames 
588d76c711SLang Hames   auto ClonedModule =
598d76c711SLang Hames       cantFail(parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext()));
608d76c711SLang Hames   ClonedModule->setModuleIdentifier(TSM.getModule()->getName());
618d76c711SLang Hames   return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx));
628d76c711SLang Hames }
638d76c711SLang Hames 
648d76c711SLang Hames } // end namespace orc
658d76c711SLang Hames } // end namespace llvm
66