llvm.org GIT mirror llvm / e3e43d9 include / llvm / ExecutionEngine / Orc / IRCompileLayer.h

Tree @e3e43d9 (Download .tar.gz)

IRCompileLayer.h @e3e43d9raw · history · blame

//===------ 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.


#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/ObjectCache.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 {
  typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>

  typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;

  /// @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) {

    for (const auto &M : Ms) {
      auto Object =

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

      if (!Object->getBinary()) {
        *Object = Compile(*M);
        if (ObjCache)


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

    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) {

  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 =
    if (!Obj) {
      // TODO: Actually report errors helpfully.
      return object::OwningBinary<object::ObjectFile>();

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

  BaseLayerT &BaseLayer;
  CompileFtor Compile;
  ObjectCache *ObjCache;

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