[Orc] Add some missing headers.
[oota-llvm.git] / include / llvm / ExecutionEngine / Orc / IRCompileLayer.h
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
14 #ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
16
17 #include "llvm/ExecutionEngine/ObjectCache.h"
18 #include "llvm/Object/ObjectFile.h"
19 #include <memory>
20
21 namespace llvm {
22
23 /// @brief Eager IR compiling layer.
24 ///
25 ///   This layer accepts sets of LLVM IR Modules (via addModuleSet). It
26 /// immediately compiles each IR module to an object file (each IR Module is
27 /// compiled separately). The resulting set of object files is then added to
28 /// the layer below, which must implement the object layer concept.
29 template <typename BaseLayerT> class IRCompileLayer {
30 public:
31   typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)>
32       CompileFtor;
33
34 private:
35   typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT;
36
37   typedef std::vector<std::unique_ptr<object::ObjectFile>> OwningObjectVec;
38   typedef std::vector<std::unique_ptr<MemoryBuffer>> OwningBufferVec;
39
40 public:
41   /// @brief Handle to a set of compiled modules.
42   typedef ObjSetHandleT ModuleSetHandleT;
43
44   /// @brief Construct an IRCompileLayer with the given BaseLayer, which must
45   ///        implement the ObjectLayer concept.
46   IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile)
47       : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {}
48
49   /// @brief Set an ObjectCache to query before compiling.
50   void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; }
51
52   /// @brief Compile each module in the given module set, then then add the
53   ///        resulting set of objects to the base layer, along with the memory
54   //         manager MM.
55   ///
56   /// @return A handle for the added modules.
57   template <typename ModuleSetT>
58   ModuleSetHandleT addModuleSet(ModuleSetT Ms,
59                                 std::unique_ptr<RTDyldMemoryManager> MM) {
60     OwningObjectVec Objects;
61     OwningBufferVec Buffers;
62
63     for (const auto &M : Ms) {
64       std::unique_ptr<object::ObjectFile> Object;
65       std::unique_ptr<MemoryBuffer> Buffer;
66
67       if (ObjCache)
68         std::tie(Object, Buffer) = tryToLoadFromObjectCache(*M).takeBinary();
69
70       if (!Object) {
71         std::tie(Object, Buffer) = Compile(*M).takeBinary();
72         if (ObjCache)
73           ObjCache->notifyObjectCompiled(&*M, Buffer->getMemBufferRef());
74       }
75
76       Objects.push_back(std::move(Object));
77       Buffers.push_back(std::move(Buffer));
78     }
79
80     ModuleSetHandleT H =
81       BaseLayer.addObjectSet(Objects, std::move(MM));
82
83     BaseLayer.takeOwnershipOfBuffers(H, std::move(Buffers));
84
85     return H;
86   }
87
88   /// @brief Remove the module set associated with the handle H.
89   void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); }
90
91   /// @brief Get the address of a loaded symbol. This call is forwarded to the
92   ///        base layer's getSymbolAddress implementation.
93   uint64_t getSymbolAddress(const std::string &Name, bool ExportedSymbolsOnly) {
94     return BaseLayer.getSymbolAddress(Name, ExportedSymbolsOnly);
95   }
96
97   /// @brief Get the address of the given symbol in the context of the set of
98   ///        compiled modules represented by the handle H. This call is
99   ///        forwarded to the base layer's implementation.
100   uint64_t lookupSymbolAddressIn(ModuleSetHandleT H, const std::string &Name,
101                                  bool ExportedSymbolsOnly) {
102     return BaseLayer.lookupSymbolAddressIn(H, Name, ExportedSymbolsOnly);
103   }
104
105 private:
106   object::OwningBinary<object::ObjectFile>
107   tryToLoadFromObjectCache(const Module &M) {
108     std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M);
109     if (!ObjBuffer)
110       return object::OwningBinary<object::ObjectFile>();
111
112     ErrorOr<std::unique_ptr<object::ObjectFile>> Obj =
113         object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef());
114     if (!Obj)
115       return object::OwningBinary<object::ObjectFile>();
116
117     return object::OwningBinary<object::ObjectFile>(std::move(*Obj),
118                                                     std::move(ObjBuffer));
119   }
120
121   BaseLayerT &BaseLayer;
122   CompileFtor Compile;
123   ObjectCache *ObjCache;
124 };
125 }
126
127 #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H