ThreadSafeModule.cpp revision 360784
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
15namespace llvm {
16namespace orc {
17
18ThreadSafeModule cloneToNewContext(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