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 "llvm/ExecutionEngine/ObjectCache.h"
22 /// @brief Eager IR compiling layer.
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 {
30 typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
34 typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
36 typedef std::vector<std::unique_ptr<object::ObjectFile>> OwningObjectVec;
37 typedef std::vector<std::unique_ptr<MemoryBuffer>> OwningBufferVec;
40 /// @brief Handle to a set of compiled modules.
41 typedef ObjSetHandleT ModuleSetHandleT;
43 /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
44 /// implement the ObjectLayer concept.
45 IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
46 : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
48 /// @brief Set an ObjectCache to query before compiling.
49 void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
51 /// @brief Compile each module in the given module set, then then add the
52 /// resulting set of objects to the base layer, along with the memory
55 /// @return A handle for the added modules.
56 template <typename ModuleSetT>
57 ModuleSetHandleT addModuleSet(ModuleSetT Ms,
58 std::unique_ptr<RTDyldMemoryManager> MM) {
59 OwningObjectVec Objects;
60 OwningBufferVec Buffers;
62 for (const auto &M : Ms) {
63 std::unique_ptr<object::ObjectFile> Object;
64 std::unique_ptr<MemoryBuffer> Buffer;
67 std::tie(Object, Buffer) = tryToLoadFromObjectCache(*M).takeBinary();
70 std::tie(Object, Buffer) = Compile(*M).takeBinary();
72 ObjCache->notifyObjectCompiled(&*M, Buffer->getMemBufferRef());
75 Objects.push_back(std::move(Object));
76 Buffers.push_back(std::move(Buffer));
79 return BaseLayer.addObjectSet(std::move(Objects), std::move(MM));
82 /// @brief Remove the module set associated with the handle H.
83 void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
85 /// @brief Get the address of a loaded symbol. This call is forwarded to the
86 /// base layer's getSymbolAddress implementation.
87 uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
88 return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
91 /// @brief Get the address of the given symbol in the context of the set of
92 /// compiled modules represented by the handle H. This call is
93 /// forwarded to the base layer's implementation.
94 uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
95 bool ExportedSymbolsOnly) {
96 return BaseLayer.lookupSymbolAddressIn(H, Name, ExportedSymbolsOnly);
100 object::OwningBinary<object::ObjectFile>
101 tryToLoadFromObjectCache(const Module &M) {
102 std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
104 return object::OwningBinary<object::ObjectFile>();
106 ErrorOr<std::unique_ptr<object::ObjectFile>> Obj =
107 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
109 return object::OwningBinary<object::ObjectFile>();
111 return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
112 std::move(ObjBuffer));
115 BaseLayerT &BaseLayer;
117 ObjectCache *ObjCache;
121 #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H