Home | History | Annotate | Line # | Download | only in Orc
      1 //===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities
      2 //h-===//
      3 //
      4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      5 // See https://llvm.org/LICENSE.txt for license information.
      6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
     11 #include "llvm/Bitcode/BitcodeReader.h"
     12 #include "llvm/Bitcode/BitcodeWriter.h"
     13 #include "llvm/Transforms/Utils/Cloning.h"
     14 
     15 namespace llvm {
     16 namespace orc {
     17 
     18 ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSM,
     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   return TSM.withModuleDo([&](Module &M) {
     27     SmallVector<char, 1> ClonedModuleBuffer;
     28 
     29     {
     30       std::set<GlobalValue *> ClonedDefsInSrc;
     31       ValueToValueMapTy VMap;
     32       auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) {
     33         if (ShouldCloneDef(*GV)) {
     34           ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));
     35           return true;
     36         }
     37         return false;
     38       });
     39 
     40       if (UpdateClonedDefSource)
     41         for (auto *GV : ClonedDefsInSrc)
     42           UpdateClonedDefSource(*GV);
     43 
     44       BitcodeWriter BCWriter(ClonedModuleBuffer);
     45 
     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     ThreadSafeContext NewTSCtx(std::make_unique<LLVMContext>());
     55 
     56     auto ClonedModule = cantFail(
     57         parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext()));
     58     ClonedModule->setModuleIdentifier(M.getName());
     59     return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx));
     60   });
     61 }
     62 
     63 } // end namespace orc
     64 } // end namespace llvm
     65