diff options
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/IRCompileLayer.h')
| -rw-r--r-- | include/llvm/ExecutionEngine/Orc/IRCompileLayer.h | 148 | 
1 files changed, 148 insertions, 0 deletions
| diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h new file mode 100644 index 000000000000..637902200786 --- /dev/null +++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -0,0 +1,148 @@ +//===------ 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 "JITSymbol.h" +#include "llvm/ExecutionEngine/ObjectCache.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.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; + +  typedef std::vector<std::unique_ptr<object::ObjectFile>> OwningObjectVec; +  typedef std::vector<std::unique_ptr<MemoryBuffer>> OwningBufferVec; + +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) { +    OwningObjectVec Objects; +    OwningBufferVec Buffers; + +    for (const auto &M : Ms) { +      std::unique_ptr<object::ObjectFile> Object; +      std::unique_ptr<MemoryBuffer> Buffer; + +      if (ObjCache) +        std::tie(Object, Buffer) = tryToLoadFromObjectCache(*M).takeBinary(); + +      if (!Object) { +        std::tie(Object, Buffer) = Compile(*M).takeBinary(); +        if (ObjCache) +          ObjCache->notifyObjectCompiled(&*M, Buffer->getMemBufferRef()); +      } + +      Objects.push_back(std::move(Object)); +      Buffers.push_back(std::move(Buffer)); +    } + +    ModuleSetHandleT H = +      BaseLayer.addObjectSet(Objects, std::move(MemMgr), std::move(Resolver)); + +    BaseLayer.takeOwnershipOfBuffers(H, std::move(Buffers)); + +    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>(); + +    ErrorOr<std::unique_ptr<object::ObjectFile>> Obj = +        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); +    if (!Obj) +      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 | 
