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