brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · d460cf6 Raw
111 lines · cpp
1//===-- ThreadSafeModule.cpp - Thread safe Module, Context, and Utilities -===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"10#include "llvm/Bitcode/BitcodeReader.h"11#include "llvm/Bitcode/BitcodeWriter.h"12#include "llvm/Transforms/Utils/Cloning.h"13 14namespace llvm {15namespace orc {16 17static std::pair<std::string, SmallVector<char, 1>>18serializeModule(const Module &M, GVPredicate ShouldCloneDef,19                GVModifier UpdateClonedDefSource) {20  std::string ModuleName;21  SmallVector<char, 1> ClonedModuleBuffer;22 23  ModuleName = M.getModuleIdentifier();24  std::set<GlobalValue *> ClonedDefsInSrc;25  ValueToValueMapTy VMap;26  auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) {27    if (ShouldCloneDef(*GV)) {28      ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));29      return true;30    }31    return false;32  });33 34  if (UpdateClonedDefSource)35    for (auto *GV : ClonedDefsInSrc)36      UpdateClonedDefSource(*GV);37 38  BitcodeWriter BCWriter(ClonedModuleBuffer);39  BCWriter.writeModule(*Tmp);40  BCWriter.writeSymtab();41  BCWriter.writeStrtab();42 43  return {std::move(ModuleName), std::move(ClonedModuleBuffer)};44}45 46ThreadSafeModule47deserializeModule(std::string ModuleName,48                  const SmallVector<char, 1> &ClonedModuleBuffer,49                  ThreadSafeContext TSCtx) {50  MemoryBufferRef ClonedModuleBufferRef(51      StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()),52      "cloned module buffer");53 54  // Then parse the buffer into the new Module.55  auto M = TSCtx.withContextDo([&](LLVMContext *Ctx) {56    assert(Ctx && "No LLVMContext provided");57    auto TmpM = cantFail(parseBitcodeFile(ClonedModuleBufferRef, *Ctx));58    TmpM->setModuleIdentifier(ModuleName);59    return TmpM;60  });61 62  return ThreadSafeModule(std::move(M), std::move(TSCtx));63}64 65ThreadSafeModule66cloneExternalModuleToContext(const Module &M, ThreadSafeContext TSCtx,67                             GVPredicate ShouldCloneDef,68                             GVModifier UpdateClonedDefSource) {69 70  if (!ShouldCloneDef)71    ShouldCloneDef = [](const GlobalValue &) { return true; };72 73  auto [ModuleName, ClonedModuleBuffer] = serializeModule(74      M, std::move(ShouldCloneDef), std::move(UpdateClonedDefSource));75 76  return deserializeModule(std::move(ModuleName), ClonedModuleBuffer,77                           std::move(TSCtx));78}79 80ThreadSafeModule cloneToContext(const ThreadSafeModule &TSM,81                                ThreadSafeContext TSCtx,82                                GVPredicate ShouldCloneDef,83                                GVModifier UpdateClonedDefSource) {84  assert(TSM && "Can not clone null module");85 86  if (!ShouldCloneDef)87    ShouldCloneDef = [](const GlobalValue &) { return true; };88 89  // First copy the source module into a buffer.90  auto [ModuleName, ClonedModuleBuffer] = TSM.withModuleDo([&](Module &M) {91    return serializeModule(M, std::move(ShouldCloneDef),92                           std::move(UpdateClonedDefSource));93  });94 95  return deserializeModule(std::move(ModuleName), ClonedModuleBuffer,96                           std::move(TSCtx));97}98 99ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSM,100                                   GVPredicate ShouldCloneDef,101                                   GVModifier UpdateClonedDefSource) {102  assert(TSM && "Can not clone null module");103 104  ThreadSafeContext TSCtx(std::make_unique<LLVMContext>());105  return cloneToContext(TSM, std::move(TSCtx), std::move(ShouldCloneDef),106                        std::move(UpdateClonedDefSource));107}108 109} // end namespace orc110} // end namespace llvm111