//===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Contains the definition for a basic, eagerly compiling layer of the JIT.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H

#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Object/ObjectFile.h"
#include <memory>

namespace llvm {
namespace orc {

/// @brief Eager IR compiling layer.
///
///   This layer accepts sets of LLVM IR Modules (via addModuleSet). It
/// immediately compiles each IR module to an object file (each IR Module is
/// compiled separately). The resulting set of object files is then added to
/// the layer below, which must implement the object layer concept.
template <typename BaseLayerT> class IRCompileLayer {
public:
  typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
      CompileFtor;

private:
  typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;

public:
  /// @brief Handle to a set of compiled modules.
  typedef ObjSetHandleT ModuleSetHandleT;

  /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
  ///        implement the ObjectLayer concept.
  IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
      : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}

  /// @brief Set an ObjectCache to query before compiling.
  void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }

  /// @brief Compile each module in the given module set, then add the resulting
  ///        set of objects to the base layer along with the memory manager and
  ///        symbol resolver.
  ///
  /// @return A handle for the added modules.
  template <typename ModuleSetT, typename MemoryManagerPtrT,
            typename SymbolResolverPtrT>
  ModuleSetHandleT addModuleSet(ModuleSetT Ms,
                                MemoryManagerPtrT MemMgr,
                                SymbolResolverPtrT Resolver) {
    std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>>
      Objects;

    for (const auto &M : Ms) {
      auto Object =
        llvm::make_unique<object::OwningBinary<object::ObjectFile>>();

      if (ObjCache)
        *Object = tryToLoadFromObjectCache(*M);

      if (!Object->getBinary()) {
        *Object = Compile(*M);
        if (ObjCache)
          ObjCache->notifyObjectCompiled(&*M,
                                     Object->getBinary()->getMemoryBufferRef());
      }

      Objects.push_back(std::move(Object));
    }

    ModuleSetHandleT H =
      BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr),
                             std::move(Resolver));

    return H;
  }

  /// @brief Remove the module set associated with the handle H.
  void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }

  /// @brief 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(const std::string &Name, bool ExportedSymbolsOnly) {
    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
  }

  /// @brief Get the address of the given symbol in the context of the set of
  ///        compiled modules represented by the handle H. This call is
  ///        forwarded to the base layer's implementation.
  /// @param H The handle for the module set to search in.
  /// @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 is found in the
  ///         given module set.
  JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
                         bool ExportedSymbolsOnly) {
    return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
  }

  /// @brief Immediately emit and finalize the moduleOB set represented by the
  ///        given handle.
  /// @param H Handle for module set to emit/finalize.
  void emitAndFinalize(ModuleSetHandleT H) {
    BaseLayer.emitAndFinalize(H);
  }

private:
  object::OwningBinary<object::ObjectFile>
  tryToLoadFromObjectCache(const Module &M) {
    std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
    if (!ObjBuffer)
      return object::OwningBinary<object::ObjectFile>();

    Expected<std::unique_ptr<object::ObjectFile>> Obj =
        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
    if (!Obj) {
      // TODO: Actually report errors helpfully.
      consumeError(Obj.takeError());
      return object::OwningBinary<object::ObjectFile>();
    }

    return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
                                                    std::move(ObjBuffer));
  }

  BaseLayerT &BaseLayer;
  CompileFtor Compile;
  ObjectCache *ObjCache;
};

} // End namespace orc.
} // End namespace llvm.

#endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H
