IRCompileLayer.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Contains the definition for a basic, eagerly compiling layer of the JIT.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
  14. #define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
  15. #include "JITSymbol.h"
  16. #include "llvm/ExecutionEngine/ObjectCache.h"
  17. #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
  18. #include "llvm/Object/ObjectFile.h"
  19. #include <memory>
  20. namespace llvm {
  21. namespace orc {
  22. /// @brief Eager IR compiling layer.
  23. ///
  24. /// This layer accepts sets of LLVM IR Modules (via addModuleSet). It
  25. /// immediately compiles each IR module to an object file (each IR Module is
  26. /// compiled separately). The resulting set of object files is then added to
  27. /// the layer below, which must implement the object layer concept.
  28. template <typename BaseLayerT> class IRCompileLayer {
  29. public:
  30. typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
  31. CompileFtor;
  32. private:
  33. typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
  34. typedef std::vector<std::unique_ptr<object::ObjectFile>> OwningObjectVec;
  35. typedef std::vector<std::unique_ptr<MemoryBuffer>> OwningBufferVec;
  36. public:
  37. /// @brief Handle to a set of compiled modules.
  38. typedef ObjSetHandleT ModuleSetHandleT;
  39. /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
  40. /// implement the ObjectLayer concept.
  41. IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
  42. : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
  43. /// @brief Set an ObjectCache to query before compiling.
  44. void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
  45. /// @brief Compile each module in the given module set, then add the resulting
  46. /// set of objects to the base layer along with the memory manager and
  47. /// symbol resolver.
  48. ///
  49. /// @return A handle for the added modules.
  50. template <typename ModuleSetT, typename MemoryManagerPtrT,
  51. typename SymbolResolverPtrT>
  52. ModuleSetHandleT addModuleSet(ModuleSetT Ms,
  53. MemoryManagerPtrT MemMgr,
  54. SymbolResolverPtrT Resolver) {
  55. OwningObjectVec Objects;
  56. OwningBufferVec Buffers;
  57. for (const auto &M : Ms) {
  58. std::unique_ptr<object::ObjectFile> Object;
  59. std::unique_ptr<MemoryBuffer> Buffer;
  60. if (ObjCache)
  61. std::tie(Object, Buffer) = tryToLoadFromObjectCache(*M).takeBinary();
  62. if (!Object) {
  63. std::tie(Object, Buffer) = Compile(*M).takeBinary();
  64. if (ObjCache)
  65. ObjCache->notifyObjectCompiled(&*M, Buffer->getMemBufferRef());
  66. }
  67. Objects.push_back(std::move(Object));
  68. Buffers.push_back(std::move(Buffer));
  69. }
  70. ModuleSetHandleT H =
  71. BaseLayer.addObjectSet(Objects, std::move(MemMgr), std::move(Resolver));
  72. BaseLayer.takeOwnershipOfBuffers(H, std::move(Buffers));
  73. return H;
  74. }
  75. /// @brief Remove the module set associated with the handle H.
  76. void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
  77. /// @brief Search for the given named symbol.
  78. /// @param Name The name of the symbol to search for.
  79. /// @param ExportedSymbolsOnly If true, search only for exported symbols.
  80. /// @return A handle for the given named symbol, if it exists.
  81. JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
  82. return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
  83. }
  84. /// @brief Get the address of the given symbol in the context of the set of
  85. /// compiled modules represented by the handle H. This call is
  86. /// forwarded to the base layer's implementation.
  87. /// @param H The handle for the module set to search in.
  88. /// @param Name The name of the symbol to search for.
  89. /// @param ExportedSymbolsOnly If true, search only for exported symbols.
  90. /// @return A handle for the given named symbol, if it is found in the
  91. /// given module set.
  92. JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
  93. bool ExportedSymbolsOnly) {
  94. return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
  95. }
  96. /// @brief Immediately emit and finalize the moduleOB set represented by the
  97. /// given handle.
  98. /// @param H Handle for module set to emit/finalize.
  99. void emitAndFinalize(ModuleSetHandleT H) {
  100. BaseLayer.emitAndFinalize(H);
  101. }
  102. private:
  103. object::OwningBinary<object::ObjectFile>
  104. tryToLoadFromObjectCache(const Module &M) {
  105. std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
  106. if (!ObjBuffer)
  107. return object::OwningBinary<object::ObjectFile>();
  108. ErrorOr<std::unique_ptr<object::ObjectFile>> Obj =
  109. object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
  110. if (!Obj)
  111. return object::OwningBinary<object::ObjectFile>();
  112. return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
  113. std::move(ObjBuffer));
  114. }
  115. BaseLayerT &BaseLayer;
  116. CompileFtor Compile;
  117. ObjectCache *ObjCache;
  118. };
  119. } // End namespace orc.
  120. } // End namespace llvm.
  121. #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H