//===- CompileOnDemandLayer.h - Compile each function on demand -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// JIT layer for breaking up modules and inserting callbacks to allow
// individual functions to be compiled on demand.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
#define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H

#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
#include "llvm/ExecutionEngine/Orc/Legacy.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/Orc/Speculation.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
#include <functional>
#include <iterator>
#include <list>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

namespace llvm {

class Value;

namespace orc {

class ExtractingIRMaterializationUnit;

class CompileOnDemandLayer : public IRLayer {
  friend class PartitioningIRMaterializationUnit;

public:
  /// Builder for IndirectStubsManagers.
  using IndirectStubsManagerBuilder =
      std::function<std::unique_ptr<IndirectStubsManager>()>;

  using GlobalValueSet = std::set<const GlobalValue *>;

  /// Partitioning function.
  using PartitionFunction =
      std::function<Optional<GlobalValueSet>(GlobalValueSet Requested)>;

  /// Off-the-shelf partitioning which compiles all requested symbols (usually
  /// a single function at a time).
  static Optional<GlobalValueSet> compileRequested(GlobalValueSet Requested);

  /// Off-the-shelf partitioning which compiles whole modules whenever any
  /// symbol in them is requested.
  static Optional<GlobalValueSet> compileWholeModule(GlobalValueSet Requested);

  /// Construct a CompileOnDemandLayer.
  CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer,
                        LazyCallThroughManager &LCTMgr,
                        IndirectStubsManagerBuilder BuildIndirectStubsManager);

  /// Sets the partition function.
  void setPartitionFunction(PartitionFunction Partition);

  /// Sets the ImplSymbolMap
  void setImplMap(ImplSymbolMap *Imp);
  /// Emits the given module. This should not be called by clients: it will be
  /// called by the JIT when a definition added via the add method is requested.
  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;

private:
  struct PerDylibResources {
  public:
    PerDylibResources(JITDylib &ImplD,
                      std::unique_ptr<IndirectStubsManager> ISMgr)
        : ImplD(ImplD), ISMgr(std::move(ISMgr)) {}
    JITDylib &getImplDylib() { return ImplD; }
    IndirectStubsManager &getISManager() { return *ISMgr; }

  private:
    JITDylib &ImplD;
    std::unique_ptr<IndirectStubsManager> ISMgr;
  };

  using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>;

  PerDylibResources &getPerDylibResources(JITDylib &TargetD);

  void cleanUpModule(Module &M);

  void expandPartition(GlobalValueSet &Partition);

  void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
                     IRMaterializationUnit::SymbolNameToDefinitionMap Defs);

  mutable std::mutex CODLayerMutex;

  IRLayer &BaseLayer;
  LazyCallThroughManager &LCTMgr;
  IndirectStubsManagerBuilder BuildIndirectStubsManager;
  PerDylibResourcesMap DylibResources;
  PartitionFunction Partition = compileRequested;
  SymbolLinkagePromoter PromoteSymbols;
  ImplSymbolMap *AliaseeImpls = nullptr;
};

/// Compile-on-demand layer.
///
///   When a module is added to this layer a stub is created for each of its
/// function definitions. The stubs and other global values are immediately
/// added to the layer below. When a stub is called it triggers the extraction
/// of the function body from the original module. The extracted body is then
/// compiled and executed.
template <typename BaseLayerT,
          typename CompileCallbackMgrT = JITCompileCallbackManager,
          typename IndirectStubsMgrT = IndirectStubsManager>
class LegacyCompileOnDemandLayer {
private:
  template <typename MaterializerFtor>
  class LambdaMaterializer final : public ValueMaterializer {
  public:
    LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}

    Value *materialize(Value *V) final { return M(V); }

  private:
    MaterializerFtor M;
  };

  template <typename MaterializerFtor>
  LambdaMaterializer<MaterializerFtor>
  createLambdaMaterializer(MaterializerFtor M) {
    return LambdaMaterializer<MaterializerFtor>(std::move(M));
  }

  // Provide type-erasure for the Modules and MemoryManagers.
  template <typename ResourceT>
  class ResourceOwner {
  public:
    ResourceOwner() = default;
    ResourceOwner(const ResourceOwner &) = delete;
    ResourceOwner &operator=(const ResourceOwner &) = delete;
    virtual ~ResourceOwner() = default;

    virtual ResourceT& getResource() const = 0;
  };

  template <typename ResourceT, typename ResourcePtrT>
  class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
  public:
    ResourceOwnerImpl(ResourcePtrT ResourcePtr)
      : ResourcePtr(std::move(ResourcePtr)) {}

    ResourceT& getResource() const override { return *ResourcePtr; }

  private:
    ResourcePtrT ResourcePtr;
  };

  template <typename ResourceT, typename ResourcePtrT>
  std::unique_ptr<ResourceOwner<ResourceT>>
  wrapOwnership(ResourcePtrT ResourcePtr) {
    using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
    return std::make_unique<RO>(std::move(ResourcePtr));
  }

  struct LogicalDylib {
    struct SourceModuleEntry {
      std::unique_ptr<Module> SourceMod;
      std::set<Function*> StubsToClone;
    };

    using SourceModulesList = std::vector<SourceModuleEntry>;
    using SourceModuleHandle = typename SourceModulesList::size_type;

    LogicalDylib() = default;

    LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
                 std::unique_ptr<IndirectStubsMgrT> StubsMgr)
        : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
          StubsMgr(std::move(StubsMgr)) {}

    SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
      SourceModuleHandle H = SourceModules.size();
      SourceModules.push_back(SourceModuleEntry());
      SourceModules.back().SourceMod = std::move(M);
      return H;
    }

    Module& getSourceModule(SourceModuleHandle H) {
      return *SourceModules[H].SourceMod;
    }

    std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
      return SourceModules[H].StubsToClone;
    }

    JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
                         bool ExportedSymbolsOnly) {
      if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
        return Sym;
      for (auto BLK : BaseLayerVModuleKeys)
        if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
          return Sym;
        else if (auto Err = Sym.takeError())
          return std::move(Err);
      return nullptr;
    }

    Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
      for (auto &BLK : BaseLayerVModuleKeys)
        if (auto Err = BaseLayer.removeModule(BLK))
          return Err;
      return Error::success();
    }

    VModuleKey K;
    std::shared_ptr<SymbolResolver> BackingResolver;
    std::unique_ptr<IndirectStubsMgrT> StubsMgr;
    SymbolLinkagePromoter PromoteSymbols;
    SourceModulesList SourceModules;
    std::vector<VModuleKey> BaseLayerVModuleKeys;
  };

public:

  /// Module partitioning functor.
  using PartitioningFtor = std::function<std::set<Function*>(Function&)>;

  /// Builder for IndirectStubsManagers.
  using IndirectStubsManagerBuilderT =
      std::function<std::unique_ptr<IndirectStubsMgrT>()>;

  using SymbolResolverGetter =
      std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;

  using SymbolResolverSetter =
      std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;

  /// Construct a compile-on-demand layer instance.
  LLVM_ATTRIBUTE_DEPRECATED(
      LegacyCompileOnDemandLayer(
          ExecutionSession &ES, BaseLayerT &BaseLayer,
          SymbolResolverGetter GetSymbolResolver,
          SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition,
          CompileCallbackMgrT &CallbackMgr,
          IndirectStubsManagerBuilderT CreateIndirectStubsManager,
          bool CloneStubsIntoPartitions = true),
      "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
      "use "
      "the ORCv2 LegacyCompileOnDemandLayer instead");

  /// Legacy layer constructor with deprecation acknowledgement.
  LegacyCompileOnDemandLayer(
      ORCv1DeprecationAcknowledgement, ExecutionSession &ES,
      BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver,
      SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition,
      CompileCallbackMgrT &CallbackMgr,
      IndirectStubsManagerBuilderT CreateIndirectStubsManager,
      bool CloneStubsIntoPartitions = true)
      : ES(ES), BaseLayer(BaseLayer),
        GetSymbolResolver(std::move(GetSymbolResolver)),
        SetSymbolResolver(std::move(SetSymbolResolver)),
        Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
        CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
        CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}

  ~LegacyCompileOnDemandLayer() {
    // FIXME: Report error on log.
    while (!LogicalDylibs.empty())
      consumeError(removeModule(LogicalDylibs.begin()->first));
  }

  /// Add a module to the compile-on-demand layer.
  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {

    assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
    auto I = LogicalDylibs.insert(
        LogicalDylibs.end(),
        std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
                                       CreateIndirectStubsManager())));

    return addLogicalModule(I->second, std::move(M));
  }

  /// Add extra modules to an existing logical module.
  Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
    return addLogicalModule(LogicalDylibs[K], std::move(M));
  }

  /// Remove the module represented by the given key.
  ///
  ///   This will remove all modules in the layers below that were derived from
  /// the module represented by K.
  Error removeModule(VModuleKey K) {
    auto I = LogicalDylibs.find(K);
    assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
    auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
    LogicalDylibs.erase(I);
    return Err;
  }

  /// Search for the given named symbol.
  /// @param Name The name of the symbol to search for.
  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
  /// @return A handle for the given named symbol, if it exists.
  JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
    for (auto &KV : LogicalDylibs) {
      if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
        return Sym;
      if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
        return Sym;
      else if (auto Err = Sym.takeError())
        return std::move(Err);
    }
    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
  }

  /// Get the address of a symbol provided by this layer, or some layer
  ///        below this one.
  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
                         bool ExportedSymbolsOnly) {
    assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
    return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
  }

  /// Update the stub for the given function to point at FnBodyAddr.
  /// This can be used to support re-optimization.
  /// @return true if the function exists and the stub is updated, false
  ///         otherwise.
  //
  // FIXME: We should track and free associated resources (unused compile
  //        callbacks, uncompiled IR, and no-longer-needed/reachable function
  //        implementations).
  Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
    //Find out which logical dylib contains our symbol
    auto LDI = LogicalDylibs.begin();
    for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
      if (auto LMResources =
            LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
        Module &SrcM = LMResources->SourceModule->getResource();
        std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
        if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
                                                            FnBodyAddr))
          return Err;
        return Error::success();
      }
    }
    return make_error<JITSymbolNotFound>(FuncName);
  }

private:
  Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {

    // Rename anonymous globals and promote linkage to ensure that everything
    // will resolve properly after we partition SrcM.
    LD.PromoteSymbols(*SrcMPtr);

    // Create a logical module handle for SrcM within the logical dylib.
    Module &SrcM = *SrcMPtr;
    auto LMId = LD.addSourceModule(std::move(SrcMPtr));

    // Create stub functions.
    const DataLayout &DL = SrcM.getDataLayout();
    {
      typename IndirectStubsMgrT::StubInitsMap StubInits;
      for (auto &F : SrcM) {
        // Skip declarations.
        if (F.isDeclaration())
          continue;

        // Skip weak functions for which we already have definitions.
        auto MangledName = mangle(F.getName(), DL);
        if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
          if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
            continue;
          else if (auto Err = Sym.takeError())
            return std::move(Err);
        }

        // Record all functions defined by this module.
        if (CloneStubsIntoPartitions)
          LD.getStubsToClone(LMId).insert(&F);

        // Create a callback, associate it with the stub for the function,
        // and set the compile action to compile the partition containing the
        // function.
        auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
          if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
            return *FnImplAddrOrErr;
          else {
            // FIXME: Report error, return to 'abort' or something similar.
            consumeError(FnImplAddrOrErr.takeError());
            return 0;
          }
        };
        if (auto CCAddr =
                CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
          StubInits[MangledName] =
              std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
        else
          return CCAddr.takeError();
      }

      if (auto Err = LD.StubsMgr->createStubs(StubInits))
        return Err;
    }

    // If this module doesn't contain any globals, aliases, or module flags then
    // we can bail out early and avoid the overhead of creating and managing an
    // empty globals module.
    if (SrcM.global_empty() && SrcM.alias_empty() &&
        !SrcM.getModuleFlagsMetadata())
      return Error::success();

    // Create the GlobalValues module.
    auto GVsM = std::make_unique<Module>((SrcM.getName() + ".globals").str(),
                                          SrcM.getContext());
    GVsM->setDataLayout(DL);

    ValueToValueMapTy VMap;

    // Clone global variable decls.
    for (auto &GV : SrcM.globals())
      if (!GV.isDeclaration() && !VMap.count(&GV))
        cloneGlobalVariableDecl(*GVsM, GV, &VMap);

    // And the aliases.
    for (auto &A : SrcM.aliases())
      if (!VMap.count(&A))
        cloneGlobalAliasDecl(*GVsM, A, VMap);

    // Clone the module flags.
    cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);

    // Now we need to clone the GV and alias initializers.

    // Initializers may refer to functions declared (but not defined) in this
    // module. Build a materializer to clone decls on demand.
    auto Materializer = createLambdaMaterializer(
      [&LD, &GVsM](Value *V) -> Value* {
        if (auto *F = dyn_cast<Function>(V)) {
          // Decls in the original module just get cloned.
          if (F->isDeclaration())
            return cloneFunctionDecl(*GVsM, *F);

          // Definitions in the original module (which we have emitted stubs
          // for at this point) get turned into a constant alias to the stub
          // instead.
          const DataLayout &DL = GVsM->getDataLayout();
          std::string FName = mangle(F->getName(), DL);
          unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
          JITTargetAddress StubAddr =
            LD.StubsMgr->findStub(FName, false).getAddress();

          ConstantInt *StubAddrCI =
            ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
          Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
                                                 StubAddrCI, F->getType());
          return GlobalAlias::create(F->getFunctionType(),
                                     F->getType()->getAddressSpace(),
                                     F->getLinkage(), F->getName(),
                                     Init, GVsM.get());
        }
        // else....
        return nullptr;
      });

    // Clone the global variable initializers.
    for (auto &GV : SrcM.globals())
      if (!GV.isDeclaration())
        moveGlobalVariableInitializer(GV, VMap, &Materializer);

    // Clone the global alias initializers.
    for (auto &A : SrcM.aliases()) {
      auto *NewA = cast<GlobalAlias>(VMap[&A]);
      assert(NewA && "Alias not cloned?");
      Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
                             &Materializer);
      NewA->setAliasee(cast<Constant>(Init));
    }

    // Build a resolver for the globals module and add it to the base layer.
    auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
      if (auto Sym = LD.StubsMgr->findStub(Name, false))
        return Sym;

      if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
        return Sym;
      else if (auto Err = Sym.takeError())
        return std::move(Err);

      return nullptr;
    };

    auto GVsResolver = createSymbolResolver(
        [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
          auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);

          if (!RS) {
            logAllUnhandledErrors(
                RS.takeError(), errs(),
                "CODLayer/GVsResolver responsibility set lookup failed: ");
            return SymbolNameSet();
          }

          if (RS->size() == Symbols.size())
            return *RS;

          SymbolNameSet NotFoundViaLegacyLookup;
          for (auto &S : Symbols)
            if (!RS->count(S))
              NotFoundViaLegacyLookup.insert(S);
          auto RS2 =
              LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);

          for (auto &S : RS2)
            (*RS).insert(S);

          return *RS;
        },
        [this, &LD,
         LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
                       SymbolNameSet Symbols) {
          auto NotFoundViaLegacyLookup =
              lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
          return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
        });

    SetSymbolResolver(LD.K, std::move(GVsResolver));

    if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
      return Err;

    LD.BaseLayerVModuleKeys.push_back(LD.K);

    return Error::success();
  }

  static std::string mangle(StringRef Name, const DataLayout &DL) {
    std::string MangledName;
    {
      raw_string_ostream MangledNameStream(MangledName);
      Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
    }
    return MangledName;
  }

  Expected<JITTargetAddress>
  extractAndCompile(LogicalDylib &LD,
                    typename LogicalDylib::SourceModuleHandle LMId,
                    Function &F) {
    Module &SrcM = LD.getSourceModule(LMId);

    // If F is a declaration we must already have compiled it.
    if (F.isDeclaration())
      return 0;

    // Grab the name of the function being called here.
    std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());

    JITTargetAddress CalledAddr = 0;
    auto Part = Partition(F);
    if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
      auto &PartKey = *PartKeyOrErr;
      for (auto *SubF : Part) {
        std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
        if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
          if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
            JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;

            // If this is the function we're calling record the address so we can
            // return it from this function.
            if (SubF == &F)
              CalledAddr = FnBodyAddr;

            // Update the function body pointer for the stub.
            if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
              return 0;

          } else
            return FnBodyAddrOrErr.takeError();
        } else if (auto Err = FnBodySym.takeError())
          return std::move(Err);
        else
          llvm_unreachable("Function not emitted for partition");
      }

      LD.BaseLayerVModuleKeys.push_back(PartKey);
    } else
      return PartKeyOrErr.takeError();

    return CalledAddr;
  }

  template <typename PartitionT>
  Expected<VModuleKey>
  emitPartition(LogicalDylib &LD,
                typename LogicalDylib::SourceModuleHandle LMId,
                const PartitionT &Part) {
    Module &SrcM = LD.getSourceModule(LMId);

    // Create the module.
    std::string NewName = SrcM.getName();
    for (auto *F : Part) {
      NewName += ".";
      NewName += F->getName();
    }

    auto M = std::make_unique<Module>(NewName, SrcM.getContext());
    M->setDataLayout(SrcM.getDataLayout());
    ValueToValueMapTy VMap;

    auto Materializer = createLambdaMaterializer([&LD, &LMId,
                                                  &M](Value *V) -> Value * {
      if (auto *GV = dyn_cast<GlobalVariable>(V))
        return cloneGlobalVariableDecl(*M, *GV);

      if (auto *F = dyn_cast<Function>(V)) {
        // Check whether we want to clone an available_externally definition.
        if (!LD.getStubsToClone(LMId).count(F))
          return cloneFunctionDecl(*M, *F);

        // Ok - we want an inlinable stub. For that to work we need a decl
        // for the stub pointer.
        auto *StubPtr = createImplPointer(*F->getType(), *M,
                                          F->getName() + "$stub_ptr", nullptr);
        auto *ClonedF = cloneFunctionDecl(*M, *F);
        makeStub(*ClonedF, *StubPtr);
        ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
        ClonedF->addFnAttr(Attribute::AlwaysInline);
        return ClonedF;
      }

      if (auto *A = dyn_cast<GlobalAlias>(V)) {
        auto *Ty = A->getValueType();
        if (Ty->isFunctionTy())
          return Function::Create(cast<FunctionType>(Ty),
                                  GlobalValue::ExternalLinkage, A->getName(),
                                  M.get());

        return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
                                  nullptr, A->getName(), nullptr,
                                  GlobalValue::NotThreadLocal,
                                  A->getType()->getAddressSpace());
      }

      return nullptr;
    });

    // Create decls in the new module.
    for (auto *F : Part)
      cloneFunctionDecl(*M, *F, &VMap);

    // Move the function bodies.
    for (auto *F : Part)
      moveFunctionBody(*F, VMap, &Materializer);

    auto K = ES.allocateVModule();

    auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
      return LD.findSymbol(BaseLayer, Name, false);
    };

    // Create memory manager and symbol resolver.
    auto Resolver = createSymbolResolver(
        [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
          auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
          if (!RS) {
            logAllUnhandledErrors(
                RS.takeError(), errs(),
                "CODLayer/SubResolver responsibility set lookup failed: ");
            return SymbolNameSet();
          }

          if (RS->size() == Symbols.size())
            return *RS;

          SymbolNameSet NotFoundViaLegacyLookup;
          for (auto &S : Symbols)
            if (!RS->count(S))
              NotFoundViaLegacyLookup.insert(S);

          auto RS2 =
              LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);

          for (auto &S : RS2)
            (*RS).insert(S);

          return *RS;
        },
        [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
                                  SymbolNameSet Symbols) {
          auto NotFoundViaLegacyLookup =
              lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
          return LD.BackingResolver->lookup(Q,
                                            std::move(NotFoundViaLegacyLookup));
        });
    SetSymbolResolver(K, std::move(Resolver));

    if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
      return std::move(Err);

    return K;
  }

  ExecutionSession &ES;
  BaseLayerT &BaseLayer;
  SymbolResolverGetter GetSymbolResolver;
  SymbolResolverSetter SetSymbolResolver;
  PartitioningFtor Partition;
  CompileCallbackMgrT &CompileCallbackMgr;
  IndirectStubsManagerBuilderT CreateIndirectStubsManager;

  std::map<VModuleKey, LogicalDylib> LogicalDylibs;
  bool CloneStubsIntoPartitions;
};

template <typename BaseLayerT, typename CompileCallbackMgrT,
          typename IndirectStubsMgrT>
LegacyCompileOnDemandLayer<BaseLayerT, CompileCallbackMgrT, IndirectStubsMgrT>::
    LegacyCompileOnDemandLayer(
        ExecutionSession &ES, BaseLayerT &BaseLayer,
        SymbolResolverGetter GetSymbolResolver,
        SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition,
        CompileCallbackMgrT &CallbackMgr,
        IndirectStubsManagerBuilderT CreateIndirectStubsManager,
        bool CloneStubsIntoPartitions)
    : ES(ES), BaseLayer(BaseLayer),
      GetSymbolResolver(std::move(GetSymbolResolver)),
      SetSymbolResolver(std::move(SetSymbolResolver)),
      Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
      CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
      CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}

} // end namespace orc
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
